diff options
author | Tejun Heo <tj@kernel.org> | 2011-05-24 03:59:36 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-05-24 03:59:36 -0400 |
commit | 6988f20fe04e9ef3aea488cb8ab57fbeb78e12f0 (patch) | |
tree | c9d7fc50a2e2147a5ca07e3096e7eeb916ad2da9 /arch | |
parent | 0415b00d175e0d8945e6785aad21b5f157976ce0 (diff) | |
parent | 6ea0c34dac89611126455537552cffe6c7e832ad (diff) |
Merge branch 'fixes-2.6.39' into for-2.6.40
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-ep93xx/gpio.c | 46 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-omap4panda.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-omap2/devices.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_l3_smx.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-regulators.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 1 | ||||
-rw-r--r-- | arch/arm/mm/init.c | 2 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 45 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/irqs.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/onenand.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-pxa/include/plat/pxa3xx_nand.h | 2 | ||||
-rw-r--r-- | arch/avr32/Kconfig | 14 | ||||
-rw-r--r-- | arch/avr32/boards/atngw100/mrmt.c | 2 | ||||
-rw-r--r-- | arch/avr32/boards/atngw100/setup.c | 2 | ||||
-rw-r--r-- | arch/avr32/kernel/irq.c | 37 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/extint.c | 82 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/intc.c | 14 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/pio.c | 37 | ||||
-rw-r--r-- | arch/cris/Kconfig | 1 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/axisflashmap.c | 6 | ||||
-rw-r--r-- | arch/cris/arch-v32/drivers/Kconfig | 1 | ||||
-rw-r--r-- | arch/cris/arch-v32/drivers/axisflashmap.c | 6 | ||||
-rw-r--r-- | arch/h8300/Kconfig | 1 | ||||
-rw-r--r-- | arch/h8300/kernel/irq.c | 33 | ||||
-rw-r--r-- | arch/ia64/mm/contig.c | 2 | ||||
-rw-r--r-- | arch/ia64/mm/discontig.c | 2 | ||||
-rw-r--r-- | arch/m32r/Kconfig | 1 | ||||
-rw-r--r-- | arch/m32r/kernel/irq.c | 45 | ||||
-rw-r--r-- | arch/m32r/platforms/m32104ut/setup.c | 8 | ||||
-rw-r--r-- | arch/m32r/platforms/m32700ut/setup.c | 28 | ||||
-rw-r--r-- | arch/m32r/platforms/mappi/setup.c | 16 | ||||
-rw-r--r-- | arch/m32r/platforms/mappi2/setup.c | 20 | ||||
-rw-r--r-- | arch/m32r/platforms/mappi3/setup.c | 20 | ||||
-rw-r--r-- | arch/m32r/platforms/oaks32r/setup.c | 12 | ||||
-rw-r--r-- | arch/m32r/platforms/opsput/setup.c | 28 | ||||
-rw-r--r-- | arch/m32r/platforms/usrv/setup.c | 18 | ||||
-rw-r--r-- | arch/m68k/Kconfig | 456 | ||||
-rw-r--r-- | arch/m68k/Kconfig.debug | 34 | ||||
-rw-r--r-- | arch/m68k/Kconfig.mmu | 417 | ||||
-rw-r--r-- | arch/m68k/Kconfig.nommu (renamed from arch/m68knommu/Kconfig) | 94 | ||||
-rw-r--r-- | arch/m68k/Makefile | 122 | ||||
-rw-r--r-- | arch/m68k/Makefile_mm | 121 | ||||
-rw-r--r-- | arch/m68k/Makefile_no (renamed from arch/m68knommu/Makefile) | 16 | ||||
-rw-r--r-- | arch/m68k/configs/m5208evb_defconfig (renamed from arch/m68knommu/configs/m5208evb_defconfig) | 2 | ||||
-rw-r--r-- | arch/m68k/configs/m5249evb_defconfig (renamed from arch/m68knommu/configs/m5249evb_defconfig) | 2 | ||||
-rw-r--r-- | arch/m68k/configs/m5272c3_defconfig (renamed from arch/m68knommu/configs/m5272c3_defconfig) | 2 | ||||
-rw-r--r-- | arch/m68k/configs/m5275evb_defconfig (renamed from arch/m68knommu/configs/m5275evb_defconfig) | 2 | ||||
-rw-r--r-- | arch/m68k/configs/m5307c3_defconfig (renamed from arch/m68knommu/configs/m5307c3_defconfig) | 2 | ||||
-rw-r--r-- | arch/m68k/configs/m5407c3_defconfig (renamed from arch/m68knommu/configs/m5407c3_defconfig) | 2 | ||||
-rw-r--r-- | arch/m68k/kernel/Makefile | 18 | ||||
-rw-r--r-- | arch/m68k/kernel/Makefile_mm | 17 | ||||
-rw-r--r-- | arch/m68k/kernel/Makefile_no (renamed from arch/m68knommu/kernel/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/asm-offsets.c | 101 | ||||
-rw-r--r-- | arch/m68k/kernel/asm-offsets_mm.c | 100 | ||||
-rw-r--r-- | arch/m68k/kernel/asm-offsets_no.c (renamed from arch/m68knommu/kernel/asm-offsets.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/dma.c | 135 | ||||
-rw-r--r-- | arch/m68k/kernel/dma_mm.c | 130 | ||||
-rw-r--r-- | arch/m68k/kernel/dma_no.c (renamed from arch/m68knommu/kernel/dma.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/entry.S | 756 | ||||
-rw-r--r-- | arch/m68k/kernel/entry_mm.S | 753 | ||||
-rw-r--r-- | arch/m68k/kernel/entry_no.S (renamed from arch/m68knommu/kernel/entry.S) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/init_task.c (renamed from arch/m68knommu/kernel/init_task.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/irq.c (renamed from arch/m68knommu/kernel/irq.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/m68k_ksyms.c | 21 | ||||
-rw-r--r-- | arch/m68k/kernel/m68k_ksyms_mm.c | 16 | ||||
-rw-r--r-- | arch/m68k/kernel/m68k_ksyms_no.c (renamed from arch/m68knommu/kernel/m68k_ksyms.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/module.c | 156 | ||||
-rw-r--r-- | arch/m68k/kernel/module_mm.c | 155 | ||||
-rw-r--r-- | arch/m68k/kernel/module_no.c (renamed from arch/m68knommu/kernel/module.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/process.c | 355 | ||||
-rw-r--r-- | arch/m68k/kernel/process_mm.c | 354 | ||||
-rw-r--r-- | arch/m68k/kernel/process_no.c (renamed from arch/m68knommu/kernel/process.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/ptrace.c | 282 | ||||
-rw-r--r-- | arch/m68k/kernel/ptrace_mm.c | 277 | ||||
-rw-r--r-- | arch/m68k/kernel/ptrace_no.c (renamed from arch/m68knommu/kernel/ptrace.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/setup.c | 534 | ||||
-rw-r--r-- | arch/m68k/kernel/setup_mm.c | 533 | ||||
-rw-r--r-- | arch/m68k/kernel/setup_no.c (renamed from arch/m68knommu/kernel/setup.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/signal.c | 1018 | ||||
-rw-r--r-- | arch/m68k/kernel/signal_mm.c | 1017 | ||||
-rw-r--r-- | arch/m68k/kernel/signal_no.c (renamed from arch/m68knommu/kernel/signal.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/sys_m68k.c | 551 | ||||
-rw-r--r-- | arch/m68k/kernel/sys_m68k_mm.c | 546 | ||||
-rw-r--r-- | arch/m68k/kernel/sys_m68k_no.c (renamed from arch/m68knommu/kernel/sys_m68k.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/syscalltable.S (renamed from arch/m68knommu/kernel/syscalltable.S) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/time.c | 119 | ||||
-rw-r--r-- | arch/m68k/kernel/time_mm.c | 114 | ||||
-rw-r--r-- | arch/m68k/kernel/time_no.c (renamed from arch/m68knommu/kernel/time.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/traps.c | 1208 | ||||
-rw-r--r-- | arch/m68k/kernel/traps_mm.c | 1207 | ||||
-rw-r--r-- | arch/m68k/kernel/traps_no.c (renamed from arch/m68knommu/kernel/traps.c) | 0 | ||||
-rw-r--r-- | arch/m68k/kernel/vmlinux.lds.S | 11 | ||||
-rw-r--r-- | arch/m68k/kernel/vmlinux.lds_mm.S | 10 | ||||
-rw-r--r-- | arch/m68k/kernel/vmlinux.lds_no.S (renamed from arch/m68knommu/kernel/vmlinux.lds.S) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/Makefile | 11 | ||||
-rw-r--r-- | arch/m68k/lib/Makefile_mm | 6 | ||||
-rw-r--r-- | arch/m68k/lib/Makefile_no (renamed from arch/m68knommu/lib/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/checksum.c | 430 | ||||
-rw-r--r-- | arch/m68k/lib/checksum_mm.c | 425 | ||||
-rw-r--r-- | arch/m68k/lib/checksum_no.c (renamed from arch/m68knommu/lib/checksum.c) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/delay.c (renamed from arch/m68knommu/lib/delay.c) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/divsi3.S (renamed from arch/m68knommu/lib/divsi3.S) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/memcpy.c (renamed from arch/m68knommu/lib/memcpy.c) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/memmove.c (renamed from arch/m68knommu/lib/memmove.c) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/memset.c (renamed from arch/m68knommu/lib/memset.c) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/modsi3.S (renamed from arch/m68knommu/lib/modsi3.S) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/muldi3.c | 68 | ||||
-rw-r--r-- | arch/m68k/lib/muldi3_mm.c (renamed from arch/m68knommu/lib/ashrdi3.c) | 48 | ||||
-rw-r--r-- | arch/m68k/lib/muldi3_no.c (renamed from arch/m68knommu/lib/muldi3.c) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/mulsi3.S (renamed from arch/m68knommu/lib/mulsi3.S) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/udivsi3.S (renamed from arch/m68knommu/lib/udivsi3.S) | 0 | ||||
-rw-r--r-- | arch/m68k/lib/umodsi3.S (renamed from arch/m68knommu/lib/umodsi3.S) | 0 | ||||
-rw-r--r-- | arch/m68k/mm/Makefile | 13 | ||||
-rw-r--r-- | arch/m68k/mm/Makefile_mm | 8 | ||||
-rw-r--r-- | arch/m68k/mm/Makefile_no (renamed from arch/m68knommu/mm/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/mm/init.c | 153 | ||||
-rw-r--r-- | arch/m68k/mm/init_mm.c | 150 | ||||
-rw-r--r-- | arch/m68k/mm/init_no.c (renamed from arch/m68knommu/mm/init.c) | 0 | ||||
-rw-r--r-- | arch/m68k/mm/kmap.c | 368 | ||||
-rw-r--r-- | arch/m68k/mm/kmap_mm.c | 367 | ||||
-rw-r--r-- | arch/m68k/mm/kmap_no.c (renamed from arch/m68knommu/mm/kmap.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5206/Makefile (renamed from arch/m68knommu/platform/5206/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5206/config.c (renamed from arch/m68knommu/platform/5206/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5206/gpio.c (renamed from arch/m68knommu/platform/5206/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5206e/Makefile (renamed from arch/m68knommu/platform/5206e/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5206e/config.c (renamed from arch/m68knommu/platform/5206e/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5206e/gpio.c (renamed from arch/m68knommu/platform/5206e/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/520x/Makefile (renamed from arch/m68knommu/platform/520x/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/520x/config.c (renamed from arch/m68knommu/platform/520x/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/520x/gpio.c (renamed from arch/m68knommu/platform/520x/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/523x/Makefile (renamed from arch/m68knommu/platform/523x/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/523x/config.c (renamed from arch/m68knommu/platform/523x/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/523x/gpio.c (renamed from arch/m68knommu/platform/523x/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5249/Makefile (renamed from arch/m68knommu/platform/5249/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5249/config.c (renamed from arch/m68knommu/platform/5249/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5249/gpio.c (renamed from arch/m68knommu/platform/5249/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5249/intc2.c (renamed from arch/m68knommu/platform/5249/intc2.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5272/Makefile (renamed from arch/m68knommu/platform/5272/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5272/config.c (renamed from arch/m68knommu/platform/5272/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5272/gpio.c (renamed from arch/m68knommu/platform/5272/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5272/intc.c (renamed from arch/m68knommu/platform/5272/intc.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/527x/Makefile (renamed from arch/m68knommu/platform/527x/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/527x/config.c (renamed from arch/m68knommu/platform/527x/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/527x/gpio.c (renamed from arch/m68knommu/platform/527x/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/528x/Makefile (renamed from arch/m68knommu/platform/528x/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/528x/config.c (renamed from arch/m68knommu/platform/528x/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/528x/gpio.c (renamed from arch/m68knommu/platform/528x/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5307/Makefile (renamed from arch/m68knommu/platform/5307/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5307/config.c (renamed from arch/m68knommu/platform/5307/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5307/gpio.c (renamed from arch/m68knommu/platform/5307/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5307/nettel.c (renamed from arch/m68knommu/platform/5307/nettel.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/532x/Makefile (renamed from arch/m68knommu/platform/532x/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/532x/config.c (renamed from arch/m68knommu/platform/532x/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/532x/gpio.c (renamed from arch/m68knommu/platform/532x/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5407/Makefile (renamed from arch/m68knommu/platform/5407/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5407/config.c (renamed from arch/m68knommu/platform/5407/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/5407/gpio.c (renamed from arch/m68knommu/platform/5407/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/54xx/Makefile (renamed from arch/m68knommu/platform/54xx/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/54xx/config.c (renamed from arch/m68knommu/platform/54xx/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/54xx/firebee.c (renamed from arch/m68knommu/platform/54xx/firebee.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/Makefile (renamed from arch/m68knommu/platform/68328/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/bootlogo.h (renamed from arch/m68knommu/platform/68328/bootlogo.h) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/bootlogo.pl (renamed from arch/m68knommu/platform/68328/bootlogo.pl) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/config.c (renamed from arch/m68knommu/platform/68328/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/entry.S (renamed from arch/m68knommu/platform/68328/entry.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/head-de2.S (renamed from arch/m68knommu/platform/68328/head-de2.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/head-pilot.S (renamed from arch/m68knommu/platform/68328/head-pilot.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/head-ram.S (renamed from arch/m68knommu/platform/68328/head-ram.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/head-rom.S (renamed from arch/m68knommu/platform/68328/head-rom.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/ints.c (renamed from arch/m68knommu/platform/68328/ints.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/romvec.S (renamed from arch/m68knommu/platform/68328/romvec.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68328/timers.c (renamed from arch/m68knommu/platform/68328/timers.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68360/Makefile (renamed from arch/m68knommu/platform/68360/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68360/commproc.c (renamed from arch/m68knommu/platform/68360/commproc.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68360/config.c (renamed from arch/m68knommu/platform/68360/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68360/entry.S (renamed from arch/m68knommu/platform/68360/entry.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68360/head-ram.S (renamed from arch/m68knommu/platform/68360/head-ram.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68360/head-rom.S (renamed from arch/m68knommu/platform/68360/head-rom.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68360/ints.c (renamed from arch/m68knommu/platform/68360/ints.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68EZ328/Makefile (renamed from arch/m68knommu/platform/68EZ328/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68EZ328/bootlogo.h (renamed from arch/m68knommu/platform/68EZ328/bootlogo.h) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68EZ328/config.c (renamed from arch/m68knommu/platform/68EZ328/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68VZ328/Makefile (renamed from arch/m68knommu/platform/68VZ328/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/68VZ328/config.c (renamed from arch/m68knommu/platform/68VZ328/config.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/Makefile (renamed from arch/m68knommu/platform/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/Makefile (renamed from arch/m68knommu/platform/coldfire/Makefile) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/cache.c (renamed from arch/m68knommu/platform/coldfire/cache.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/clk.c (renamed from arch/m68knommu/platform/coldfire/clk.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/dma.c (renamed from arch/m68knommu/platform/coldfire/dma.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/dma_timer.c (renamed from arch/m68knommu/platform/coldfire/dma_timer.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/entry.S (renamed from arch/m68knommu/platform/coldfire/entry.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/gpio.c (renamed from arch/m68knommu/platform/coldfire/gpio.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/head.S (renamed from arch/m68knommu/platform/coldfire/head.S) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/intc-2.c (renamed from arch/m68knommu/platform/coldfire/intc-2.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/intc-simr.c (renamed from arch/m68knommu/platform/coldfire/intc-simr.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/intc.c (renamed from arch/m68knommu/platform/coldfire/intc.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/pinmux.c (renamed from arch/m68knommu/platform/coldfire/pinmux.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/pit.c (renamed from arch/m68knommu/platform/coldfire/pit.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/sltimers.c (renamed from arch/m68knommu/platform/coldfire/sltimers.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/timers.c (renamed from arch/m68knommu/platform/coldfire/timers.c) | 0 | ||||
-rw-r--r-- | arch/m68k/platform/coldfire/vectors.c (renamed from arch/m68knommu/platform/coldfire/vectors.c) | 0 | ||||
-rw-r--r-- | arch/m68knommu/Kconfig.debug | 35 | ||||
-rw-r--r-- | arch/m68knommu/defconfig | 74 | ||||
-rw-r--r-- | arch/m68knommu/kernel/.gitignore | 1 | ||||
-rw-r--r-- | arch/m68knommu/lib/ashldi3.c | 62 | ||||
-rw-r--r-- | arch/m68knommu/lib/lshrdi3.c | 62 | ||||
-rw-r--r-- | arch/mips/Kconfig | 4 | ||||
-rw-r--r-- | arch/mips/alchemy/common/irq.c | 98 | ||||
-rw-r--r-- | arch/mips/alchemy/devboards/bcsr.c | 18 | ||||
-rw-r--r-- | arch/mips/ar7/irq.c | 42 | ||||
-rw-r--r-- | arch/mips/ath79/irq.c | 24 | ||||
-rw-r--r-- | arch/mips/bcm63xx/irq.c | 77 | ||||
-rw-r--r-- | arch/mips/dec/ioasic-irq.c | 60 | ||||
-rw-r--r-- | arch/mips/dec/kn02-irq.c | 23 | ||||
-rw-r--r-- | arch/mips/emma/markeins/irq.c | 67 | ||||
-rw-r--r-- | arch/mips/include/asm/irq.h | 64 | ||||
-rw-r--r-- | arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h | 21 | ||||
-rw-r--r-- | arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h | 343 | ||||
-rw-r--r-- | arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h | 17 | ||||
-rw-r--r-- | arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h | 144 | ||||
-rw-r--r-- | arch/mips/include/asm/spinlock.h | 22 | ||||
-rw-r--r-- | arch/mips/include/asm/unistd.h | 24 | ||||
-rw-r--r-- | arch/mips/jazz/irq.c | 14 | ||||
-rw-r--r-- | arch/mips/jz4740/board-qi_lb60.c | 32 | ||||
-rw-r--r-- | arch/mips/jz4740/gpio.c | 111 | ||||
-rw-r--r-- | arch/mips/jz4740/irq.c | 32 | ||||
-rw-r--r-- | arch/mips/kernel/i8259.c | 37 | ||||
-rw-r--r-- | arch/mips/kernel/irq-gic.c | 43 | ||||
-rw-r--r-- | arch/mips/kernel/irq-gt641xx.c | 26 | ||||
-rw-r--r-- | arch/mips/kernel/irq-msc01.c | 51 | ||||
-rw-r--r-- | arch/mips/kernel/irq-rm7000.c | 18 | ||||
-rw-r--r-- | arch/mips/kernel/irq-rm9000.c | 49 | ||||
-rw-r--r-- | arch/mips/kernel/irq.c | 49 | ||||
-rw-r--r-- | arch/mips/kernel/irq_cpu.c | 46 | ||||
-rw-r--r-- | arch/mips/kernel/irq_txx9.c | 28 | ||||
-rw-r--r-- | arch/mips/kernel/scall32-o32.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-64.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-n32.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-o32.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 13 | ||||
-rw-r--r-- | arch/mips/lasat/interrupt.c | 16 | ||||
-rw-r--r-- | arch/mips/loongson/common/bonito-irq.c | 16 | ||||
-rw-r--r-- | arch/mips/mipssim/sim_smtc.c | 3 | ||||
-rw-r--r-- | arch/mips/mti-malta/malta-smtc.c | 10 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/Kconfig | 15 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/Makefile | 8 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_eth.c | 187 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_irq.c | 56 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c | 239 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_irq_per.c | 135 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c | 18 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_setup.c | 10 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_smp.c | 77 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_smtc.c | 105 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_time.c | 16 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_usb.c | 239 | ||||
-rw-r--r-- | arch/mips/pnx833x/common/interrupts.c | 98 | ||||
-rw-r--r-- | arch/mips/pnx8550/common/int.c | 18 | ||||
-rw-r--r-- | arch/mips/powertv/asic/irq_asic.c | 13 | ||||
-rw-r--r-- | arch/mips/rb532/irq.c | 32 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-int.c | 60 | ||||
-rw-r--r-- | arch/mips/sgi-ip27/ip27-irq.c | 38 | ||||
-rw-r--r-- | arch/mips/sgi-ip27/ip27-timer.c | 11 | ||||
-rw-r--r-- | arch/mips/sgi-ip32/ip32-irq.c | 134 | ||||
-rw-r--r-- | arch/mips/sibyte/bcm1480/irq.c | 55 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/irq.c | 53 | ||||
-rw-r--r-- | arch/mips/sni/a20r.c | 23 | ||||
-rw-r--r-- | arch/mips/sni/pcimt.c | 21 | ||||
-rw-r--r-- | arch/mips/sni/pcit.c | 21 | ||||
-rw-r--r-- | arch/mips/sni/rm200.c | 42 | ||||
-rw-r--r-- | arch/mips/txx9/generic/irq_tx4939.c | 28 | ||||
-rw-r--r-- | arch/mips/txx9/jmr3927/irq.c | 14 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4927/irq.c | 58 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4938/irq.c | 54 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4939/irq.c | 14 | ||||
-rw-r--r-- | arch/mips/vr41xx/common/icu.c | 72 | ||||
-rw-r--r-- | arch/mips/vr41xx/common/irq.c | 19 | ||||
-rw-r--r-- | arch/parisc/mm/init.c | 2 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/ccwdev.h | 4 | ||||
-rw-r--r-- | arch/s390/include/asm/ccwgroup.h | 4 | ||||
-rw-r--r-- | arch/s390/include/asm/cmpxchg.h | 225 | ||||
-rw-r--r-- | arch/s390/include/asm/system.h | 196 | ||||
-rw-r--r-- | arch/s390/include/asm/unistd.h | 6 | ||||
-rw-r--r-- | arch/s390/kernel/compat_wrapper.S | 27 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 22 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 88 | ||||
-rw-r--r-- | arch/s390/kernel/syscalls.S | 4 | ||||
-rw-r--r-- | arch/s390/oprofile/Makefile | 3 | ||||
-rw-r--r-- | arch/s390/oprofile/init.c | 15 | ||||
-rw-r--r-- | arch/sparc/kernel/time_32.c | 4 | ||||
-rw-r--r-- | arch/sparc/mm/init_32.c | 2 | ||||
-rw-r--r-- | arch/tile/mm/pgtable.c | 2 | ||||
-rw-r--r-- | arch/um/Kconfig.common | 1 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 53 | ||||
-rw-r--r-- | arch/unicore32/mm/init.c | 2 | ||||
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/percpu.h | 17 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 33 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 97 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mtrr/main.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_p4.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/devicetree.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/i8237.c | 30 | ||||
-rw-r--r-- | arch/x86/kernel/i8259.c | 33 | ||||
-rw-r--r-- | arch/x86/kernel/kgdb.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/microcode_core.c | 34 | ||||
-rw-r--r-- | arch/x86/kernel/mpparse.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 32 | ||||
-rw-r--r-- | arch/x86/lib/cmpxchg16b_emu.S | 14 | ||||
-rw-r--r-- | arch/x86/oprofile/nmi_int.c | 44 | ||||
-rw-r--r-- | arch/x86/platform/olpc/olpc-xo1.c | 23 | ||||
-rw-r--r-- | arch/xtensa/Kconfig | 6 | ||||
-rw-r--r-- | arch/xtensa/kernel/irq.c | 106 | ||||
-rw-r--r-- | arch/xtensa/platforms/s6105/device.c | 2 | ||||
-rw-r--r-- | arch/xtensa/variants/s6000/gpio.c | 45 |
321 files changed, 9989 insertions, 9558 deletions
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index a889fa7c3ba1..34e071d79761 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c | |||
@@ -360,52 +360,14 @@ static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
360 | gpio = ep93xx_chip->chip.base; | 360 | gpio = ep93xx_chip->chip.base; |
361 | for (i = 0; i < chip->ngpio; i++, gpio++) { | 361 | for (i = 0; i < chip->ngpio; i++, gpio++) { |
362 | int is_out = data_dir_reg & (1 << i); | 362 | int is_out = data_dir_reg & (1 << i); |
363 | int irq = gpio_to_irq(gpio); | ||
363 | 364 | ||
364 | seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s", | 365 | seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s %s\n", |
365 | chip->label, i, gpio, | 366 | chip->label, i, gpio, |
366 | gpiochip_is_requested(chip, i) ? : "", | 367 | gpiochip_is_requested(chip, i) ? : "", |
367 | is_out ? "out" : "in ", | 368 | is_out ? "out" : "in ", |
368 | (data_reg & (1 << i)) ? "hi" : "lo"); | 369 | (data_reg & (1<< i)) ? "hi" : "lo", |
369 | 370 | (!is_out && irq>= 0) ? "(interrupt)" : ""); | |
370 | if (!is_out) { | ||
371 | int irq = gpio_to_irq(gpio); | ||
372 | struct irq_desc *desc = irq_desc + irq; | ||
373 | |||
374 | if (irq >= 0 && desc->action) { | ||
375 | char *trigger; | ||
376 | |||
377 | switch (desc->status & IRQ_TYPE_SENSE_MASK) { | ||
378 | case IRQ_TYPE_NONE: | ||
379 | trigger = "(default)"; | ||
380 | break; | ||
381 | case IRQ_TYPE_EDGE_FALLING: | ||
382 | trigger = "edge-falling"; | ||
383 | break; | ||
384 | case IRQ_TYPE_EDGE_RISING: | ||
385 | trigger = "edge-rising"; | ||
386 | break; | ||
387 | case IRQ_TYPE_EDGE_BOTH: | ||
388 | trigger = "edge-both"; | ||
389 | break; | ||
390 | case IRQ_TYPE_LEVEL_HIGH: | ||
391 | trigger = "level-high"; | ||
392 | break; | ||
393 | case IRQ_TYPE_LEVEL_LOW: | ||
394 | trigger = "level-low"; | ||
395 | break; | ||
396 | default: | ||
397 | trigger = "?trigger?"; | ||
398 | break; | ||
399 | } | ||
400 | |||
401 | seq_printf(s, " irq-%d %s%s", | ||
402 | irq, trigger, | ||
403 | (desc->status & IRQ_WAKEUP) | ||
404 | ? " wakeup" : ""); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | seq_printf(s, "\n"); | ||
409 | } | 371 | } |
410 | } | 372 | } |
411 | 373 | ||
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index c936c6d7ded0..f3a7b1011914 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c | |||
@@ -285,19 +285,6 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) | |||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | static struct regulator_init_data omap4_panda_vaux1 = { | ||
289 | .constraints = { | ||
290 | .min_uV = 1000000, | ||
291 | .max_uV = 3000000, | ||
292 | .apply_uV = true, | ||
293 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
294 | | REGULATOR_MODE_STANDBY, | ||
295 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
296 | | REGULATOR_CHANGE_MODE | ||
297 | | REGULATOR_CHANGE_STATUS, | ||
298 | }, | ||
299 | }; | ||
300 | |||
301 | static struct regulator_init_data omap4_panda_vaux2 = { | 288 | static struct regulator_init_data omap4_panda_vaux2 = { |
302 | .constraints = { | 289 | .constraints = { |
303 | .min_uV = 1200000, | 290 | .min_uV = 1200000, |
@@ -353,19 +340,6 @@ static struct regulator_init_data omap4_panda_vpp = { | |||
353 | }, | 340 | }, |
354 | }; | 341 | }; |
355 | 342 | ||
356 | static struct regulator_init_data omap4_panda_vusim = { | ||
357 | .constraints = { | ||
358 | .min_uV = 1200000, | ||
359 | .max_uV = 2900000, | ||
360 | .apply_uV = true, | ||
361 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
362 | | REGULATOR_MODE_STANDBY, | ||
363 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
364 | | REGULATOR_CHANGE_MODE | ||
365 | | REGULATOR_CHANGE_STATUS, | ||
366 | }, | ||
367 | }; | ||
368 | |||
369 | static struct regulator_init_data omap4_panda_vana = { | 343 | static struct regulator_init_data omap4_panda_vana = { |
370 | .constraints = { | 344 | .constraints = { |
371 | .min_uV = 2100000, | 345 | .min_uV = 2100000, |
@@ -424,12 +398,10 @@ static struct twl4030_platform_data omap4_panda_twldata = { | |||
424 | /* Regulators */ | 398 | /* Regulators */ |
425 | .vmmc = &omap4_panda_vmmc, | 399 | .vmmc = &omap4_panda_vmmc, |
426 | .vpp = &omap4_panda_vpp, | 400 | .vpp = &omap4_panda_vpp, |
427 | .vusim = &omap4_panda_vusim, | ||
428 | .vana = &omap4_panda_vana, | 401 | .vana = &omap4_panda_vana, |
429 | .vcxio = &omap4_panda_vcxio, | 402 | .vcxio = &omap4_panda_vcxio, |
430 | .vdac = &omap4_panda_vdac, | 403 | .vdac = &omap4_panda_vdac, |
431 | .vusb = &omap4_panda_vusb, | 404 | .vusb = &omap4_panda_vusb, |
432 | .vaux1 = &omap4_panda_vaux1, | ||
433 | .vaux2 = &omap4_panda_vaux2, | 405 | .vaux2 = &omap4_panda_vaux2, |
434 | .vaux3 = &omap4_panda_vaux3, | 406 | .vaux3 = &omap4_panda_vaux3, |
435 | .clk32kg = &omap4_panda_clk32kg, | 407 | .clk32kg = &omap4_panda_clk32kg, |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index e97851492847..84d1b735fe80 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -66,7 +66,7 @@ static int __init omap3_l3_init(void) | |||
66 | 66 | ||
67 | WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name); | 67 | WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name); |
68 | 68 | ||
69 | return PTR_ERR(od); | 69 | return IS_ERR(od) ? PTR_ERR(od) : 0; |
70 | } | 70 | } |
71 | postcore_initcall(omap3_l3_init); | 71 | postcore_initcall(omap3_l3_init); |
72 | 72 | ||
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 674174365f78..493505c3b2f5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -693,6 +693,7 @@ static int __init gpmc_init(void) | |||
693 | { | 693 | { |
694 | u32 l, irq; | 694 | u32 l, irq; |
695 | int cs, ret = -EINVAL; | 695 | int cs, ret = -EINVAL; |
696 | int gpmc_irq; | ||
696 | char *ck = NULL; | 697 | char *ck = NULL; |
697 | 698 | ||
698 | if (cpu_is_omap24xx()) { | 699 | if (cpu_is_omap24xx()) { |
@@ -701,12 +702,15 @@ static int __init gpmc_init(void) | |||
701 | l = OMAP2420_GPMC_BASE; | 702 | l = OMAP2420_GPMC_BASE; |
702 | else | 703 | else |
703 | l = OMAP34XX_GPMC_BASE; | 704 | l = OMAP34XX_GPMC_BASE; |
705 | gpmc_irq = INT_34XX_GPMC_IRQ; | ||
704 | } else if (cpu_is_omap34xx()) { | 706 | } else if (cpu_is_omap34xx()) { |
705 | ck = "gpmc_fck"; | 707 | ck = "gpmc_fck"; |
706 | l = OMAP34XX_GPMC_BASE; | 708 | l = OMAP34XX_GPMC_BASE; |
709 | gpmc_irq = INT_34XX_GPMC_IRQ; | ||
707 | } else if (cpu_is_omap44xx()) { | 710 | } else if (cpu_is_omap44xx()) { |
708 | ck = "gpmc_ck"; | 711 | ck = "gpmc_ck"; |
709 | l = OMAP44XX_GPMC_BASE; | 712 | l = OMAP44XX_GPMC_BASE; |
713 | gpmc_irq = OMAP44XX_IRQ_GPMC; | ||
710 | } | 714 | } |
711 | 715 | ||
712 | if (WARN_ON(!ck)) | 716 | if (WARN_ON(!ck)) |
@@ -739,16 +743,17 @@ static int __init gpmc_init(void) | |||
739 | /* initalize the irq_chained */ | 743 | /* initalize the irq_chained */ |
740 | irq = OMAP_GPMC_IRQ_BASE; | 744 | irq = OMAP_GPMC_IRQ_BASE; |
741 | for (cs = 0; cs < GPMC_CS_NUM; cs++) { | 745 | for (cs = 0; cs < GPMC_CS_NUM; cs++) { |
742 | set_irq_handler(irq, handle_simple_irq); | 746 | set_irq_chip_and_handler(irq, &dummy_irq_chip, |
747 | handle_simple_irq); | ||
743 | set_irq_flags(irq, IRQF_VALID); | 748 | set_irq_flags(irq, IRQF_VALID); |
744 | irq++; | 749 | irq++; |
745 | } | 750 | } |
746 | 751 | ||
747 | ret = request_irq(INT_34XX_GPMC_IRQ, | 752 | ret = request_irq(gpmc_irq, |
748 | gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); | 753 | gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); |
749 | if (ret) | 754 | if (ret) |
750 | pr_err("gpmc: irq-%d could not claim: err %d\n", | 755 | pr_err("gpmc: irq-%d could not claim: err %d\n", |
751 | INT_34XX_GPMC_IRQ, ret); | 756 | gpmc_irq, ret); |
752 | return ret; | 757 | return ret; |
753 | } | 758 | } |
754 | postcore_initcall(gpmc_init); | 759 | postcore_initcall(gpmc_init); |
@@ -757,8 +762,6 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev) | |||
757 | { | 762 | { |
758 | u8 cs; | 763 | u8 cs; |
759 | 764 | ||
760 | if (irq != INT_34XX_GPMC_IRQ) | ||
761 | return IRQ_HANDLED; | ||
762 | /* check cs to invoke the irq */ | 765 | /* check cs to invoke the irq */ |
763 | cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; | 766 | cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; |
764 | if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) | 767 | if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) |
diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c index 265bff3acb9e..5f2da7565b68 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.c +++ b/arch/arm/mach-omap2/omap_l3_smx.c | |||
@@ -226,7 +226,6 @@ static int __init omap3_l3_probe(struct platform_device *pdev) | |||
226 | struct omap3_l3 *l3; | 226 | struct omap3_l3 *l3; |
227 | struct resource *res; | 227 | struct resource *res; |
228 | int ret; | 228 | int ret; |
229 | int irq; | ||
230 | 229 | ||
231 | l3 = kzalloc(sizeof(*l3), GFP_KERNEL); | 230 | l3 = kzalloc(sizeof(*l3), GFP_KERNEL); |
232 | if (!l3) { | 231 | if (!l3) { |
@@ -249,18 +248,17 @@ static int __init omap3_l3_probe(struct platform_device *pdev) | |||
249 | goto err2; | 248 | goto err2; |
250 | } | 249 | } |
251 | 250 | ||
252 | irq = platform_get_irq(pdev, 0); | 251 | l3->debug_irq = platform_get_irq(pdev, 0); |
253 | ret = request_irq(irq, omap3_l3_app_irq, | 252 | ret = request_irq(l3->debug_irq, omap3_l3_app_irq, |
254 | IRQF_DISABLED | IRQF_TRIGGER_RISING, | 253 | IRQF_DISABLED | IRQF_TRIGGER_RISING, |
255 | "l3-debug-irq", l3); | 254 | "l3-debug-irq", l3); |
256 | if (ret) { | 255 | if (ret) { |
257 | dev_err(&pdev->dev, "couldn't request debug irq\n"); | 256 | dev_err(&pdev->dev, "couldn't request debug irq\n"); |
258 | goto err3; | 257 | goto err3; |
259 | } | 258 | } |
260 | l3->debug_irq = irq; | ||
261 | 259 | ||
262 | irq = platform_get_irq(pdev, 1); | 260 | l3->app_irq = platform_get_irq(pdev, 1); |
263 | ret = request_irq(irq, omap3_l3_app_irq, | 261 | ret = request_irq(l3->app_irq, omap3_l3_app_irq, |
264 | IRQF_DISABLED | IRQF_TRIGGER_RISING, | 262 | IRQF_DISABLED | IRQF_TRIGGER_RISING, |
265 | "l3-app-irq", l3); | 263 | "l3-app-irq", l3); |
266 | 264 | ||
@@ -269,7 +267,6 @@ static int __init omap3_l3_probe(struct platform_device *pdev) | |||
269 | goto err4; | 267 | goto err4; |
270 | } | 268 | } |
271 | 269 | ||
272 | l3->app_irq = irq; | ||
273 | goto err0; | 270 | goto err0; |
274 | 271 | ||
275 | err4: | 272 | err4: |
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 2675fae52537..f979b892e4fa 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/regulator/machine.h> | 14 | #include <linux/regulator/machine.h> |
15 | #include <linux/regulator/ab8500.h> | 15 | #include <linux/regulator/ab8500.h> |
16 | 16 | ||
17 | extern struct ab8500_regulator_reg_init | ||
18 | ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; | ||
17 | extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; | 19 | extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; |
18 | 20 | ||
19 | #endif | 21 | #endif |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 8790d984cac8..d0076453d7ff 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/amba/serial.h> | 20 | #include <linux/amba/serial.h> |
21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
22 | #include <linux/mfd/ab8500.h> | 22 | #include <linux/mfd/ab8500.h> |
23 | #include <linux/regulator/ab8500.h> | ||
23 | #include <linux/mfd/tc3589x.h> | 24 | #include <linux/mfd/tc3589x.h> |
24 | #include <linux/leds-lp5521.h> | 25 | #include <linux/leds-lp5521.h> |
25 | #include <linux/input.h> | 26 | #include <linux/input.h> |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index b3b0f0f5053d..e5f6fc428348 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -78,7 +78,7 @@ __tagtable(ATAG_INITRD2, parse_tag_initrd2); | |||
78 | */ | 78 | */ |
79 | struct meminfo meminfo; | 79 | struct meminfo meminfo; |
80 | 80 | ||
81 | void show_mem(void) | 81 | void show_mem(unsigned int filter) |
82 | { | 82 | { |
83 | int free = 0, total = 0, reserved = 0; | 83 | int free = 0, total = 0, reserved = 0; |
84 | int shared = 0, cached = 0, slab = 0, i; | 84 | int shared = 0, cached = 0, slab = 0, i; |
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 70620426ee55..80643bc38e10 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -832,51 +832,6 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
832 | : "? ", | 832 | : "? ", |
833 | (mode < 0) ? "unknown" : modes[mode], | 833 | (mode < 0) ? "unknown" : modes[mode], |
834 | pull ? "pull" : "none"); | 834 | pull ? "pull" : "none"); |
835 | |||
836 | if (!is_out) { | ||
837 | int irq = gpio_to_irq(gpio); | ||
838 | struct irq_desc *desc = irq_to_desc(irq); | ||
839 | |||
840 | /* This races with request_irq(), set_irq_type(), | ||
841 | * and set_irq_wake() ... but those are "rare". | ||
842 | * | ||
843 | * More significantly, trigger type flags aren't | ||
844 | * currently maintained by genirq. | ||
845 | */ | ||
846 | if (irq >= 0 && desc->action) { | ||
847 | char *trigger; | ||
848 | |||
849 | switch (desc->status & IRQ_TYPE_SENSE_MASK) { | ||
850 | case IRQ_TYPE_NONE: | ||
851 | trigger = "(default)"; | ||
852 | break; | ||
853 | case IRQ_TYPE_EDGE_FALLING: | ||
854 | trigger = "edge-falling"; | ||
855 | break; | ||
856 | case IRQ_TYPE_EDGE_RISING: | ||
857 | trigger = "edge-rising"; | ||
858 | break; | ||
859 | case IRQ_TYPE_EDGE_BOTH: | ||
860 | trigger = "edge-both"; | ||
861 | break; | ||
862 | case IRQ_TYPE_LEVEL_HIGH: | ||
863 | trigger = "level-high"; | ||
864 | break; | ||
865 | case IRQ_TYPE_LEVEL_LOW: | ||
866 | trigger = "level-low"; | ||
867 | break; | ||
868 | default: | ||
869 | trigger = "?trigger?"; | ||
870 | break; | ||
871 | } | ||
872 | |||
873 | seq_printf(s, " irq-%d %s%s", | ||
874 | irq, trigger, | ||
875 | (desc->status & IRQ_WAKEUP) | ||
876 | ? " wakeup" : ""); | ||
877 | } | ||
878 | } | ||
879 | |||
880 | seq_printf(s, "\n"); | 835 | seq_printf(s, "\n"); |
881 | } | 836 | } |
882 | } | 837 | } |
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index d77928370463..5a25098ea7ea 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h | |||
@@ -416,7 +416,7 @@ | |||
416 | 416 | ||
417 | /* GPMC related */ | 417 | /* GPMC related */ |
418 | #define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END) | 418 | #define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END) |
419 | #define OMAP_GPMC_NR_IRQS 7 | 419 | #define OMAP_GPMC_NR_IRQS 8 |
420 | #define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS) | 420 | #define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS) |
421 | 421 | ||
422 | 422 | ||
diff --git a/arch/arm/plat-omap/include/plat/onenand.h b/arch/arm/plat-omap/include/plat/onenand.h index cbe897ca7f9e..2858667d2e4f 100644 --- a/arch/arm/plat-omap/include/plat/onenand.h +++ b/arch/arm/plat-omap/include/plat/onenand.h | |||
@@ -32,6 +32,7 @@ struct omap_onenand_platform_data { | |||
32 | int dma_channel; | 32 | int dma_channel; |
33 | u8 flags; | 33 | u8 flags; |
34 | u8 regulator_can_sleep; | 34 | u8 regulator_can_sleep; |
35 | u8 skip_initial_unlocking; | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | #define ONENAND_MAX_PARTITIONS 8 | 38 | #define ONENAND_MAX_PARTITIONS 8 |
diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h index 01a8448e471c..442301fe48b4 100644 --- a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h +++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h | |||
@@ -30,6 +30,7 @@ struct pxa3xx_nand_cmdset { | |||
30 | }; | 30 | }; |
31 | 31 | ||
32 | struct pxa3xx_nand_flash { | 32 | struct pxa3xx_nand_flash { |
33 | char *name; | ||
33 | uint32_t chip_id; | 34 | uint32_t chip_id; |
34 | unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */ | 35 | unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */ |
35 | unsigned int page_size; /* Page size in bytes (PAGE_SZ) */ | 36 | unsigned int page_size; /* Page size in bytes (PAGE_SZ) */ |
@@ -37,7 +38,6 @@ struct pxa3xx_nand_flash { | |||
37 | unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ | 38 | unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ |
38 | unsigned int num_blocks; /* Number of physical blocks in Flash */ | 39 | unsigned int num_blocks; /* Number of physical blocks in Flash */ |
39 | 40 | ||
40 | struct pxa3xx_nand_cmdset *cmdset; /* NAND command set */ | ||
41 | struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ | 41 | struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ |
42 | }; | 42 | }; |
43 | 43 | ||
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index cd2062fe0f61..49642b59f73d 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig | |||
@@ -6,6 +6,11 @@ config AVR32 | |||
6 | select HAVE_CLK | 6 | select HAVE_CLK |
7 | select HAVE_OPROFILE | 7 | select HAVE_OPROFILE |
8 | select HAVE_KPROBES | 8 | select HAVE_KPROBES |
9 | select HAVE_GENERIC_HARDIRQS | ||
10 | select GENERIC_IRQ_PROBE | ||
11 | select HARDIRQS_SW_RESEND | ||
12 | select GENERIC_IRQ_SHOW | ||
13 | select GENERIC_HARDIRQS_NO_DEPRECATED | ||
9 | help | 14 | help |
10 | AVR32 is a high-performance 32-bit RISC microprocessor core, | 15 | AVR32 is a high-performance 32-bit RISC microprocessor core, |
11 | designed for cost-sensitive embedded applications, with particular | 16 | designed for cost-sensitive embedded applications, with particular |
@@ -17,9 +22,6 @@ config AVR32 | |||
17 | config GENERIC_GPIO | 22 | config GENERIC_GPIO |
18 | def_bool y | 23 | def_bool y |
19 | 24 | ||
20 | config GENERIC_HARDIRQS | ||
21 | def_bool y | ||
22 | |||
23 | config STACKTRACE_SUPPORT | 25 | config STACKTRACE_SUPPORT |
24 | def_bool y | 26 | def_bool y |
25 | 27 | ||
@@ -29,12 +31,6 @@ config LOCKDEP_SUPPORT | |||
29 | config TRACE_IRQFLAGS_SUPPORT | 31 | config TRACE_IRQFLAGS_SUPPORT |
30 | def_bool y | 32 | def_bool y |
31 | 33 | ||
32 | config HARDIRQS_SW_RESEND | ||
33 | def_bool y | ||
34 | |||
35 | config GENERIC_IRQ_PROBE | ||
36 | def_bool y | ||
37 | |||
38 | config RWSEM_GENERIC_SPINLOCK | 34 | config RWSEM_GENERIC_SPINLOCK |
39 | def_bool y | 35 | def_bool y |
40 | 36 | ||
diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c index 7919be311f4a..f91431963452 100644 --- a/arch/avr32/boards/atngw100/mrmt.c +++ b/arch/avr32/boards/atngw100/mrmt.c | |||
@@ -301,7 +301,7 @@ static int __init mrmt1_init(void) | |||
301 | /* Select the Touchscreen interrupt pin mode */ | 301 | /* Select the Touchscreen interrupt pin mode */ |
302 | at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ), | 302 | at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ), |
303 | GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); | 303 | GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); |
304 | set_irq_type( AT32_EXTINT(TS_IRQ), IRQ_TYPE_EDGE_FALLING ); | 304 | irq_set_irq_type(AT32_EXTINT(TS_IRQ), IRQ_TYPE_EDGE_FALLING); |
305 | at32_spi_setup_slaves(0,spi01_board_info,ARRAY_SIZE(spi01_board_info)); | 305 | at32_spi_setup_slaves(0,spi01_board_info,ARRAY_SIZE(spi01_board_info)); |
306 | spi_register_board_info(spi01_board_info,ARRAY_SIZE(spi01_board_info)); | 306 | spi_register_board_info(spi01_board_info,ARRAY_SIZE(spi01_board_info)); |
307 | #endif | 307 | #endif |
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 659d119ce712..fafed4c38fd2 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c | |||
@@ -322,6 +322,6 @@ static int __init atngw100_arch_init(void) | |||
322 | /* set_irq_type() after the arch_initcall for EIC has run, and | 322 | /* set_irq_type() after the arch_initcall for EIC has run, and |
323 | * before the I2C subsystem could try using this IRQ. | 323 | * before the I2C subsystem could try using this IRQ. |
324 | */ | 324 | */ |
325 | return set_irq_type(AT32_EXTINT(3), IRQ_TYPE_EDGE_FALLING); | 325 | return irq_set_irq_type(AT32_EXTINT(3), IRQ_TYPE_EDGE_FALLING); |
326 | } | 326 | } |
327 | arch_initcall(atngw100_arch_init); | 327 | arch_initcall(atngw100_arch_init); |
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c index 9604f7758f9a..bc3aa18293df 100644 --- a/arch/avr32/kernel/irq.c +++ b/arch/avr32/kernel/irq.c | |||
@@ -26,40 +26,3 @@ void __weak nmi_disable(void) | |||
26 | { | 26 | { |
27 | 27 | ||
28 | } | 28 | } |
29 | |||
30 | #ifdef CONFIG_PROC_FS | ||
31 | int show_interrupts(struct seq_file *p, void *v) | ||
32 | { | ||
33 | int i = *(loff_t *)v, cpu; | ||
34 | struct irqaction *action; | ||
35 | unsigned long flags; | ||
36 | |||
37 | if (i == 0) { | ||
38 | seq_puts(p, " "); | ||
39 | for_each_online_cpu(cpu) | ||
40 | seq_printf(p, "CPU%d ", cpu); | ||
41 | seq_putc(p, '\n'); | ||
42 | } | ||
43 | |||
44 | if (i < NR_IRQS) { | ||
45 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
46 | action = irq_desc[i].action; | ||
47 | if (!action) | ||
48 | goto unlock; | ||
49 | |||
50 | seq_printf(p, "%3d: ", i); | ||
51 | for_each_online_cpu(cpu) | ||
52 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); | ||
53 | seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-"); | ||
54 | seq_printf(p, " %s", action->name); | ||
55 | for (action = action->next; action; action = action->next) | ||
56 | seq_printf(p, ", %s", action->name); | ||
57 | |||
58 | seq_putc(p, '\n'); | ||
59 | unlock: | ||
60 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
61 | } | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | #endif | ||
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index e9d12058ffd3..47ba4b9b6db1 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c | |||
@@ -61,45 +61,42 @@ struct eic { | |||
61 | static struct eic *nmi_eic; | 61 | static struct eic *nmi_eic; |
62 | static bool nmi_enabled; | 62 | static bool nmi_enabled; |
63 | 63 | ||
64 | static void eic_ack_irq(unsigned int irq) | 64 | static void eic_ack_irq(struct irq_chip *d) |
65 | { | 65 | { |
66 | struct eic *eic = get_irq_chip_data(irq); | 66 | struct eic *eic = irq_data_get_irq_chip_data(data); |
67 | eic_writel(eic, ICR, 1 << (irq - eic->first_irq)); | 67 | eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq)); |
68 | } | 68 | } |
69 | 69 | ||
70 | static void eic_mask_irq(unsigned int irq) | 70 | static void eic_mask_irq(struct irq_chip *d) |
71 | { | 71 | { |
72 | struct eic *eic = get_irq_chip_data(irq); | 72 | struct eic *eic = irq_data_get_irq_chip_data(data); |
73 | eic_writel(eic, IDR, 1 << (irq - eic->first_irq)); | 73 | eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq)); |
74 | } | 74 | } |
75 | 75 | ||
76 | static void eic_mask_ack_irq(unsigned int irq) | 76 | static void eic_mask_ack_irq(struct irq_chip *d) |
77 | { | 77 | { |
78 | struct eic *eic = get_irq_chip_data(irq); | 78 | struct eic *eic = irq_data_get_irq_chip_data(data); |
79 | eic_writel(eic, ICR, 1 << (irq - eic->first_irq)); | 79 | eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq)); |
80 | eic_writel(eic, IDR, 1 << (irq - eic->first_irq)); | 80 | eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq)); |
81 | } | 81 | } |
82 | 82 | ||
83 | static void eic_unmask_irq(unsigned int irq) | 83 | static void eic_unmask_irq(struct irq_chip *d) |
84 | { | 84 | { |
85 | struct eic *eic = get_irq_chip_data(irq); | 85 | struct eic *eic = irq_data_get_irq_chip_data(data); |
86 | eic_writel(eic, IER, 1 << (irq - eic->first_irq)); | 86 | eic_writel(eic, IER, 1 << (d->irq - eic->first_irq)); |
87 | } | 87 | } |
88 | 88 | ||
89 | static int eic_set_irq_type(unsigned int irq, unsigned int flow_type) | 89 | static int eic_set_irq_type(struct irq_chip *d, unsigned int flow_type) |
90 | { | 90 | { |
91 | struct eic *eic = get_irq_chip_data(irq); | 91 | struct eic *eic = irq_data_get_irq_chip_data(data); |
92 | struct irq_desc *desc; | 92 | unsigned int irq = d->irq; |
93 | unsigned int i = irq - eic->first_irq; | 93 | unsigned int i = irq - eic->first_irq; |
94 | u32 mode, edge, level; | 94 | u32 mode, edge, level; |
95 | int ret = 0; | ||
96 | 95 | ||
97 | flow_type &= IRQ_TYPE_SENSE_MASK; | 96 | flow_type &= IRQ_TYPE_SENSE_MASK; |
98 | if (flow_type == IRQ_TYPE_NONE) | 97 | if (flow_type == IRQ_TYPE_NONE) |
99 | flow_type = IRQ_TYPE_LEVEL_LOW; | 98 | flow_type = IRQ_TYPE_LEVEL_LOW; |
100 | 99 | ||
101 | desc = &irq_desc[irq]; | ||
102 | |||
103 | mode = eic_readl(eic, MODE); | 100 | mode = eic_readl(eic, MODE); |
104 | edge = eic_readl(eic, EDGE); | 101 | edge = eic_readl(eic, EDGE); |
105 | level = eic_readl(eic, LEVEL); | 102 | level = eic_readl(eic, LEVEL); |
@@ -122,39 +119,34 @@ static int eic_set_irq_type(unsigned int irq, unsigned int flow_type) | |||
122 | edge &= ~(1 << i); | 119 | edge &= ~(1 << i); |
123 | break; | 120 | break; |
124 | default: | 121 | default: |
125 | ret = -EINVAL; | 122 | return -EINVAL; |
126 | break; | ||
127 | } | 123 | } |
128 | 124 | ||
129 | if (ret == 0) { | 125 | eic_writel(eic, MODE, mode); |
130 | eic_writel(eic, MODE, mode); | 126 | eic_writel(eic, EDGE, edge); |
131 | eic_writel(eic, EDGE, edge); | 127 | eic_writel(eic, LEVEL, level); |
132 | eic_writel(eic, LEVEL, level); | ||
133 | |||
134 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { | ||
135 | flow_type |= IRQ_LEVEL; | ||
136 | __set_irq_handler_unlocked(irq, handle_level_irq); | ||
137 | } else | ||
138 | __set_irq_handler_unlocked(irq, handle_edge_irq); | ||
139 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | ||
140 | desc->status |= flow_type; | ||
141 | } | ||
142 | 128 | ||
143 | return ret; | 129 | irqd_set_trigger_type(d, flow_type); |
130 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||
131 | __irq_set_handler_locked(irq, handle_level_irq); | ||
132 | else | ||
133 | __irq_set_handler_locked(irq, handle_edge_irq); | ||
134 | |||
135 | return IRQ_SET_MASK_OK_NOCOPY; | ||
144 | } | 136 | } |
145 | 137 | ||
146 | static struct irq_chip eic_chip = { | 138 | static struct irq_chip eic_chip = { |
147 | .name = "eic", | 139 | .name = "eic", |
148 | .ack = eic_ack_irq, | 140 | .irq_ack = eic_ack_irq, |
149 | .mask = eic_mask_irq, | 141 | .irq_mask = eic_mask_irq, |
150 | .mask_ack = eic_mask_ack_irq, | 142 | .irq_mask_ack = eic_mask_ack_irq, |
151 | .unmask = eic_unmask_irq, | 143 | .irq_unmask = eic_unmask_irq, |
152 | .set_type = eic_set_irq_type, | 144 | .irq_set_type = eic_set_irq_type, |
153 | }; | 145 | }; |
154 | 146 | ||
155 | static void demux_eic_irq(unsigned int irq, struct irq_desc *desc) | 147 | static void demux_eic_irq(unsigned int irq, struct irq_desc *desc) |
156 | { | 148 | { |
157 | struct eic *eic = desc->handler_data; | 149 | struct eic *eic = irq_desc_get_handler_data(desc); |
158 | unsigned long status, pending; | 150 | unsigned long status, pending; |
159 | unsigned int i; | 151 | unsigned int i; |
160 | 152 | ||
@@ -234,13 +226,13 @@ static int __init eic_probe(struct platform_device *pdev) | |||
234 | eic->chip = &eic_chip; | 226 | eic->chip = &eic_chip; |
235 | 227 | ||
236 | for (i = 0; i < nr_of_irqs; i++) { | 228 | for (i = 0; i < nr_of_irqs; i++) { |
237 | set_irq_chip_and_handler(eic->first_irq + i, &eic_chip, | 229 | irq_set_chip_and_handler(eic->first_irq + i, &eic_chip, |
238 | handle_level_irq); | 230 | handle_level_irq); |
239 | set_irq_chip_data(eic->first_irq + i, eic); | 231 | irq_set_chip_data(eic->first_irq + i, eic); |
240 | } | 232 | } |
241 | 233 | ||
242 | set_irq_chained_handler(int_irq, demux_eic_irq); | 234 | irq_set_chained_handler(int_irq, demux_eic_irq); |
243 | set_irq_data(int_irq, eic); | 235 | irq_set_handler_data(int_irq, eic); |
244 | 236 | ||
245 | if (pdev->id == 0) { | 237 | if (pdev->id == 0) { |
246 | nmi_eic = eic; | 238 | nmi_eic = eic; |
diff --git a/arch/avr32/mach-at32ap/intc.c b/arch/avr32/mach-at32ap/intc.c index 994c4545e2b7..21ce35f33aa5 100644 --- a/arch/avr32/mach-at32ap/intc.c +++ b/arch/avr32/mach-at32ap/intc.c | |||
@@ -34,12 +34,12 @@ extern struct platform_device at32_intc0_device; | |||
34 | * TODO: We may be able to implement mask/unmask by setting IxM flags | 34 | * TODO: We may be able to implement mask/unmask by setting IxM flags |
35 | * in the status register. | 35 | * in the status register. |
36 | */ | 36 | */ |
37 | static void intc_mask_irq(unsigned int irq) | 37 | static void intc_mask_irq(struct irq_data *d) |
38 | { | 38 | { |
39 | 39 | ||
40 | } | 40 | } |
41 | 41 | ||
42 | static void intc_unmask_irq(unsigned int irq) | 42 | static void intc_unmask_irq(struct irq_data *d) |
43 | { | 43 | { |
44 | 44 | ||
45 | } | 45 | } |
@@ -47,8 +47,8 @@ static void intc_unmask_irq(unsigned int irq) | |||
47 | static struct intc intc0 = { | 47 | static struct intc intc0 = { |
48 | .chip = { | 48 | .chip = { |
49 | .name = "intc", | 49 | .name = "intc", |
50 | .mask = intc_mask_irq, | 50 | .irq_mask = intc_mask_irq, |
51 | .unmask = intc_unmask_irq, | 51 | .irq_unmask = intc_unmask_irq, |
52 | }, | 52 | }, |
53 | }; | 53 | }; |
54 | 54 | ||
@@ -57,7 +57,6 @@ static struct intc intc0 = { | |||
57 | */ | 57 | */ |
58 | asmlinkage void do_IRQ(int level, struct pt_regs *regs) | 58 | asmlinkage void do_IRQ(int level, struct pt_regs *regs) |
59 | { | 59 | { |
60 | struct irq_desc *desc; | ||
61 | struct pt_regs *old_regs; | 60 | struct pt_regs *old_regs; |
62 | unsigned int irq; | 61 | unsigned int irq; |
63 | unsigned long status_reg; | 62 | unsigned long status_reg; |
@@ -69,8 +68,7 @@ asmlinkage void do_IRQ(int level, struct pt_regs *regs) | |||
69 | irq_enter(); | 68 | irq_enter(); |
70 | 69 | ||
71 | irq = intc_readl(&intc0, INTCAUSE0 - 4 * level); | 70 | irq = intc_readl(&intc0, INTCAUSE0 - 4 * level); |
72 | desc = irq_desc + irq; | 71 | generic_handle_irq(irq); |
73 | desc->handle_irq(irq, desc); | ||
74 | 72 | ||
75 | /* | 73 | /* |
76 | * Clear all interrupt level masks so that we may handle | 74 | * Clear all interrupt level masks so that we may handle |
@@ -128,7 +126,7 @@ void __init init_IRQ(void) | |||
128 | intc_writel(&intc0, INTPR0 + 4 * i, offset); | 126 | intc_writel(&intc0, INTPR0 + 4 * i, offset); |
129 | readback = intc_readl(&intc0, INTPR0 + 4 * i); | 127 | readback = intc_readl(&intc0, INTPR0 + 4 * i); |
130 | if (readback == offset) | 128 | if (readback == offset) |
131 | set_irq_chip_and_handler(i, &intc0.chip, | 129 | irq_set_chip_and_handler(i, &intc0.chip, |
132 | handle_simple_irq); | 130 | handle_simple_irq); |
133 | } | 131 | } |
134 | 132 | ||
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index 09a274c9d0b7..37534103574e 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c | |||
@@ -249,23 +249,23 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
249 | 249 | ||
250 | /* GPIO IRQ support */ | 250 | /* GPIO IRQ support */ |
251 | 251 | ||
252 | static void gpio_irq_mask(unsigned irq) | 252 | static void gpio_irq_mask(struct irq_data *d) |
253 | { | 253 | { |
254 | unsigned gpio = irq_to_gpio(irq); | 254 | unsigned gpio = irq_to_gpio(d->irq); |
255 | struct pio_device *pio = &pio_dev[gpio >> 5]; | 255 | struct pio_device *pio = &pio_dev[gpio >> 5]; |
256 | 256 | ||
257 | pio_writel(pio, IDR, 1 << (gpio & 0x1f)); | 257 | pio_writel(pio, IDR, 1 << (gpio & 0x1f)); |
258 | } | 258 | } |
259 | 259 | ||
260 | static void gpio_irq_unmask(unsigned irq) | 260 | static void gpio_irq_unmask(struct irq_data *d)) |
261 | { | 261 | { |
262 | unsigned gpio = irq_to_gpio(irq); | 262 | unsigned gpio = irq_to_gpio(d->irq); |
263 | struct pio_device *pio = &pio_dev[gpio >> 5]; | 263 | struct pio_device *pio = &pio_dev[gpio >> 5]; |
264 | 264 | ||
265 | pio_writel(pio, IER, 1 << (gpio & 0x1f)); | 265 | pio_writel(pio, IER, 1 << (gpio & 0x1f)); |
266 | } | 266 | } |
267 | 267 | ||
268 | static int gpio_irq_type(unsigned irq, unsigned type) | 268 | static int gpio_irq_type(struct irq_data *d, unsigned type) |
269 | { | 269 | { |
270 | if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE) | 270 | if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE) |
271 | return -EINVAL; | 271 | return -EINVAL; |
@@ -275,20 +275,19 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
275 | 275 | ||
276 | static struct irq_chip gpio_irqchip = { | 276 | static struct irq_chip gpio_irqchip = { |
277 | .name = "gpio", | 277 | .name = "gpio", |
278 | .mask = gpio_irq_mask, | 278 | .irq_mask = gpio_irq_mask, |
279 | .unmask = gpio_irq_unmask, | 279 | .irq_unmask = gpio_irq_unmask, |
280 | .set_type = gpio_irq_type, | 280 | .irq_set_type = gpio_irq_type, |
281 | }; | 281 | }; |
282 | 282 | ||
283 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | 283 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) |
284 | { | 284 | { |
285 | struct pio_device *pio = get_irq_chip_data(irq); | 285 | struct pio_device *pio = get_irq_desc_chip_data(desc); |
286 | unsigned gpio_irq; | 286 | unsigned gpio_irq; |
287 | 287 | ||
288 | gpio_irq = (unsigned) get_irq_data(irq); | 288 | gpio_irq = (unsigned) irq_get_handler_data(irq); |
289 | for (;;) { | 289 | for (;;) { |
290 | u32 isr; | 290 | u32 isr; |
291 | struct irq_desc *d; | ||
292 | 291 | ||
293 | /* ack pending GPIO interrupts */ | 292 | /* ack pending GPIO interrupts */ |
294 | isr = pio_readl(pio, ISR) & pio_readl(pio, IMR); | 293 | isr = pio_readl(pio, ISR) & pio_readl(pio, IMR); |
@@ -301,9 +300,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
301 | isr &= ~(1 << i); | 300 | isr &= ~(1 << i); |
302 | 301 | ||
303 | i += gpio_irq; | 302 | i += gpio_irq; |
304 | d = &irq_desc[i]; | 303 | generic_handle_irq(i); |
305 | |||
306 | d->handle_irq(i, d); | ||
307 | } while (isr); | 304 | } while (isr); |
308 | } | 305 | } |
309 | } | 306 | } |
@@ -313,16 +310,16 @@ gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) | |||
313 | { | 310 | { |
314 | unsigned i; | 311 | unsigned i; |
315 | 312 | ||
316 | set_irq_chip_data(irq, pio); | 313 | irq_set_chip_data(irq, pio); |
317 | set_irq_data(irq, (void *) gpio_irq); | 314 | irq_set_handler_data(irq, (void *)gpio_irq); |
318 | 315 | ||
319 | for (i = 0; i < 32; i++, gpio_irq++) { | 316 | for (i = 0; i < 32; i++, gpio_irq++) { |
320 | set_irq_chip_data(gpio_irq, pio); | 317 | irq_set_chip_data(gpio_irq, pio); |
321 | set_irq_chip_and_handler(gpio_irq, &gpio_irqchip, | 318 | irq_set_chip_and_handler(gpio_irq, &gpio_irqchip, |
322 | handle_simple_irq); | 319 | handle_simple_irq); |
323 | } | 320 | } |
324 | 321 | ||
325 | set_irq_chained_handler(irq, gpio_irq_handler); | 322 | irq_set_chained_handler(irq, gpio_irq_handler); |
326 | } | 323 | } |
327 | 324 | ||
328 | /*--------------------------------------------------------------------------*/ | 325 | /*--------------------------------------------------------------------------*/ |
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 4db5b46e1eff..04a7fc5eaf46 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig | |||
@@ -276,7 +276,6 @@ config ETRAX_AXISFLASHMAP | |||
276 | select MTD_CHAR | 276 | select MTD_CHAR |
277 | select MTD_BLOCK | 277 | select MTD_BLOCK |
278 | select MTD_PARTITIONS | 278 | select MTD_PARTITIONS |
279 | select MTD_CONCAT | ||
280 | select MTD_COMPLEX_MAPPINGS | 279 | select MTD_COMPLEX_MAPPINGS |
281 | help | 280 | help |
282 | This option enables MTD mapping of flash devices. Needed to use | 281 | This option enables MTD mapping of flash devices. Needed to use |
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c index b2079703af7e..ed708e19d09e 100644 --- a/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/arch/cris/arch-v10/drivers/axisflashmap.c | |||
@@ -234,7 +234,6 @@ static struct mtd_info *flash_probe(void) | |||
234 | } | 234 | } |
235 | 235 | ||
236 | if (mtd_cse0 && mtd_cse1) { | 236 | if (mtd_cse0 && mtd_cse1) { |
237 | #ifdef CONFIG_MTD_CONCAT | ||
238 | struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; | 237 | struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 }; |
239 | 238 | ||
240 | /* Since the concatenation layer adds a small overhead we | 239 | /* Since the concatenation layer adds a small overhead we |
@@ -246,11 +245,6 @@ static struct mtd_info *flash_probe(void) | |||
246 | */ | 245 | */ |
247 | mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds), | 246 | mtd_cse = mtd_concat_create(mtds, ARRAY_SIZE(mtds), |
248 | "cse0+cse1"); | 247 | "cse0+cse1"); |
249 | #else | ||
250 | printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " | ||
251 | "(mis)configuration!\n", map_cse0.name, map_cse1.name); | ||
252 | mtd_cse = NULL; | ||
253 | #endif | ||
254 | if (!mtd_cse) { | 248 | if (!mtd_cse) { |
255 | printk(KERN_ERR "%s and %s: Concatenation failed!\n", | 249 | printk(KERN_ERR "%s and %s: Concatenation failed!\n", |
256 | map_cse0.name, map_cse1.name); | 250 | map_cse0.name, map_cse1.name); |
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index a2dd740c5907..1633b120aa81 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig | |||
@@ -406,7 +406,6 @@ config ETRAX_AXISFLASHMAP | |||
406 | select MTD_CHAR | 406 | select MTD_CHAR |
407 | select MTD_BLOCK | 407 | select MTD_BLOCK |
408 | select MTD_PARTITIONS | 408 | select MTD_PARTITIONS |
409 | select MTD_CONCAT | ||
410 | select MTD_COMPLEX_MAPPINGS | 409 | select MTD_COMPLEX_MAPPINGS |
411 | help | 410 | help |
412 | This option enables MTD mapping of flash devices. Needed to use | 411 | This option enables MTD mapping of flash devices. Needed to use |
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c index 51e1e85df96d..3d751250271b 100644 --- a/arch/cris/arch-v32/drivers/axisflashmap.c +++ b/arch/cris/arch-v32/drivers/axisflashmap.c | |||
@@ -275,7 +275,6 @@ static struct mtd_info *flash_probe(void) | |||
275 | } | 275 | } |
276 | 276 | ||
277 | if (count > 1) { | 277 | if (count > 1) { |
278 | #ifdef CONFIG_MTD_CONCAT | ||
279 | /* Since the concatenation layer adds a small overhead we | 278 | /* Since the concatenation layer adds a small overhead we |
280 | * could try to figure out if the chips in cse0 and cse1 are | 279 | * could try to figure out if the chips in cse0 and cse1 are |
281 | * identical and reprobe the whole cse0+cse1 window. But since | 280 | * identical and reprobe the whole cse0+cse1 window. But since |
@@ -284,11 +283,6 @@ static struct mtd_info *flash_probe(void) | |||
284 | * complicating the probing procedure. | 283 | * complicating the probing procedure. |
285 | */ | 284 | */ |
286 | mtd_total = mtd_concat_create(mtds, count, "cse0+cse1"); | 285 | mtd_total = mtd_concat_create(mtds, count, "cse0+cse1"); |
287 | #else | ||
288 | printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel " | ||
289 | "(mis)configuration!\n", map_cse0.name, map_cse1.name); | ||
290 | mtd_toal = NULL; | ||
291 | #endif | ||
292 | if (!mtd_total) { | 286 | if (!mtd_total) { |
293 | printk(KERN_ERR "%s and %s: Concatenation failed!\n", | 287 | printk(KERN_ERR "%s and %s: Concatenation failed!\n", |
294 | map_cse0.name, map_cse1.name); | 288 | map_cse0.name, map_cse1.name); |
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 9624db193e3c..931a1ac99ff1 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig | |||
@@ -4,6 +4,7 @@ config H8300 | |||
4 | select HAVE_IDE | 4 | select HAVE_IDE |
5 | select HAVE_GENERIC_HARDIRQS | 5 | select HAVE_GENERIC_HARDIRQS |
6 | select GENERIC_HARDIRQS_NO_DEPRECATED | 6 | select GENERIC_HARDIRQS_NO_DEPRECATED |
7 | select GENERIC_IRQ_SHOW | ||
7 | 8 | ||
8 | config SYMBOL_PREFIX | 9 | config SYMBOL_PREFIX |
9 | string | 10 | string |
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c index 7643d39925d6..1f67fed476af 100644 --- a/arch/h8300/kernel/irq.c +++ b/arch/h8300/kernel/irq.c | |||
@@ -155,7 +155,7 @@ void __init init_IRQ(void) | |||
155 | setup_vector(); | 155 | setup_vector(); |
156 | 156 | ||
157 | for (c = 0; c < NR_IRQS; c++) | 157 | for (c = 0; c < NR_IRQS; c++) |
158 | set_irq_chip_and_handler(c, &h8300irq_chip, handle_simple_irq); | 158 | irq_set_chip_and_handler(c, &h8300irq_chip, handle_simple_irq); |
159 | } | 159 | } |
160 | 160 | ||
161 | asmlinkage void do_IRQ(int irq) | 161 | asmlinkage void do_IRQ(int irq) |
@@ -164,34 +164,3 @@ asmlinkage void do_IRQ(int irq) | |||
164 | generic_handle_irq(irq); | 164 | generic_handle_irq(irq); |
165 | irq_exit(); | 165 | irq_exit(); |
166 | } | 166 | } |
167 | |||
168 | #if defined(CONFIG_PROC_FS) | ||
169 | int show_interrupts(struct seq_file *p, void *v) | ||
170 | { | ||
171 | int i = *(loff_t *) v; | ||
172 | struct irqaction * action; | ||
173 | unsigned long flags; | ||
174 | |||
175 | if (i == 0) | ||
176 | seq_puts(p, " CPU0"); | ||
177 | |||
178 | if (i < NR_IRQS) { | ||
179 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
180 | action = irq_desc[i].action; | ||
181 | if (!action) | ||
182 | goto unlock; | ||
183 | seq_printf(p, "%3d: ",i); | ||
184 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
185 | seq_printf(p, " %14s", irq_desc[i].irq_data.chip->name); | ||
186 | seq_printf(p, "-%-8s", irq_desc[i].name); | ||
187 | seq_printf(p, " %s", action->name); | ||
188 | |||
189 | for (action=action->next; action; action = action->next) | ||
190 | seq_printf(p, ", %s", action->name); | ||
191 | seq_putc(p, '\n'); | ||
192 | unlock: | ||
193 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
194 | } | ||
195 | return 0; | ||
196 | } | ||
197 | #endif | ||
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 54bf54059811..9a018cde5d84 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c | |||
@@ -36,7 +36,7 @@ static unsigned long max_gap; | |||
36 | * Shows a simple page count of reserved and used pages in the system. | 36 | * Shows a simple page count of reserved and used pages in the system. |
37 | * For discontig machines, it does this on a per-pgdat basis. | 37 | * For discontig machines, it does this on a per-pgdat basis. |
38 | */ | 38 | */ |
39 | void show_mem(void) | 39 | void show_mem(unsigned int filter) |
40 | { | 40 | { |
41 | int i, total_reserved = 0; | 41 | int i, total_reserved = 0; |
42 | int total_shared = 0, total_cached = 0; | 42 | int total_shared = 0, total_cached = 0; |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 61620323bb60..82ab1bc6afb1 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -614,7 +614,7 @@ void __cpuinit *per_cpu_init(void) | |||
614 | * Shows a simple page count of reserved and used pages in the system. | 614 | * Shows a simple page count of reserved and used pages in the system. |
615 | * For discontig machines, it does this on a per-pgdat basis. | 615 | * For discontig machines, it does this on a per-pgdat basis. |
616 | */ | 616 | */ |
617 | void show_mem(void) | 617 | void show_mem(unsigned int filter) |
618 | { | 618 | { |
619 | int i, total_reserved = 0; | 619 | int i, total_reserved = 0; |
620 | int total_shared = 0, total_cached = 0; | 620 | int total_shared = 0, total_cached = 0; |
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 62afe23c9a49..b28d0908a402 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig | |||
@@ -10,6 +10,7 @@ config M32R | |||
10 | select HAVE_GENERIC_HARDIRQS | 10 | select HAVE_GENERIC_HARDIRQS |
11 | select GENERIC_HARDIRQS_NO_DEPRECATED | 11 | select GENERIC_HARDIRQS_NO_DEPRECATED |
12 | select GENERIC_IRQ_PROBE | 12 | select GENERIC_IRQ_PROBE |
13 | select GENERIC_IRQ_SHOW | ||
13 | 14 | ||
14 | config SBUS | 15 | config SBUS |
15 | bool | 16 | bool |
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c index 76eaf3883fbd..c7272b894283 100644 --- a/arch/m32r/kernel/irq.c +++ b/arch/m32r/kernel/irq.c | |||
@@ -18,55 +18,10 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel_stat.h> | 19 | #include <linux/kernel_stat.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/seq_file.h> | ||
22 | #include <linux/module.h> | 21 | #include <linux/module.h> |
23 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
24 | 23 | ||
25 | /* | 24 | /* |
26 | * Generic, controller-independent functions: | ||
27 | */ | ||
28 | |||
29 | int show_interrupts(struct seq_file *p, void *v) | ||
30 | { | ||
31 | int i = *(loff_t *) v, j; | ||
32 | struct irqaction * action; | ||
33 | unsigned long flags; | ||
34 | |||
35 | if (i == 0) { | ||
36 | seq_printf(p, " "); | ||
37 | for_each_online_cpu(j) | ||
38 | seq_printf(p, "CPU%d ",j); | ||
39 | seq_putc(p, '\n'); | ||
40 | } | ||
41 | |||
42 | if (i < NR_IRQS) { | ||
43 | struct irq_desc *desc = irq_to_desc(i); | ||
44 | |||
45 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
46 | action = desc->action; | ||
47 | if (!action) | ||
48 | goto skip; | ||
49 | seq_printf(p, "%3d: ",i); | ||
50 | #ifndef CONFIG_SMP | ||
51 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
52 | #else | ||
53 | for_each_online_cpu(j) | ||
54 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | ||
55 | #endif | ||
56 | seq_printf(p, " %14s", desc->irq_data.chip->name); | ||
57 | seq_printf(p, " %s", action->name); | ||
58 | |||
59 | for (action=action->next; action; action = action->next) | ||
60 | seq_printf(p, ", %s", action->name); | ||
61 | |||
62 | seq_putc(p, '\n'); | ||
63 | skip: | ||
64 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
65 | } | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * do_IRQ handles all normal device IRQs (the special | 25 | * do_IRQ handles all normal device IRQs (the special |
71 | * SMP cross-CPU interrupts have their own specific | 26 | * SMP cross-CPU interrupts have their own specific |
72 | * handlers). | 27 | * handlers). |
diff --git a/arch/m32r/platforms/m32104ut/setup.c b/arch/m32r/platforms/m32104ut/setup.c index 4a693d02c1e1..34671d32cefc 100644 --- a/arch/m32r/platforms/m32104ut/setup.c +++ b/arch/m32r/platforms/m32104ut/setup.c | |||
@@ -76,7 +76,7 @@ void __init init_IRQ(void) | |||
76 | 76 | ||
77 | #if defined(CONFIG_SMC91X) | 77 | #if defined(CONFIG_SMC91X) |
78 | /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/ | 78 | /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/ |
79 | set_irq_chip_and_handler(M32R_IRQ_INT0, &m32104ut_irq_type, | 79 | irq_set_chip_and_handler(M32R_IRQ_INT0, &m32104ut_irq_type, |
80 | handle_level_irq); | 80 | handle_level_irq); |
81 | /* "H" level sense */ | 81 | /* "H" level sense */ |
82 | cu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; | 82 | cu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; |
@@ -84,20 +84,20 @@ void __init init_IRQ(void) | |||
84 | #endif /* CONFIG_SMC91X */ | 84 | #endif /* CONFIG_SMC91X */ |
85 | 85 | ||
86 | /* MFT2 : system timer */ | 86 | /* MFT2 : system timer */ |
87 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &m32104ut_irq_type, | 87 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &m32104ut_irq_type, |
88 | handle_level_irq); | 88 | handle_level_irq); |
89 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 89 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
90 | disable_m32104ut_irq(M32R_IRQ_MFT2); | 90 | disable_m32104ut_irq(M32R_IRQ_MFT2); |
91 | 91 | ||
92 | #ifdef CONFIG_SERIAL_M32R_SIO | 92 | #ifdef CONFIG_SERIAL_M32R_SIO |
93 | /* SIO0_R : uart receive data */ | 93 | /* SIO0_R : uart receive data */ |
94 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &m32104ut_irq_type, | 94 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &m32104ut_irq_type, |
95 | handle_level_irq); | 95 | handle_level_irq); |
96 | icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN; | 96 | icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN; |
97 | disable_m32104ut_irq(M32R_IRQ_SIO0_R); | 97 | disable_m32104ut_irq(M32R_IRQ_SIO0_R); |
98 | 98 | ||
99 | /* SIO0_S : uart send data */ | 99 | /* SIO0_S : uart send data */ |
100 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &m32104ut_irq_type, | 100 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &m32104ut_irq_type, |
101 | handle_level_irq); | 101 | handle_level_irq); |
102 | icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN; | 102 | icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN; |
103 | disable_m32104ut_irq(M32R_IRQ_SIO0_S); | 103 | disable_m32104ut_irq(M32R_IRQ_SIO0_S); |
diff --git a/arch/m32r/platforms/m32700ut/setup.c b/arch/m32r/platforms/m32700ut/setup.c index 2074bcc841eb..1053e1cb7401 100644 --- a/arch/m32r/platforms/m32700ut/setup.c +++ b/arch/m32r/platforms/m32700ut/setup.c | |||
@@ -259,76 +259,76 @@ void __init init_IRQ(void) | |||
259 | { | 259 | { |
260 | #if defined(CONFIG_SMC91X) | 260 | #if defined(CONFIG_SMC91X) |
261 | /* INT#0: LAN controller on M32700UT-LAN (SMC91C111)*/ | 261 | /* INT#0: LAN controller on M32700UT-LAN (SMC91C111)*/ |
262 | set_irq_chip_and_handler(M32700UT_LAN_IRQ_LAN, | 262 | irq_set_chip_and_handler(M32700UT_LAN_IRQ_LAN, |
263 | &m32700ut_lanpld_irq_type, handle_level_irq); | 263 | &m32700ut_lanpld_irq_type, handle_level_irq); |
264 | lanpld_icu_data[irq2lanpldirq(M32700UT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ | 264 | lanpld_icu_data[irq2lanpldirq(M32700UT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ |
265 | disable_m32700ut_lanpld_irq(M32700UT_LAN_IRQ_LAN); | 265 | disable_m32700ut_lanpld_irq(M32700UT_LAN_IRQ_LAN); |
266 | #endif /* CONFIG_SMC91X */ | 266 | #endif /* CONFIG_SMC91X */ |
267 | 267 | ||
268 | /* MFT2 : system timer */ | 268 | /* MFT2 : system timer */ |
269 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &m32700ut_irq_type, | 269 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &m32700ut_irq_type, |
270 | handle_level_irq); | 270 | handle_level_irq); |
271 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 271 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
272 | disable_m32700ut_irq(M32R_IRQ_MFT2); | 272 | disable_m32700ut_irq(M32R_IRQ_MFT2); |
273 | 273 | ||
274 | /* SIO0 : receive */ | 274 | /* SIO0 : receive */ |
275 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &m32700ut_irq_type, | 275 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &m32700ut_irq_type, |
276 | handle_level_irq); | 276 | handle_level_irq); |
277 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 277 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
278 | disable_m32700ut_irq(M32R_IRQ_SIO0_R); | 278 | disable_m32700ut_irq(M32R_IRQ_SIO0_R); |
279 | 279 | ||
280 | /* SIO0 : send */ | 280 | /* SIO0 : send */ |
281 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &m32700ut_irq_type, | 281 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &m32700ut_irq_type, |
282 | handle_level_irq); | 282 | handle_level_irq); |
283 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 283 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
284 | disable_m32700ut_irq(M32R_IRQ_SIO0_S); | 284 | disable_m32700ut_irq(M32R_IRQ_SIO0_S); |
285 | 285 | ||
286 | /* SIO1 : receive */ | 286 | /* SIO1 : receive */ |
287 | set_irq_chip_and_handler(M32R_IRQ_SIO1_R, &m32700ut_irq_type, | 287 | irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &m32700ut_irq_type, |
288 | handle_level_irq); | 288 | handle_level_irq); |
289 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 289 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
290 | disable_m32700ut_irq(M32R_IRQ_SIO1_R); | 290 | disable_m32700ut_irq(M32R_IRQ_SIO1_R); |
291 | 291 | ||
292 | /* SIO1 : send */ | 292 | /* SIO1 : send */ |
293 | set_irq_chip_and_handler(M32R_IRQ_SIO1_S, &m32700ut_irq_type, | 293 | irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &m32700ut_irq_type, |
294 | handle_level_irq); | 294 | handle_level_irq); |
295 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 295 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
296 | disable_m32700ut_irq(M32R_IRQ_SIO1_S); | 296 | disable_m32700ut_irq(M32R_IRQ_SIO1_S); |
297 | 297 | ||
298 | /* DMA1 : */ | 298 | /* DMA1 : */ |
299 | set_irq_chip_and_handler(M32R_IRQ_DMA1, &m32700ut_irq_type, | 299 | irq_set_chip_and_handler(M32R_IRQ_DMA1, &m32700ut_irq_type, |
300 | handle_level_irq); | 300 | handle_level_irq); |
301 | icu_data[M32R_IRQ_DMA1].icucr = 0; | 301 | icu_data[M32R_IRQ_DMA1].icucr = 0; |
302 | disable_m32700ut_irq(M32R_IRQ_DMA1); | 302 | disable_m32700ut_irq(M32R_IRQ_DMA1); |
303 | 303 | ||
304 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 304 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
305 | /* INT#1: SIO0 Receive on PLD */ | 305 | /* INT#1: SIO0 Receive on PLD */ |
306 | set_irq_chip_and_handler(PLD_IRQ_SIO0_RCV, &m32700ut_pld_irq_type, | 306 | irq_set_chip_and_handler(PLD_IRQ_SIO0_RCV, &m32700ut_pld_irq_type, |
307 | handle_level_irq); | 307 | handle_level_irq); |
308 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 308 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
309 | disable_m32700ut_pld_irq(PLD_IRQ_SIO0_RCV); | 309 | disable_m32700ut_pld_irq(PLD_IRQ_SIO0_RCV); |
310 | 310 | ||
311 | /* INT#1: SIO0 Send on PLD */ | 311 | /* INT#1: SIO0 Send on PLD */ |
312 | set_irq_chip_and_handler(PLD_IRQ_SIO0_SND, &m32700ut_pld_irq_type, | 312 | irq_set_chip_and_handler(PLD_IRQ_SIO0_SND, &m32700ut_pld_irq_type, |
313 | handle_level_irq); | 313 | handle_level_irq); |
314 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 314 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
315 | disable_m32700ut_pld_irq(PLD_IRQ_SIO0_SND); | 315 | disable_m32700ut_pld_irq(PLD_IRQ_SIO0_SND); |
316 | #endif /* CONFIG_SERIAL_M32R_PLDSIO */ | 316 | #endif /* CONFIG_SERIAL_M32R_PLDSIO */ |
317 | 317 | ||
318 | /* INT#1: CFC IREQ on PLD */ | 318 | /* INT#1: CFC IREQ on PLD */ |
319 | set_irq_chip_and_handler(PLD_IRQ_CFIREQ, &m32700ut_pld_irq_type, | 319 | irq_set_chip_and_handler(PLD_IRQ_CFIREQ, &m32700ut_pld_irq_type, |
320 | handle_level_irq); | 320 | handle_level_irq); |
321 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ | 321 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ |
322 | disable_m32700ut_pld_irq(PLD_IRQ_CFIREQ); | 322 | disable_m32700ut_pld_irq(PLD_IRQ_CFIREQ); |
323 | 323 | ||
324 | /* INT#1: CFC Insert on PLD */ | 324 | /* INT#1: CFC Insert on PLD */ |
325 | set_irq_chip_and_handler(PLD_IRQ_CFC_INSERT, &m32700ut_pld_irq_type, | 325 | irq_set_chip_and_handler(PLD_IRQ_CFC_INSERT, &m32700ut_pld_irq_type, |
326 | handle_level_irq); | 326 | handle_level_irq); |
327 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ | 327 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ |
328 | disable_m32700ut_pld_irq(PLD_IRQ_CFC_INSERT); | 328 | disable_m32700ut_pld_irq(PLD_IRQ_CFC_INSERT); |
329 | 329 | ||
330 | /* INT#1: CFC Eject on PLD */ | 330 | /* INT#1: CFC Eject on PLD */ |
331 | set_irq_chip_and_handler(PLD_IRQ_CFC_EJECT, &m32700ut_pld_irq_type, | 331 | irq_set_chip_and_handler(PLD_IRQ_CFC_EJECT, &m32700ut_pld_irq_type, |
332 | handle_level_irq); | 332 | handle_level_irq); |
333 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ | 333 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ |
334 | disable_m32700ut_pld_irq(PLD_IRQ_CFC_EJECT); | 334 | disable_m32700ut_pld_irq(PLD_IRQ_CFC_EJECT); |
@@ -349,7 +349,7 @@ void __init init_IRQ(void) | |||
349 | 349 | ||
350 | #if defined(CONFIG_USB) | 350 | #if defined(CONFIG_USB) |
351 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ | 351 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ |
352 | set_irq_chip_and_handler(M32700UT_LCD_IRQ_USB_INT1, | 352 | irq_set_chip_and_handler(M32700UT_LCD_IRQ_USB_INT1, |
353 | &m32700ut_lcdpld_irq_type, handle_level_irq); | 353 | &m32700ut_lcdpld_irq_type, handle_level_irq); |
354 | 354 | ||
355 | lcdpld_icu_data[irq2lcdpldirq(M32700UT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ | 355 | lcdpld_icu_data[irq2lcdpldirq(M32700UT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ |
@@ -366,7 +366,7 @@ void __init init_IRQ(void) | |||
366 | /* | 366 | /* |
367 | * INT3# is used for AR | 367 | * INT3# is used for AR |
368 | */ | 368 | */ |
369 | set_irq_chip_and_handler(M32R_IRQ_INT3, &m32700ut_irq_type, | 369 | irq_set_chip_and_handler(M32R_IRQ_INT3, &m32700ut_irq_type, |
370 | handle_level_irq); | 370 | handle_level_irq); |
371 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 371 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
372 | disable_m32700ut_irq(M32R_IRQ_INT3); | 372 | disable_m32700ut_irq(M32R_IRQ_INT3); |
diff --git a/arch/m32r/platforms/mappi/setup.c b/arch/m32r/platforms/mappi/setup.c index cdd8c4574027..35130ac3f8d1 100644 --- a/arch/m32r/platforms/mappi/setup.c +++ b/arch/m32r/platforms/mappi/setup.c | |||
@@ -75,39 +75,39 @@ void __init init_IRQ(void) | |||
75 | 75 | ||
76 | #ifdef CONFIG_NE2000 | 76 | #ifdef CONFIG_NE2000 |
77 | /* INT0 : LAN controller (RTL8019AS) */ | 77 | /* INT0 : LAN controller (RTL8019AS) */ |
78 | set_irq_chip_and_handler(M32R_IRQ_INT0, &mappi_irq_type, | 78 | irq_set_chip_and_handler(M32R_IRQ_INT0, &mappi_irq_type, |
79 | handle_level_irq); | 79 | handle_level_irq); |
80 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11; | 80 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD11; |
81 | disable_mappi_irq(M32R_IRQ_INT0); | 81 | disable_mappi_irq(M32R_IRQ_INT0); |
82 | #endif /* CONFIG_M32R_NE2000 */ | 82 | #endif /* CONFIG_M32R_NE2000 */ |
83 | 83 | ||
84 | /* MFT2 : system timer */ | 84 | /* MFT2 : system timer */ |
85 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &mappi_irq_type, | 85 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &mappi_irq_type, |
86 | handle_level_irq); | 86 | handle_level_irq); |
87 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 87 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
88 | disable_mappi_irq(M32R_IRQ_MFT2); | 88 | disable_mappi_irq(M32R_IRQ_MFT2); |
89 | 89 | ||
90 | #ifdef CONFIG_SERIAL_M32R_SIO | 90 | #ifdef CONFIG_SERIAL_M32R_SIO |
91 | /* SIO0_R : uart receive data */ | 91 | /* SIO0_R : uart receive data */ |
92 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &mappi_irq_type, | 92 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &mappi_irq_type, |
93 | handle_level_irq); | 93 | handle_level_irq); |
94 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 94 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
95 | disable_mappi_irq(M32R_IRQ_SIO0_R); | 95 | disable_mappi_irq(M32R_IRQ_SIO0_R); |
96 | 96 | ||
97 | /* SIO0_S : uart send data */ | 97 | /* SIO0_S : uart send data */ |
98 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &mappi_irq_type, | 98 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &mappi_irq_type, |
99 | handle_level_irq); | 99 | handle_level_irq); |
100 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 100 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
101 | disable_mappi_irq(M32R_IRQ_SIO0_S); | 101 | disable_mappi_irq(M32R_IRQ_SIO0_S); |
102 | 102 | ||
103 | /* SIO1_R : uart receive data */ | 103 | /* SIO1_R : uart receive data */ |
104 | set_irq_chip_and_handler(M32R_IRQ_SIO1_R, &mappi_irq_type, | 104 | irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &mappi_irq_type, |
105 | handle_level_irq); | 105 | handle_level_irq); |
106 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 106 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
107 | disable_mappi_irq(M32R_IRQ_SIO1_R); | 107 | disable_mappi_irq(M32R_IRQ_SIO1_R); |
108 | 108 | ||
109 | /* SIO1_S : uart send data */ | 109 | /* SIO1_S : uart send data */ |
110 | set_irq_chip_and_handler(M32R_IRQ_SIO1_S, &mappi_irq_type, | 110 | irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &mappi_irq_type, |
111 | handle_level_irq); | 111 | handle_level_irq); |
112 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 112 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
113 | disable_mappi_irq(M32R_IRQ_SIO1_S); | 113 | disable_mappi_irq(M32R_IRQ_SIO1_S); |
@@ -115,13 +115,13 @@ void __init init_IRQ(void) | |||
115 | 115 | ||
116 | #if defined(CONFIG_M32R_PCC) | 116 | #if defined(CONFIG_M32R_PCC) |
117 | /* INT1 : pccard0 interrupt */ | 117 | /* INT1 : pccard0 interrupt */ |
118 | set_irq_chip_and_handler(M32R_IRQ_INT1, &mappi_irq_type, | 118 | irq_set_chip_and_handler(M32R_IRQ_INT1, &mappi_irq_type, |
119 | handle_level_irq); | 119 | handle_level_irq); |
120 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; | 120 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; |
121 | disable_mappi_irq(M32R_IRQ_INT1); | 121 | disable_mappi_irq(M32R_IRQ_INT1); |
122 | 122 | ||
123 | /* INT2 : pccard1 interrupt */ | 123 | /* INT2 : pccard1 interrupt */ |
124 | set_irq_chip_and_handler(M32R_IRQ_INT2, &mappi_irq_type, | 124 | irq_set_chip_and_handler(M32R_IRQ_INT2, &mappi_irq_type, |
125 | handle_level_irq); | 125 | handle_level_irq); |
126 | icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; | 126 | icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; |
127 | disable_mappi_irq(M32R_IRQ_INT2); | 127 | disable_mappi_irq(M32R_IRQ_INT2); |
diff --git a/arch/m32r/platforms/mappi2/setup.c b/arch/m32r/platforms/mappi2/setup.c index 9117c30ea365..f3ed6b60a5f8 100644 --- a/arch/m32r/platforms/mappi2/setup.c +++ b/arch/m32r/platforms/mappi2/setup.c | |||
@@ -76,38 +76,38 @@ void __init init_IRQ(void) | |||
76 | { | 76 | { |
77 | #if defined(CONFIG_SMC91X) | 77 | #if defined(CONFIG_SMC91X) |
78 | /* INT0 : LAN controller (SMC91111) */ | 78 | /* INT0 : LAN controller (SMC91111) */ |
79 | set_irq_chip_and_handler(M32R_IRQ_INT0, &mappi2_irq_type, | 79 | irq_set_chip_and_handler(M32R_IRQ_INT0, &mappi2_irq_type, |
80 | handle_level_irq); | 80 | handle_level_irq); |
81 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 81 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
82 | disable_mappi2_irq(M32R_IRQ_INT0); | 82 | disable_mappi2_irq(M32R_IRQ_INT0); |
83 | #endif /* CONFIG_SMC91X */ | 83 | #endif /* CONFIG_SMC91X */ |
84 | 84 | ||
85 | /* MFT2 : system timer */ | 85 | /* MFT2 : system timer */ |
86 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &mappi2_irq_type, | 86 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &mappi2_irq_type, |
87 | handle_level_irq); | 87 | handle_level_irq); |
88 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 88 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
89 | disable_mappi2_irq(M32R_IRQ_MFT2); | 89 | disable_mappi2_irq(M32R_IRQ_MFT2); |
90 | 90 | ||
91 | #ifdef CONFIG_SERIAL_M32R_SIO | 91 | #ifdef CONFIG_SERIAL_M32R_SIO |
92 | /* SIO0_R : uart receive data */ | 92 | /* SIO0_R : uart receive data */ |
93 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &mappi2_irq_type, | 93 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &mappi2_irq_type, |
94 | handle_level_irq); | 94 | handle_level_irq); |
95 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 95 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
96 | disable_mappi2_irq(M32R_IRQ_SIO0_R); | 96 | disable_mappi2_irq(M32R_IRQ_SIO0_R); |
97 | 97 | ||
98 | /* SIO0_S : uart send data */ | 98 | /* SIO0_S : uart send data */ |
99 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &mappi2_irq_type, | 99 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &mappi2_irq_type, |
100 | handle_level_irq); | 100 | handle_level_irq); |
101 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 101 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
102 | disable_mappi2_irq(M32R_IRQ_SIO0_S); | 102 | disable_mappi2_irq(M32R_IRQ_SIO0_S); |
103 | /* SIO1_R : uart receive data */ | 103 | /* SIO1_R : uart receive data */ |
104 | set_irq_chip_and_handler(M32R_IRQ_SIO1_R, &mappi2_irq_type, | 104 | irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &mappi2_irq_type, |
105 | handle_level_irq); | 105 | handle_level_irq); |
106 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 106 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
107 | disable_mappi2_irq(M32R_IRQ_SIO1_R); | 107 | disable_mappi2_irq(M32R_IRQ_SIO1_R); |
108 | 108 | ||
109 | /* SIO1_S : uart send data */ | 109 | /* SIO1_S : uart send data */ |
110 | set_irq_chip_and_handler(M32R_IRQ_SIO1_S, &mappi2_irq_type, | 110 | irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &mappi2_irq_type, |
111 | handle_level_irq); | 111 | handle_level_irq); |
112 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 112 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
113 | disable_mappi2_irq(M32R_IRQ_SIO1_S); | 113 | disable_mappi2_irq(M32R_IRQ_SIO1_S); |
@@ -115,27 +115,27 @@ void __init init_IRQ(void) | |||
115 | 115 | ||
116 | #if defined(CONFIG_USB) | 116 | #if defined(CONFIG_USB) |
117 | /* INT1 : USB Host controller interrupt */ | 117 | /* INT1 : USB Host controller interrupt */ |
118 | set_irq_chip_and_handler(M32R_IRQ_INT1, &mappi2_irq_type, | 118 | irq_set_chip_and_handler(M32R_IRQ_INT1, &mappi2_irq_type, |
119 | handle_level_irq); | 119 | handle_level_irq); |
120 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; | 120 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; |
121 | disable_mappi2_irq(M32R_IRQ_INT1); | 121 | disable_mappi2_irq(M32R_IRQ_INT1); |
122 | #endif /* CONFIG_USB */ | 122 | #endif /* CONFIG_USB */ |
123 | 123 | ||
124 | /* ICUCR40: CFC IREQ */ | 124 | /* ICUCR40: CFC IREQ */ |
125 | set_irq_chip_and_handler(PLD_IRQ_CFIREQ, &mappi2_irq_type, | 125 | irq_set_chip_and_handler(PLD_IRQ_CFIREQ, &mappi2_irq_type, |
126 | handle_level_irq); | 126 | handle_level_irq); |
127 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; | 127 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; |
128 | disable_mappi2_irq(PLD_IRQ_CFIREQ); | 128 | disable_mappi2_irq(PLD_IRQ_CFIREQ); |
129 | 129 | ||
130 | #if defined(CONFIG_M32R_CFC) | 130 | #if defined(CONFIG_M32R_CFC) |
131 | /* ICUCR41: CFC Insert */ | 131 | /* ICUCR41: CFC Insert */ |
132 | set_irq_chip_and_handler(PLD_IRQ_CFC_INSERT, &mappi2_irq_type, | 132 | irq_set_chip_and_handler(PLD_IRQ_CFC_INSERT, &mappi2_irq_type, |
133 | handle_level_irq); | 133 | handle_level_irq); |
134 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; | 134 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; |
135 | disable_mappi2_irq(PLD_IRQ_CFC_INSERT); | 135 | disable_mappi2_irq(PLD_IRQ_CFC_INSERT); |
136 | 136 | ||
137 | /* ICUCR42: CFC Eject */ | 137 | /* ICUCR42: CFC Eject */ |
138 | set_irq_chip_and_handler(PLD_IRQ_CFC_EJECT, &mappi2_irq_type, | 138 | irq_set_chip_and_handler(PLD_IRQ_CFC_EJECT, &mappi2_irq_type, |
139 | handle_level_irq); | 139 | handle_level_irq); |
140 | icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 140 | icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
141 | disable_mappi2_irq(PLD_IRQ_CFC_EJECT); | 141 | disable_mappi2_irq(PLD_IRQ_CFC_EJECT); |
diff --git a/arch/m32r/platforms/mappi3/setup.c b/arch/m32r/platforms/mappi3/setup.c index b44f5ded2bbe..2408e356ad10 100644 --- a/arch/m32r/platforms/mappi3/setup.c +++ b/arch/m32r/platforms/mappi3/setup.c | |||
@@ -75,38 +75,38 @@ void __init init_IRQ(void) | |||
75 | { | 75 | { |
76 | #if defined(CONFIG_SMC91X) | 76 | #if defined(CONFIG_SMC91X) |
77 | /* INT0 : LAN controller (SMC91111) */ | 77 | /* INT0 : LAN controller (SMC91111) */ |
78 | set_irq_chip_and_handler(M32R_IRQ_INT0, &mappi3_irq_type, | 78 | irq_set_chip_and_handler(M32R_IRQ_INT0, &mappi3_irq_type, |
79 | handle_level_irq); | 79 | handle_level_irq); |
80 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 80 | icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
81 | disable_mappi3_irq(M32R_IRQ_INT0); | 81 | disable_mappi3_irq(M32R_IRQ_INT0); |
82 | #endif /* CONFIG_SMC91X */ | 82 | #endif /* CONFIG_SMC91X */ |
83 | 83 | ||
84 | /* MFT2 : system timer */ | 84 | /* MFT2 : system timer */ |
85 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &mappi3_irq_type, | 85 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &mappi3_irq_type, |
86 | handle_level_irq); | 86 | handle_level_irq); |
87 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 87 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
88 | disable_mappi3_irq(M32R_IRQ_MFT2); | 88 | disable_mappi3_irq(M32R_IRQ_MFT2); |
89 | 89 | ||
90 | #ifdef CONFIG_SERIAL_M32R_SIO | 90 | #ifdef CONFIG_SERIAL_M32R_SIO |
91 | /* SIO0_R : uart receive data */ | 91 | /* SIO0_R : uart receive data */ |
92 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &mappi3_irq_type, | 92 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &mappi3_irq_type, |
93 | handle_level_irq); | 93 | handle_level_irq); |
94 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 94 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
95 | disable_mappi3_irq(M32R_IRQ_SIO0_R); | 95 | disable_mappi3_irq(M32R_IRQ_SIO0_R); |
96 | 96 | ||
97 | /* SIO0_S : uart send data */ | 97 | /* SIO0_S : uart send data */ |
98 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &mappi3_irq_type, | 98 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &mappi3_irq_type, |
99 | handle_level_irq); | 99 | handle_level_irq); |
100 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 100 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
101 | disable_mappi3_irq(M32R_IRQ_SIO0_S); | 101 | disable_mappi3_irq(M32R_IRQ_SIO0_S); |
102 | /* SIO1_R : uart receive data */ | 102 | /* SIO1_R : uart receive data */ |
103 | set_irq_chip_and_handler(M32R_IRQ_SIO1_R, &mappi3_irq_type, | 103 | irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &mappi3_irq_type, |
104 | handle_level_irq); | 104 | handle_level_irq); |
105 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 105 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
106 | disable_mappi3_irq(M32R_IRQ_SIO1_R); | 106 | disable_mappi3_irq(M32R_IRQ_SIO1_R); |
107 | 107 | ||
108 | /* SIO1_S : uart send data */ | 108 | /* SIO1_S : uart send data */ |
109 | set_irq_chip_and_handler(M32R_IRQ_SIO1_S, &mappi3_irq_type, | 109 | irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &mappi3_irq_type, |
110 | handle_level_irq); | 110 | handle_level_irq); |
111 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 111 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
112 | disable_mappi3_irq(M32R_IRQ_SIO1_S); | 112 | disable_mappi3_irq(M32R_IRQ_SIO1_S); |
@@ -114,21 +114,21 @@ void __init init_IRQ(void) | |||
114 | 114 | ||
115 | #if defined(CONFIG_USB) | 115 | #if defined(CONFIG_USB) |
116 | /* INT1 : USB Host controller interrupt */ | 116 | /* INT1 : USB Host controller interrupt */ |
117 | set_irq_chip_and_handler(M32R_IRQ_INT1, &mappi3_irq_type, | 117 | irq_set_chip_and_handler(M32R_IRQ_INT1, &mappi3_irq_type, |
118 | handle_level_irq); | 118 | handle_level_irq); |
119 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; | 119 | icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; |
120 | disable_mappi3_irq(M32R_IRQ_INT1); | 120 | disable_mappi3_irq(M32R_IRQ_INT1); |
121 | #endif /* CONFIG_USB */ | 121 | #endif /* CONFIG_USB */ |
122 | 122 | ||
123 | /* CFC IREQ */ | 123 | /* CFC IREQ */ |
124 | set_irq_chip_and_handler(PLD_IRQ_CFIREQ, &mappi3_irq_type, | 124 | irq_set_chip_and_handler(PLD_IRQ_CFIREQ, &mappi3_irq_type, |
125 | handle_level_irq); | 125 | handle_level_irq); |
126 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; | 126 | icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; |
127 | disable_mappi3_irq(PLD_IRQ_CFIREQ); | 127 | disable_mappi3_irq(PLD_IRQ_CFIREQ); |
128 | 128 | ||
129 | #if defined(CONFIG_M32R_CFC) | 129 | #if defined(CONFIG_M32R_CFC) |
130 | /* ICUCR41: CFC Insert & eject */ | 130 | /* ICUCR41: CFC Insert & eject */ |
131 | set_irq_chip_and_handler(PLD_IRQ_CFC_INSERT, &mappi3_irq_type, | 131 | irq_set_chip_and_handler(PLD_IRQ_CFC_INSERT, &mappi3_irq_type, |
132 | handle_level_irq); | 132 | handle_level_irq); |
133 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; | 133 | icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; |
134 | disable_mappi3_irq(PLD_IRQ_CFC_INSERT); | 134 | disable_mappi3_irq(PLD_IRQ_CFC_INSERT); |
@@ -136,7 +136,7 @@ void __init init_IRQ(void) | |||
136 | #endif /* CONFIG_M32R_CFC */ | 136 | #endif /* CONFIG_M32R_CFC */ |
137 | 137 | ||
138 | /* IDE IREQ */ | 138 | /* IDE IREQ */ |
139 | set_irq_chip_and_handler(PLD_IRQ_IDEIREQ, &mappi3_irq_type, | 139 | irq_set_chip_and_handler(PLD_IRQ_IDEIREQ, &mappi3_irq_type, |
140 | handle_level_irq); | 140 | handle_level_irq); |
141 | icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 141 | icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
142 | disable_mappi3_irq(PLD_IRQ_IDEIREQ); | 142 | disable_mappi3_irq(PLD_IRQ_IDEIREQ); |
diff --git a/arch/m32r/platforms/oaks32r/setup.c b/arch/m32r/platforms/oaks32r/setup.c index 19a02db7b818..83b46b067a17 100644 --- a/arch/m32r/platforms/oaks32r/setup.c +++ b/arch/m32r/platforms/oaks32r/setup.c | |||
@@ -74,39 +74,39 @@ void __init init_IRQ(void) | |||
74 | 74 | ||
75 | #ifdef CONFIG_NE2000 | 75 | #ifdef CONFIG_NE2000 |
76 | /* INT3 : LAN controller (RTL8019AS) */ | 76 | /* INT3 : LAN controller (RTL8019AS) */ |
77 | set_irq_chip_and_handler(M32R_IRQ_INT3, &oaks32r_irq_type, | 77 | irq_set_chip_and_handler(M32R_IRQ_INT3, &oaks32r_irq_type, |
78 | handle_level_irq); | 78 | handle_level_irq); |
79 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 79 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
80 | disable_oaks32r_irq(M32R_IRQ_INT3); | 80 | disable_oaks32r_irq(M32R_IRQ_INT3); |
81 | #endif /* CONFIG_M32R_NE2000 */ | 81 | #endif /* CONFIG_M32R_NE2000 */ |
82 | 82 | ||
83 | /* MFT2 : system timer */ | 83 | /* MFT2 : system timer */ |
84 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &oaks32r_irq_type, | 84 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &oaks32r_irq_type, |
85 | handle_level_irq); | 85 | handle_level_irq); |
86 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 86 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
87 | disable_oaks32r_irq(M32R_IRQ_MFT2); | 87 | disable_oaks32r_irq(M32R_IRQ_MFT2); |
88 | 88 | ||
89 | #ifdef CONFIG_SERIAL_M32R_SIO | 89 | #ifdef CONFIG_SERIAL_M32R_SIO |
90 | /* SIO0_R : uart receive data */ | 90 | /* SIO0_R : uart receive data */ |
91 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &oaks32r_irq_type, | 91 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &oaks32r_irq_type, |
92 | handle_level_irq); | 92 | handle_level_irq); |
93 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 93 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
94 | disable_oaks32r_irq(M32R_IRQ_SIO0_R); | 94 | disable_oaks32r_irq(M32R_IRQ_SIO0_R); |
95 | 95 | ||
96 | /* SIO0_S : uart send data */ | 96 | /* SIO0_S : uart send data */ |
97 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &oaks32r_irq_type, | 97 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &oaks32r_irq_type, |
98 | handle_level_irq); | 98 | handle_level_irq); |
99 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 99 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
100 | disable_oaks32r_irq(M32R_IRQ_SIO0_S); | 100 | disable_oaks32r_irq(M32R_IRQ_SIO0_S); |
101 | 101 | ||
102 | /* SIO1_R : uart receive data */ | 102 | /* SIO1_R : uart receive data */ |
103 | set_irq_chip_and_handler(M32R_IRQ_SIO1_R, &oaks32r_irq_type, | 103 | irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &oaks32r_irq_type, |
104 | handle_level_irq); | 104 | handle_level_irq); |
105 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 105 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
106 | disable_oaks32r_irq(M32R_IRQ_SIO1_R); | 106 | disable_oaks32r_irq(M32R_IRQ_SIO1_R); |
107 | 107 | ||
108 | /* SIO1_S : uart send data */ | 108 | /* SIO1_S : uart send data */ |
109 | set_irq_chip_and_handler(M32R_IRQ_SIO1_S, &oaks32r_irq_type, | 109 | irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &oaks32r_irq_type, |
110 | handle_level_irq); | 110 | handle_level_irq); |
111 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 111 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
112 | disable_oaks32r_irq(M32R_IRQ_SIO1_S); | 112 | disable_oaks32r_irq(M32R_IRQ_SIO1_S); |
diff --git a/arch/m32r/platforms/opsput/setup.c b/arch/m32r/platforms/opsput/setup.c index 12731547e8bf..32660705f5fd 100644 --- a/arch/m32r/platforms/opsput/setup.c +++ b/arch/m32r/platforms/opsput/setup.c | |||
@@ -259,76 +259,76 @@ void __init init_IRQ(void) | |||
259 | { | 259 | { |
260 | #if defined(CONFIG_SMC91X) | 260 | #if defined(CONFIG_SMC91X) |
261 | /* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/ | 261 | /* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/ |
262 | set_irq_chip_and_handler(OPSPUT_LAN_IRQ_LAN, &opsput_lanpld_irq_type, | 262 | irq_set_chip_and_handler(OPSPUT_LAN_IRQ_LAN, &opsput_lanpld_irq_type, |
263 | handle_level_irq); | 263 | handle_level_irq); |
264 | lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ | 264 | lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ |
265 | disable_opsput_lanpld_irq(OPSPUT_LAN_IRQ_LAN); | 265 | disable_opsput_lanpld_irq(OPSPUT_LAN_IRQ_LAN); |
266 | #endif /* CONFIG_SMC91X */ | 266 | #endif /* CONFIG_SMC91X */ |
267 | 267 | ||
268 | /* MFT2 : system timer */ | 268 | /* MFT2 : system timer */ |
269 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &opsput_irq_type, | 269 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &opsput_irq_type, |
270 | handle_level_irq); | 270 | handle_level_irq); |
271 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 271 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
272 | disable_opsput_irq(M32R_IRQ_MFT2); | 272 | disable_opsput_irq(M32R_IRQ_MFT2); |
273 | 273 | ||
274 | /* SIO0 : receive */ | 274 | /* SIO0 : receive */ |
275 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &opsput_irq_type, | 275 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &opsput_irq_type, |
276 | handle_level_irq); | 276 | handle_level_irq); |
277 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 277 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
278 | disable_opsput_irq(M32R_IRQ_SIO0_R); | 278 | disable_opsput_irq(M32R_IRQ_SIO0_R); |
279 | 279 | ||
280 | /* SIO0 : send */ | 280 | /* SIO0 : send */ |
281 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &opsput_irq_type, | 281 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &opsput_irq_type, |
282 | handle_level_irq); | 282 | handle_level_irq); |
283 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 283 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
284 | disable_opsput_irq(M32R_IRQ_SIO0_S); | 284 | disable_opsput_irq(M32R_IRQ_SIO0_S); |
285 | 285 | ||
286 | /* SIO1 : receive */ | 286 | /* SIO1 : receive */ |
287 | set_irq_chip_and_handler(M32R_IRQ_SIO1_R, &opsput_irq_type, | 287 | irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &opsput_irq_type, |
288 | handle_level_irq); | 288 | handle_level_irq); |
289 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 289 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
290 | disable_opsput_irq(M32R_IRQ_SIO1_R); | 290 | disable_opsput_irq(M32R_IRQ_SIO1_R); |
291 | 291 | ||
292 | /* SIO1 : send */ | 292 | /* SIO1 : send */ |
293 | set_irq_chip_and_handler(M32R_IRQ_SIO1_S, &opsput_irq_type, | 293 | irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &opsput_irq_type, |
294 | handle_level_irq); | 294 | handle_level_irq); |
295 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 295 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
296 | disable_opsput_irq(M32R_IRQ_SIO1_S); | 296 | disable_opsput_irq(M32R_IRQ_SIO1_S); |
297 | 297 | ||
298 | /* DMA1 : */ | 298 | /* DMA1 : */ |
299 | set_irq_chip_and_handler(M32R_IRQ_DMA1, &opsput_irq_type, | 299 | irq_set_chip_and_handler(M32R_IRQ_DMA1, &opsput_irq_type, |
300 | handle_level_irq); | 300 | handle_level_irq); |
301 | icu_data[M32R_IRQ_DMA1].icucr = 0; | 301 | icu_data[M32R_IRQ_DMA1].icucr = 0; |
302 | disable_opsput_irq(M32R_IRQ_DMA1); | 302 | disable_opsput_irq(M32R_IRQ_DMA1); |
303 | 303 | ||
304 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 304 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
305 | /* INT#1: SIO0 Receive on PLD */ | 305 | /* INT#1: SIO0 Receive on PLD */ |
306 | set_irq_chip_and_handler(PLD_IRQ_SIO0_RCV, &opsput_pld_irq_type, | 306 | irq_set_chip_and_handler(PLD_IRQ_SIO0_RCV, &opsput_pld_irq_type, |
307 | handle_level_irq); | 307 | handle_level_irq); |
308 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 308 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
309 | disable_opsput_pld_irq(PLD_IRQ_SIO0_RCV); | 309 | disable_opsput_pld_irq(PLD_IRQ_SIO0_RCV); |
310 | 310 | ||
311 | /* INT#1: SIO0 Send on PLD */ | 311 | /* INT#1: SIO0 Send on PLD */ |
312 | set_irq_chip_and_handler(PLD_IRQ_SIO0_SND, &opsput_pld_irq_type, | 312 | irq_set_chip_and_handler(PLD_IRQ_SIO0_SND, &opsput_pld_irq_type, |
313 | handle_level_irq); | 313 | handle_level_irq); |
314 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; | 314 | pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; |
315 | disable_opsput_pld_irq(PLD_IRQ_SIO0_SND); | 315 | disable_opsput_pld_irq(PLD_IRQ_SIO0_SND); |
316 | #endif /* CONFIG_SERIAL_M32R_PLDSIO */ | 316 | #endif /* CONFIG_SERIAL_M32R_PLDSIO */ |
317 | 317 | ||
318 | /* INT#1: CFC IREQ on PLD */ | 318 | /* INT#1: CFC IREQ on PLD */ |
319 | set_irq_chip_and_handler(PLD_IRQ_CFIREQ, &opsput_pld_irq_type, | 319 | irq_set_chip_and_handler(PLD_IRQ_CFIREQ, &opsput_pld_irq_type, |
320 | handle_level_irq); | 320 | handle_level_irq); |
321 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ | 321 | pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ |
322 | disable_opsput_pld_irq(PLD_IRQ_CFIREQ); | 322 | disable_opsput_pld_irq(PLD_IRQ_CFIREQ); |
323 | 323 | ||
324 | /* INT#1: CFC Insert on PLD */ | 324 | /* INT#1: CFC Insert on PLD */ |
325 | set_irq_chip_and_handler(PLD_IRQ_CFC_INSERT, &opsput_pld_irq_type, | 325 | irq_set_chip_and_handler(PLD_IRQ_CFC_INSERT, &opsput_pld_irq_type, |
326 | handle_level_irq); | 326 | handle_level_irq); |
327 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ | 327 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ |
328 | disable_opsput_pld_irq(PLD_IRQ_CFC_INSERT); | 328 | disable_opsput_pld_irq(PLD_IRQ_CFC_INSERT); |
329 | 329 | ||
330 | /* INT#1: CFC Eject on PLD */ | 330 | /* INT#1: CFC Eject on PLD */ |
331 | set_irq_chip_and_handler(PLD_IRQ_CFC_EJECT, &opsput_pld_irq_type, | 331 | irq_set_chip_and_handler(PLD_IRQ_CFC_EJECT, &opsput_pld_irq_type, |
332 | handle_level_irq); | 332 | handle_level_irq); |
333 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ | 333 | pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ |
334 | disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT); | 334 | disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT); |
@@ -349,7 +349,7 @@ void __init init_IRQ(void) | |||
349 | 349 | ||
350 | #if defined(CONFIG_USB) | 350 | #if defined(CONFIG_USB) |
351 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ | 351 | outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ |
352 | set_irq_chip_and_handler(OPSPUT_LCD_IRQ_USB_INT1, | 352 | irq_set_chip_and_handler(OPSPUT_LCD_IRQ_USB_INT1, |
353 | &opsput_lcdpld_irq_type, handle_level_irq); | 353 | &opsput_lcdpld_irq_type, handle_level_irq); |
354 | lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ | 354 | lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ |
355 | disable_opsput_lcdpld_irq(OPSPUT_LCD_IRQ_USB_INT1); | 355 | disable_opsput_lcdpld_irq(OPSPUT_LCD_IRQ_USB_INT1); |
@@ -365,7 +365,7 @@ void __init init_IRQ(void) | |||
365 | /* | 365 | /* |
366 | * INT3# is used for AR | 366 | * INT3# is used for AR |
367 | */ | 367 | */ |
368 | set_irq_chip_and_handler(M32R_IRQ_INT3, &opsput_irq_type, | 368 | irq_set_chip_and_handler(M32R_IRQ_INT3, &opsput_irq_type, |
369 | handle_level_irq); | 369 | handle_level_irq); |
370 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; | 370 | icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; |
371 | disable_opsput_irq(M32R_IRQ_INT3); | 371 | disable_opsput_irq(M32R_IRQ_INT3); |
diff --git a/arch/m32r/platforms/usrv/setup.c b/arch/m32r/platforms/usrv/setup.c index f3cff26d6e74..0c7a1e8c77b0 100644 --- a/arch/m32r/platforms/usrv/setup.c +++ b/arch/m32r/platforms/usrv/setup.c | |||
@@ -138,32 +138,32 @@ void __init init_IRQ(void) | |||
138 | once++; | 138 | once++; |
139 | 139 | ||
140 | /* MFT2 : system timer */ | 140 | /* MFT2 : system timer */ |
141 | set_irq_chip_and_handler(M32R_IRQ_MFT2, &mappi_irq_type, | 141 | irq_set_chip_and_handler(M32R_IRQ_MFT2, &mappi_irq_type, |
142 | handle_level_irq); | 142 | handle_level_irq); |
143 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; | 143 | icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; |
144 | disable_mappi_irq(M32R_IRQ_MFT2); | 144 | disable_mappi_irq(M32R_IRQ_MFT2); |
145 | 145 | ||
146 | #if defined(CONFIG_SERIAL_M32R_SIO) | 146 | #if defined(CONFIG_SERIAL_M32R_SIO) |
147 | /* SIO0_R : uart receive data */ | 147 | /* SIO0_R : uart receive data */ |
148 | set_irq_chip_and_handler(M32R_IRQ_SIO0_R, &mappi_irq_type, | 148 | irq_set_chip_and_handler(M32R_IRQ_SIO0_R, &mappi_irq_type, |
149 | handle_level_irq); | 149 | handle_level_irq); |
150 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; | 150 | icu_data[M32R_IRQ_SIO0_R].icucr = 0; |
151 | disable_mappi_irq(M32R_IRQ_SIO0_R); | 151 | disable_mappi_irq(M32R_IRQ_SIO0_R); |
152 | 152 | ||
153 | /* SIO0_S : uart send data */ | 153 | /* SIO0_S : uart send data */ |
154 | set_irq_chip_and_handler(M32R_IRQ_SIO0_S, &mappi_irq_type, | 154 | irq_set_chip_and_handler(M32R_IRQ_SIO0_S, &mappi_irq_type, |
155 | handle_level_irq); | 155 | handle_level_irq); |
156 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; | 156 | icu_data[M32R_IRQ_SIO0_S].icucr = 0; |
157 | disable_mappi_irq(M32R_IRQ_SIO0_S); | 157 | disable_mappi_irq(M32R_IRQ_SIO0_S); |
158 | 158 | ||
159 | /* SIO1_R : uart receive data */ | 159 | /* SIO1_R : uart receive data */ |
160 | set_irq_chip_and_handler(M32R_IRQ_SIO1_R, &mappi_irq_type, | 160 | irq_set_chip_and_handler(M32R_IRQ_SIO1_R, &mappi_irq_type, |
161 | handle_level_irq); | 161 | handle_level_irq); |
162 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; | 162 | icu_data[M32R_IRQ_SIO1_R].icucr = 0; |
163 | disable_mappi_irq(M32R_IRQ_SIO1_R); | 163 | disable_mappi_irq(M32R_IRQ_SIO1_R); |
164 | 164 | ||
165 | /* SIO1_S : uart send data */ | 165 | /* SIO1_S : uart send data */ |
166 | set_irq_chip_and_handler(M32R_IRQ_SIO1_S, &mappi_irq_type, | 166 | irq_set_chip_and_handler(M32R_IRQ_SIO1_S, &mappi_irq_type, |
167 | handle_level_irq); | 167 | handle_level_irq); |
168 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; | 168 | icu_data[M32R_IRQ_SIO1_S].icucr = 0; |
169 | disable_mappi_irq(M32R_IRQ_SIO1_S); | 169 | disable_mappi_irq(M32R_IRQ_SIO1_S); |
@@ -171,7 +171,7 @@ void __init init_IRQ(void) | |||
171 | 171 | ||
172 | /* INT#67-#71: CFC#0 IREQ on PLD */ | 172 | /* INT#67-#71: CFC#0 IREQ on PLD */ |
173 | for (i = 0 ; i < CONFIG_M32R_CFC_NUM ; i++ ) { | 173 | for (i = 0 ; i < CONFIG_M32R_CFC_NUM ; i++ ) { |
174 | set_irq_chip_and_handler(PLD_IRQ_CF0 + i, | 174 | irq_set_chip_and_handler(PLD_IRQ_CF0 + i, |
175 | &m32700ut_pld_irq_type, | 175 | &m32700ut_pld_irq_type, |
176 | handle_level_irq); | 176 | handle_level_irq); |
177 | pld_icu_data[irq2pldirq(PLD_IRQ_CF0 + i)].icucr | 177 | pld_icu_data[irq2pldirq(PLD_IRQ_CF0 + i)].icucr |
@@ -181,14 +181,14 @@ void __init init_IRQ(void) | |||
181 | 181 | ||
182 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | 182 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) |
183 | /* INT#76: 16552D#0 IREQ on PLD */ | 183 | /* INT#76: 16552D#0 IREQ on PLD */ |
184 | set_irq_chip_and_handler(PLD_IRQ_UART0, &m32700ut_pld_irq_type, | 184 | irq_set_chip_and_handler(PLD_IRQ_UART0, &m32700ut_pld_irq_type, |
185 | handle_level_irq); | 185 | handle_level_irq); |
186 | pld_icu_data[irq2pldirq(PLD_IRQ_UART0)].icucr | 186 | pld_icu_data[irq2pldirq(PLD_IRQ_UART0)].icucr |
187 | = PLD_ICUCR_ISMOD03; /* 'H' level sense */ | 187 | = PLD_ICUCR_ISMOD03; /* 'H' level sense */ |
188 | disable_m32700ut_pld_irq(PLD_IRQ_UART0); | 188 | disable_m32700ut_pld_irq(PLD_IRQ_UART0); |
189 | 189 | ||
190 | /* INT#77: 16552D#1 IREQ on PLD */ | 190 | /* INT#77: 16552D#1 IREQ on PLD */ |
191 | set_irq_chip_and_handler(PLD_IRQ_UART1, &m32700ut_pld_irq_type, | 191 | irq_set_chip_and_handler(PLD_IRQ_UART1, &m32700ut_pld_irq_type, |
192 | handle_level_irq); | 192 | handle_level_irq); |
193 | pld_icu_data[irq2pldirq(PLD_IRQ_UART1)].icucr | 193 | pld_icu_data[irq2pldirq(PLD_IRQ_UART1)].icucr |
194 | = PLD_ICUCR_ISMOD03; /* 'H' level sense */ | 194 | = PLD_ICUCR_ISMOD03; /* 'H' level sense */ |
@@ -197,7 +197,7 @@ void __init init_IRQ(void) | |||
197 | 197 | ||
198 | #if defined(CONFIG_IDC_AK4524) || defined(CONFIG_IDC_AK4524_MODULE) | 198 | #if defined(CONFIG_IDC_AK4524) || defined(CONFIG_IDC_AK4524_MODULE) |
199 | /* INT#80: AK4524 IREQ on PLD */ | 199 | /* INT#80: AK4524 IREQ on PLD */ |
200 | set_irq_chip_and_handler(PLD_IRQ_SNDINT, &m32700ut_pld_irq_type, | 200 | irq_set_chip_and_handler(PLD_IRQ_SNDINT, &m32700ut_pld_irq_type, |
201 | handle_level_irq); | 201 | handle_level_irq); |
202 | pld_icu_data[irq2pldirq(PLD_IRQ_SNDINT)].icucr | 202 | pld_icu_data[irq2pldirq(PLD_IRQ_SNDINT)].icucr |
203 | = PLD_ICUCR_ISMOD01; /* 'L' level sense */ | 203 | = PLD_ICUCR_ISMOD01; /* 'L' level sense */ |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 525174d41679..6e056d3c5d01 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
@@ -1,13 +1,11 @@ | |||
1 | config M68K | 1 | config M68K |
2 | bool | 2 | bool |
3 | default y | 3 | default y |
4 | select HAVE_AOUT | ||
5 | select HAVE_IDE | 4 | select HAVE_IDE |
6 | select GENERIC_ATOMIC64 | 5 | select HAVE_AOUT if MMU |
7 | 6 | select GENERIC_ATOMIC64 if MMU | |
8 | config MMU | 7 | select HAVE_GENERIC_HARDIRQS if !MMU |
9 | bool | 8 | select GENERIC_HARDIRQS_NO_DEPRECATED if !MMU |
10 | default y | ||
11 | 9 | ||
12 | config RWSEM_GENERIC_SPINLOCK | 10 | config RWSEM_GENERIC_SPINLOCK |
13 | bool | 11 | bool |
@@ -34,457 +32,67 @@ config TIME_LOW_RES | |||
34 | bool | 32 | bool |
35 | default y | 33 | default y |
36 | 34 | ||
37 | config GENERIC_IOMAP | ||
38 | bool | ||
39 | default y | ||
40 | |||
41 | config ARCH_MAY_HAVE_PC_FDC | ||
42 | bool | ||
43 | depends on BROKEN && (Q40 || SUN3X) | ||
44 | default y | ||
45 | |||
46 | config NO_IOPORT | 35 | config NO_IOPORT |
47 | def_bool y | 36 | def_bool y |
48 | 37 | ||
49 | config NO_DMA | 38 | config NO_DMA |
50 | def_bool SUN3 | 39 | def_bool (MMU && SUN3) || (!MMU && !COLDFIRE) |
51 | 40 | ||
41 | config ZONE_DMA | ||
42 | bool | ||
43 | default y | ||
52 | config HZ | 44 | config HZ |
53 | int | 45 | int |
46 | default 1000 if CLEOPATRA | ||
54 | default 100 | 47 | default 100 |
55 | 48 | ||
56 | config ARCH_USES_GETTIMEOFFSET | ||
57 | def_bool y | ||
58 | |||
59 | source "init/Kconfig" | 49 | source "init/Kconfig" |
60 | 50 | ||
61 | source "kernel/Kconfig.freezer" | 51 | source "kernel/Kconfig.freezer" |
62 | 52 | ||
63 | menu "Platform dependent setup" | 53 | config MMU |
64 | 54 | bool "MMU-based Paged Memory Management Support" | |
65 | config EISA | ||
66 | bool | ||
67 | ---help--- | ||
68 | The Extended Industry Standard Architecture (EISA) bus was | ||
69 | developed as an open alternative to the IBM MicroChannel bus. | ||
70 | |||
71 | The EISA bus provided some of the features of the IBM MicroChannel | ||
72 | bus while maintaining backward compatibility with cards made for | ||
73 | the older ISA bus. The EISA bus saw limited use between 1988 and | ||
74 | 1995 when it was made obsolete by the PCI bus. | ||
75 | |||
76 | Say Y here if you are building a kernel for an EISA-based machine. | ||
77 | |||
78 | Otherwise, say N. | ||
79 | |||
80 | config MCA | ||
81 | bool | ||
82 | help | ||
83 | MicroChannel Architecture is found in some IBM PS/2 machines and | ||
84 | laptops. It is a bus system similar to PCI or ISA. See | ||
85 | <file:Documentation/mca.txt> (and especially the web page given | ||
86 | there) before attempting to build an MCA bus kernel. | ||
87 | |||
88 | config PCMCIA | ||
89 | tristate | ||
90 | ---help--- | ||
91 | Say Y here if you want to attach PCMCIA- or PC-cards to your Linux | ||
92 | computer. These are credit-card size devices such as network cards, | ||
93 | modems or hard drives often used with laptops computers. There are | ||
94 | actually two varieties of these cards: the older 16 bit PCMCIA cards | ||
95 | and the newer 32 bit CardBus cards. If you want to use CardBus | ||
96 | cards, you need to say Y here and also to "CardBus support" below. | ||
97 | |||
98 | To use your PC-cards, you will need supporting software from David | ||
99 | Hinds' pcmcia-cs package (see the file <file:Documentation/Changes> | ||
100 | for location). Please also read the PCMCIA-HOWTO, available from | ||
101 | <http://www.tldp.org/docs.html#howto>. | ||
102 | |||
103 | To compile this driver as modules, choose M here: the | ||
104 | modules will be called pcmcia_core and ds. | ||
105 | |||
106 | config AMIGA | ||
107 | bool "Amiga support" | ||
108 | select MMU_MOTOROLA if MMU | ||
109 | help | ||
110 | This option enables support for the Amiga series of computers. If | ||
111 | you plan to use this kernel on an Amiga, say Y here and browse the | ||
112 | material available in <file:Documentation/m68k>; otherwise say N. | ||
113 | |||
114 | config ATARI | ||
115 | bool "Atari support" | ||
116 | select MMU_MOTOROLA if MMU | ||
117 | help | ||
118 | This option enables support for the 68000-based Atari series of | ||
119 | computers (including the TT, Falcon and Medusa). If you plan to use | ||
120 | this kernel on an Atari, say Y here and browse the material | ||
121 | available in <file:Documentation/m68k>; otherwise say N. | ||
122 | |||
123 | config MAC | ||
124 | bool "Macintosh support" | ||
125 | select MMU_MOTOROLA if MMU | ||
126 | help | ||
127 | This option enables support for the Apple Macintosh series of | ||
128 | computers (yes, there is experimental support now, at least for part | ||
129 | of the series). | ||
130 | |||
131 | Say N unless you're willing to code the remaining necessary support. | ||
132 | ;) | ||
133 | |||
134 | config NUBUS | ||
135 | bool | ||
136 | depends on MAC | ||
137 | default y | ||
138 | |||
139 | config M68K_L2_CACHE | ||
140 | bool | ||
141 | depends on MAC | ||
142 | default y | ||
143 | |||
144 | config APOLLO | ||
145 | bool "Apollo support" | ||
146 | select MMU_MOTOROLA if MMU | ||
147 | help | ||
148 | Say Y here if you want to run Linux on an MC680x0-based Apollo | ||
149 | Domain workstation such as the DN3500. | ||
150 | |||
151 | config VME | ||
152 | bool "VME (Motorola and BVM) support" | ||
153 | select MMU_MOTOROLA if MMU | ||
154 | help | ||
155 | Say Y here if you want to build a kernel for a 680x0 based VME | ||
156 | board. Boards currently supported include Motorola boards MVME147, | ||
157 | MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and | ||
158 | BVME6000 boards from BVM Ltd are also supported. | ||
159 | |||
160 | config MVME147 | ||
161 | bool "MVME147 support" | ||
162 | depends on VME | ||
163 | help | ||
164 | Say Y to include support for early Motorola VME boards. This will | ||
165 | build a kernel which can run on MVME147 single-board computers. If | ||
166 | you select this option you will have to select the appropriate | ||
167 | drivers for SCSI, Ethernet and serial ports later on. | ||
168 | |||
169 | config MVME16x | ||
170 | bool "MVME162, 166 and 167 support" | ||
171 | depends on VME | ||
172 | help | ||
173 | Say Y to include support for Motorola VME boards. This will build a | ||
174 | kernel which can run on MVME162, MVME166, MVME167, MVME172, and | ||
175 | MVME177 boards. If you select this option you will have to select | ||
176 | the appropriate drivers for SCSI, Ethernet and serial ports later | ||
177 | on. | ||
178 | |||
179 | config BVME6000 | ||
180 | bool "BVME4000 and BVME6000 support" | ||
181 | depends on VME | ||
182 | help | ||
183 | Say Y to include support for VME boards from BVM Ltd. This will | ||
184 | build a kernel which can run on BVME4000 and BVME6000 boards. If | ||
185 | you select this option you will have to select the appropriate | ||
186 | drivers for SCSI, Ethernet and serial ports later on. | ||
187 | |||
188 | config HP300 | ||
189 | bool "HP9000/300 and HP9000/400 support" | ||
190 | select MMU_MOTOROLA if MMU | ||
191 | help | ||
192 | This option enables support for the HP9000/300 and HP9000/400 series | ||
193 | of workstations. Support for these machines is still somewhat | ||
194 | experimental. If you plan to try to use the kernel on such a machine | ||
195 | say Y here. | ||
196 | Everybody else says N. | ||
197 | |||
198 | config DIO | ||
199 | bool "DIO bus support" | ||
200 | depends on HP300 | ||
201 | default y | 55 | default y |
202 | help | 56 | help |
203 | Say Y here to enable support for the "DIO" expansion bus used in | 57 | Select if you want MMU-based virtualised addressing space |
204 | HP300 machines. If you are using such a system you almost certainly | 58 | support by paged memory management. If unsure, say 'Y'. |
205 | want this. | ||
206 | |||
207 | config SUN3X | ||
208 | bool "Sun3x support" | ||
209 | select MMU_MOTOROLA if MMU | ||
210 | select M68030 | ||
211 | help | ||
212 | This option enables support for the Sun 3x series of workstations. | ||
213 | Be warned that this support is very experimental. | ||
214 | Note that Sun 3x kernels are not compatible with Sun 3 hardware. | ||
215 | General Linux information on the Sun 3x series (now discontinued) | ||
216 | is at <http://www.angelfire.com/ca2/tech68k/sun3.html>. | ||
217 | |||
218 | If you don't want to compile a kernel for a Sun 3x, say N. | ||
219 | |||
220 | config Q40 | ||
221 | bool "Q40/Q60 support" | ||
222 | select MMU_MOTOROLA if MMU | ||
223 | help | ||
224 | The Q40 is a Motorola 68040-based successor to the Sinclair QL | ||
225 | manufactured in Germany. There is an official Q40 home page at | ||
226 | <http://www.q40.de/>. This option enables support for the Q40 and | ||
227 | Q60. Select your CPU below. For 68LC060 don't forget to enable FPU | ||
228 | emulation. | ||
229 | |||
230 | config SUN3 | ||
231 | bool "Sun3 support" | ||
232 | depends on !MMU_MOTOROLA | ||
233 | select MMU_SUN3 if MMU | ||
234 | select M68020 | ||
235 | help | ||
236 | This option enables support for the Sun 3 series of workstations | ||
237 | (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires | ||
238 | that all other hardware types must be disabled, as Sun 3 kernels | ||
239 | are incompatible with all other m68k targets (including Sun 3x!). | ||
240 | |||
241 | If you don't want to compile a kernel exclusively for a Sun 3, say N. | ||
242 | |||
243 | config NATFEAT | ||
244 | bool "ARAnyM emulator support" | ||
245 | depends on ATARI | ||
246 | help | ||
247 | This option enables support for ARAnyM native features, such as | ||
248 | access to a disk image as /dev/hda. | ||
249 | |||
250 | config NFBLOCK | ||
251 | tristate "NatFeat block device support" | ||
252 | depends on BLOCK && NATFEAT | ||
253 | help | ||
254 | Say Y to include support for the ARAnyM NatFeat block device | ||
255 | which allows direct access to the hard drives without using | ||
256 | the hardware emulation. | ||
257 | |||
258 | config NFCON | ||
259 | tristate "NatFeat console driver" | ||
260 | depends on NATFEAT | ||
261 | help | ||
262 | Say Y to include support for the ARAnyM NatFeat console driver | ||
263 | which allows the console output to be redirected to the stderr | ||
264 | output of ARAnyM. | ||
265 | |||
266 | config NFETH | ||
267 | tristate "NatFeat Ethernet support" | ||
268 | depends on NET_ETHERNET && NATFEAT | ||
269 | help | ||
270 | Say Y to include support for the ARAnyM NatFeat network device | ||
271 | which will emulate a regular ethernet device while presenting an | ||
272 | ethertap device to the host system. | ||
273 | |||
274 | comment "Processor type" | ||
275 | |||
276 | config M68020 | ||
277 | bool "68020 support" | ||
278 | help | ||
279 | If you anticipate running this kernel on a computer with a MC68020 | ||
280 | processor, say Y. Otherwise, say N. Note that the 68020 requires a | ||
281 | 68851 MMU (Memory Management Unit) to run Linux/m68k, except on the | ||
282 | Sun 3, which provides its own version. | ||
283 | |||
284 | config M68030 | ||
285 | bool "68030 support" | ||
286 | depends on !MMU_SUN3 | ||
287 | help | ||
288 | If you anticipate running this kernel on a computer with a MC68030 | ||
289 | processor, say Y. Otherwise, say N. Note that a MC68EC030 will not | ||
290 | work, as it does not include an MMU (Memory Management Unit). | ||
291 | |||
292 | config M68040 | ||
293 | bool "68040 support" | ||
294 | depends on !MMU_SUN3 | ||
295 | help | ||
296 | If you anticipate running this kernel on a computer with a MC68LC040 | ||
297 | or MC68040 processor, say Y. Otherwise, say N. Note that an | ||
298 | MC68EC040 will not work, as it does not include an MMU (Memory | ||
299 | Management Unit). | ||
300 | |||
301 | config M68060 | ||
302 | bool "68060 support" | ||
303 | depends on !MMU_SUN3 | ||
304 | help | ||
305 | If you anticipate running this kernel on a computer with a MC68060 | ||
306 | processor, say Y. Otherwise, say N. | ||
307 | |||
308 | config MMU_MOTOROLA | ||
309 | bool | ||
310 | |||
311 | config MMU_SUN3 | ||
312 | bool | ||
313 | depends on MMU && !MMU_MOTOROLA | ||
314 | |||
315 | config M68KFPU_EMU | ||
316 | bool "Math emulation support (EXPERIMENTAL)" | ||
317 | depends on EXPERIMENTAL | ||
318 | help | ||
319 | At some point in the future, this will cause floating-point math | ||
320 | instructions to be emulated by the kernel on machines that lack a | ||
321 | floating-point math coprocessor. Thrill-seekers and chronically | ||
322 | sleep-deprived psychotic hacker types can say Y now, everyone else | ||
323 | should probably wait a while. | ||
324 | |||
325 | config M68KFPU_EMU_EXTRAPREC | ||
326 | bool "Math emulation extra precision" | ||
327 | depends on M68KFPU_EMU | ||
328 | help | ||
329 | The fpu uses normally a few bit more during calculations for | ||
330 | correct rounding, the emulator can (often) do the same but this | ||
331 | extra calculation can cost quite some time, so you can disable | ||
332 | it here. The emulator will then "only" calculate with a 64 bit | ||
333 | mantissa and round slightly incorrect, what is more than enough | ||
334 | for normal usage. | ||
335 | |||
336 | config M68KFPU_EMU_ONLY | ||
337 | bool "Math emulation only kernel" | ||
338 | depends on M68KFPU_EMU | ||
339 | help | ||
340 | This option prevents any floating-point instructions from being | ||
341 | compiled into the kernel, thereby the kernel doesn't save any | ||
342 | floating point context anymore during task switches, so this | ||
343 | kernel will only be usable on machines without a floating-point | ||
344 | math coprocessor. This makes the kernel a bit faster as no tests | ||
345 | needs to be executed whether a floating-point instruction in the | ||
346 | kernel should be executed or not. | ||
347 | |||
348 | config ADVANCED | ||
349 | bool "Advanced configuration options" | ||
350 | ---help--- | ||
351 | This gives you access to some advanced options for the CPU. The | ||
352 | defaults should be fine for most users, but these options may make | ||
353 | it possible for you to improve performance somewhat if you know what | ||
354 | you are doing. | ||
355 | |||
356 | Note that the answer to this question won't directly affect the | ||
357 | kernel: saying N will just cause the configurator to skip all | ||
358 | the questions about these options. | ||
359 | 59 | ||
360 | Most users should say N to this question. | 60 | menu "Platform dependent setup" |
361 | |||
362 | config RMW_INSNS | ||
363 | bool "Use read-modify-write instructions" | ||
364 | depends on ADVANCED | ||
365 | ---help--- | ||
366 | This allows to use certain instructions that work with indivisible | ||
367 | read-modify-write bus cycles. While this is faster than the | ||
368 | workaround of disabling interrupts, it can conflict with DMA | ||
369 | ( = direct memory access) on many Amiga systems, and it is also said | ||
370 | to destabilize other machines. It is very likely that this will | ||
371 | cause serious problems on any Amiga or Atari Medusa if set. The only | ||
372 | configuration where it should work are 68030-based Ataris, where it | ||
373 | apparently improves performance. But you've been warned! Unless you | ||
374 | really know what you are doing, say N. Try Y only if you're quite | ||
375 | adventurous. | ||
376 | |||
377 | config SINGLE_MEMORY_CHUNK | ||
378 | bool "Use one physical chunk of memory only" if ADVANCED && !SUN3 | ||
379 | default y if SUN3 | ||
380 | select NEED_MULTIPLE_NODES | ||
381 | help | ||
382 | Ignore all but the first contiguous chunk of physical memory for VM | ||
383 | purposes. This will save a few bytes kernel size and may speed up | ||
384 | some operations. Say N if not sure. | ||
385 | 61 | ||
386 | config 060_WRITETHROUGH | 62 | if MMU |
387 | bool "Use write-through caching for 68060 supervisor accesses" | 63 | source arch/m68k/Kconfig.mmu |
388 | depends on ADVANCED && M68060 | 64 | endif |
389 | ---help--- | 65 | if !MMU |
390 | The 68060 generally uses copyback caching of recently accessed data. | 66 | source arch/m68k/Kconfig.nommu |
391 | Copyback caching means that memory writes will be held in an on-chip | 67 | endif |
392 | cache and only written back to memory some time later. Saying Y | ||
393 | here will force supervisor (kernel) accesses to use writethrough | ||
394 | caching. Writethrough caching means that data is written to memory | ||
395 | straight away, so that cache and memory data always agree. | ||
396 | Writethrough caching is less efficient, but is needed for some | ||
397 | drivers on 68060 based systems where the 68060 bus snooping signal | ||
398 | is hardwired on. The 53c710 SCSI driver is known to suffer from | ||
399 | this problem. | ||
400 | |||
401 | config ARCH_DISCONTIGMEM_ENABLE | ||
402 | def_bool !SINGLE_MEMORY_CHUNK | ||
403 | |||
404 | config NODES_SHIFT | ||
405 | int | ||
406 | default "3" | ||
407 | depends on !SINGLE_MEMORY_CHUNK | ||
408 | 68 | ||
409 | source "mm/Kconfig" | 69 | source "mm/Kconfig" |
410 | 70 | ||
411 | endmenu | 71 | endmenu |
412 | 72 | ||
413 | menu "General setup" | 73 | menu "Executable file formats" |
414 | 74 | ||
415 | source "fs/Kconfig.binfmt" | 75 | source "fs/Kconfig.binfmt" |
416 | 76 | ||
417 | config ZORRO | 77 | endmenu |
418 | bool "Amiga Zorro (AutoConfig) bus support" | ||
419 | depends on AMIGA | ||
420 | help | ||
421 | This enables support for the Zorro bus in the Amiga. If you have | ||
422 | expansion cards in your Amiga that conform to the Amiga | ||
423 | AutoConfig(tm) specification, say Y, otherwise N. Note that even | ||
424 | expansion cards that do not fit in the Zorro slots but fit in e.g. | ||
425 | the CPU slot may fall in this category, so you have to say Y to let | ||
426 | Linux use these. | ||
427 | |||
428 | config AMIGA_PCMCIA | ||
429 | bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)" | ||
430 | depends on AMIGA && EXPERIMENTAL | ||
431 | help | ||
432 | Include support in the kernel for pcmcia on Amiga 1200 and Amiga | ||
433 | 600. If you intend to use pcmcia cards say Y; otherwise say N. | ||
434 | |||
435 | config STRAM_PROC | ||
436 | bool "ST-RAM statistics in /proc" | ||
437 | depends on ATARI | ||
438 | help | ||
439 | Say Y here to report ST-RAM usage statistics in /proc/stram. | ||
440 | |||
441 | config HEARTBEAT | ||
442 | bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 | ||
443 | default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 | ||
444 | help | ||
445 | Use the power-on LED on your machine as a load meter. The exact | ||
446 | behavior is platform-dependent, but normally the flash frequency is | ||
447 | a hyperbolic function of the 5-minute load average. | ||
448 | |||
449 | # We have a dedicated heartbeat LED. :-) | ||
450 | config PROC_HARDWARE | ||
451 | bool "/proc/hardware support" | ||
452 | help | ||
453 | Say Y here to support the /proc/hardware file, which gives you | ||
454 | access to information about the machine you're running on, | ||
455 | including the model, CPU, MMU, clock speed, BogoMIPS rating, | ||
456 | and memory size. | ||
457 | |||
458 | config ISA | ||
459 | bool | ||
460 | depends on Q40 || AMIGA_PCMCIA | ||
461 | default y | ||
462 | help | ||
463 | Find out whether you have ISA slots on your motherboard. ISA is the | ||
464 | name of a bus system, i.e. the way the CPU talks to the other stuff | ||
465 | inside your box. Other bus systems are PCI, EISA, MicroChannel | ||
466 | (MCA) or VESA. ISA is an older system, now being displaced by PCI; | ||
467 | newer boards don't support it. If you have ISA, say Y, otherwise N. | ||
468 | |||
469 | config GENERIC_ISA_DMA | ||
470 | bool | ||
471 | depends on Q40 || AMIGA_PCMCIA | ||
472 | default y | ||
473 | |||
474 | config ZONE_DMA | ||
475 | bool | ||
476 | default y | ||
477 | 78 | ||
478 | source "drivers/pci/Kconfig" | 79 | if !MMU |
80 | menu "Power management options" | ||
479 | 81 | ||
480 | source "drivers/zorro/Kconfig" | 82 | config PM |
83 | bool "Power Management support" | ||
84 | help | ||
85 | Support processor power management modes | ||
481 | 86 | ||
482 | endmenu | 87 | endmenu |
88 | endif | ||
483 | 89 | ||
484 | source "net/Kconfig" | 90 | source "net/Kconfig" |
485 | 91 | ||
486 | source "drivers/Kconfig" | 92 | source "drivers/Kconfig" |
487 | 93 | ||
94 | if MMU | ||
95 | |||
488 | menu "Character devices" | 96 | menu "Character devices" |
489 | 97 | ||
490 | config ATARI_MFPSER | 98 | config ATARI_MFPSER |
@@ -627,6 +235,8 @@ config SERIAL_CONSOLE | |||
627 | 235 | ||
628 | endmenu | 236 | endmenu |
629 | 237 | ||
238 | endif | ||
239 | |||
630 | source "fs/Kconfig" | 240 | source "fs/Kconfig" |
631 | 241 | ||
632 | source "arch/m68k/Kconfig.debug" | 242 | source "arch/m68k/Kconfig.debug" |
diff --git a/arch/m68k/Kconfig.debug b/arch/m68k/Kconfig.debug index f53b6d5300e5..2bdb1b01115c 100644 --- a/arch/m68k/Kconfig.debug +++ b/arch/m68k/Kconfig.debug | |||
@@ -2,4 +2,38 @@ menu "Kernel hacking" | |||
2 | 2 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | if !MMU | ||
6 | |||
7 | config FULLDEBUG | ||
8 | bool "Full Symbolic/Source Debugging support" | ||
9 | help | ||
10 | Enable debugging symbols on kernel build. | ||
11 | |||
12 | config HIGHPROFILE | ||
13 | bool "Use fast second timer for profiling" | ||
14 | depends on COLDFIRE | ||
15 | help | ||
16 | Use a fast secondary clock to produce profiling information. | ||
17 | |||
18 | config BOOTPARAM | ||
19 | bool 'Compiled-in Kernel Boot Parameter' | ||
20 | |||
21 | config BOOTPARAM_STRING | ||
22 | string 'Kernel Boot Parameter' | ||
23 | default 'console=ttyS0,19200' | ||
24 | depends on BOOTPARAM | ||
25 | |||
26 | config NO_KERNEL_MSG | ||
27 | bool "Suppress Kernel BUG Messages" | ||
28 | help | ||
29 | Do not output any debug BUG messages within the kernel. | ||
30 | |||
31 | config BDM_DISABLE | ||
32 | bool "Disable BDM signals" | ||
33 | depends on (EXPERIMENTAL && COLDFIRE) | ||
34 | help | ||
35 | Disable the ColdFire CPU's BDM signals. | ||
36 | |||
37 | endif | ||
38 | |||
5 | endmenu | 39 | endmenu |
diff --git a/arch/m68k/Kconfig.mmu b/arch/m68k/Kconfig.mmu new file mode 100644 index 000000000000..16539b1d5d3a --- /dev/null +++ b/arch/m68k/Kconfig.mmu | |||
@@ -0,0 +1,417 @@ | |||
1 | config GENERIC_IOMAP | ||
2 | bool | ||
3 | default y | ||
4 | |||
5 | config ARCH_MAY_HAVE_PC_FDC | ||
6 | bool | ||
7 | depends on BROKEN && (Q40 || SUN3X) | ||
8 | default y | ||
9 | |||
10 | config ARCH_USES_GETTIMEOFFSET | ||
11 | def_bool y | ||
12 | |||
13 | config EISA | ||
14 | bool | ||
15 | ---help--- | ||
16 | The Extended Industry Standard Architecture (EISA) bus was | ||
17 | developed as an open alternative to the IBM MicroChannel bus. | ||
18 | |||
19 | The EISA bus provided some of the features of the IBM MicroChannel | ||
20 | bus while maintaining backward compatibility with cards made for | ||
21 | the older ISA bus. The EISA bus saw limited use between 1988 and | ||
22 | 1995 when it was made obsolete by the PCI bus. | ||
23 | |||
24 | Say Y here if you are building a kernel for an EISA-based machine. | ||
25 | |||
26 | Otherwise, say N. | ||
27 | |||
28 | config MCA | ||
29 | bool | ||
30 | help | ||
31 | MicroChannel Architecture is found in some IBM PS/2 machines and | ||
32 | laptops. It is a bus system similar to PCI or ISA. See | ||
33 | <file:Documentation/mca.txt> (and especially the web page given | ||
34 | there) before attempting to build an MCA bus kernel. | ||
35 | |||
36 | config PCMCIA | ||
37 | tristate | ||
38 | ---help--- | ||
39 | Say Y here if you want to attach PCMCIA- or PC-cards to your Linux | ||
40 | computer. These are credit-card size devices such as network cards, | ||
41 | modems or hard drives often used with laptops computers. There are | ||
42 | actually two varieties of these cards: the older 16 bit PCMCIA cards | ||
43 | and the newer 32 bit CardBus cards. If you want to use CardBus | ||
44 | cards, you need to say Y here and also to "CardBus support" below. | ||
45 | |||
46 | To use your PC-cards, you will need supporting software from David | ||
47 | Hinds' pcmcia-cs package (see the file <file:Documentation/Changes> | ||
48 | for location). Please also read the PCMCIA-HOWTO, available from | ||
49 | <http://www.tldp.org/docs.html#howto>. | ||
50 | |||
51 | To compile this driver as modules, choose M here: the | ||
52 | modules will be called pcmcia_core and ds. | ||
53 | |||
54 | config AMIGA | ||
55 | bool "Amiga support" | ||
56 | select MMU_MOTOROLA if MMU | ||
57 | help | ||
58 | This option enables support for the Amiga series of computers. If | ||
59 | you plan to use this kernel on an Amiga, say Y here and browse the | ||
60 | material available in <file:Documentation/m68k>; otherwise say N. | ||
61 | |||
62 | config ATARI | ||
63 | bool "Atari support" | ||
64 | select MMU_MOTOROLA if MMU | ||
65 | help | ||
66 | This option enables support for the 68000-based Atari series of | ||
67 | computers (including the TT, Falcon and Medusa). If you plan to use | ||
68 | this kernel on an Atari, say Y here and browse the material | ||
69 | available in <file:Documentation/m68k>; otherwise say N. | ||
70 | |||
71 | config MAC | ||
72 | bool "Macintosh support" | ||
73 | select MMU_MOTOROLA if MMU | ||
74 | help | ||
75 | This option enables support for the Apple Macintosh series of | ||
76 | computers (yes, there is experimental support now, at least for part | ||
77 | of the series). | ||
78 | |||
79 | Say N unless you're willing to code the remaining necessary support. | ||
80 | ;) | ||
81 | |||
82 | config NUBUS | ||
83 | bool | ||
84 | depends on MAC | ||
85 | default y | ||
86 | |||
87 | config M68K_L2_CACHE | ||
88 | bool | ||
89 | depends on MAC | ||
90 | default y | ||
91 | |||
92 | config APOLLO | ||
93 | bool "Apollo support" | ||
94 | select MMU_MOTOROLA if MMU | ||
95 | help | ||
96 | Say Y here if you want to run Linux on an MC680x0-based Apollo | ||
97 | Domain workstation such as the DN3500. | ||
98 | |||
99 | config VME | ||
100 | bool "VME (Motorola and BVM) support" | ||
101 | select MMU_MOTOROLA if MMU | ||
102 | help | ||
103 | Say Y here if you want to build a kernel for a 680x0 based VME | ||
104 | board. Boards currently supported include Motorola boards MVME147, | ||
105 | MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and | ||
106 | BVME6000 boards from BVM Ltd are also supported. | ||
107 | |||
108 | config MVME147 | ||
109 | bool "MVME147 support" | ||
110 | depends on VME | ||
111 | help | ||
112 | Say Y to include support for early Motorola VME boards. This will | ||
113 | build a kernel which can run on MVME147 single-board computers. If | ||
114 | you select this option you will have to select the appropriate | ||
115 | drivers for SCSI, Ethernet and serial ports later on. | ||
116 | |||
117 | config MVME16x | ||
118 | bool "MVME162, 166 and 167 support" | ||
119 | depends on VME | ||
120 | help | ||
121 | Say Y to include support for Motorola VME boards. This will build a | ||
122 | kernel which can run on MVME162, MVME166, MVME167, MVME172, and | ||
123 | MVME177 boards. If you select this option you will have to select | ||
124 | the appropriate drivers for SCSI, Ethernet and serial ports later | ||
125 | on. | ||
126 | |||
127 | config BVME6000 | ||
128 | bool "BVME4000 and BVME6000 support" | ||
129 | depends on VME | ||
130 | help | ||
131 | Say Y to include support for VME boards from BVM Ltd. This will | ||
132 | build a kernel which can run on BVME4000 and BVME6000 boards. If | ||
133 | you select this option you will have to select the appropriate | ||
134 | drivers for SCSI, Ethernet and serial ports later on. | ||
135 | |||
136 | config HP300 | ||
137 | bool "HP9000/300 and HP9000/400 support" | ||
138 | select MMU_MOTOROLA if MMU | ||
139 | help | ||
140 | This option enables support for the HP9000/300 and HP9000/400 series | ||
141 | of workstations. Support for these machines is still somewhat | ||
142 | experimental. If you plan to try to use the kernel on such a machine | ||
143 | say Y here. | ||
144 | Everybody else says N. | ||
145 | |||
146 | config DIO | ||
147 | bool "DIO bus support" | ||
148 | depends on HP300 | ||
149 | default y | ||
150 | help | ||
151 | Say Y here to enable support for the "DIO" expansion bus used in | ||
152 | HP300 machines. If you are using such a system you almost certainly | ||
153 | want this. | ||
154 | |||
155 | config SUN3X | ||
156 | bool "Sun3x support" | ||
157 | select MMU_MOTOROLA if MMU | ||
158 | select M68030 | ||
159 | help | ||
160 | This option enables support for the Sun 3x series of workstations. | ||
161 | Be warned that this support is very experimental. | ||
162 | Note that Sun 3x kernels are not compatible with Sun 3 hardware. | ||
163 | General Linux information on the Sun 3x series (now discontinued) | ||
164 | is at <http://www.angelfire.com/ca2/tech68k/sun3.html>. | ||
165 | |||
166 | If you don't want to compile a kernel for a Sun 3x, say N. | ||
167 | |||
168 | config Q40 | ||
169 | bool "Q40/Q60 support" | ||
170 | select MMU_MOTOROLA if MMU | ||
171 | help | ||
172 | The Q40 is a Motorola 68040-based successor to the Sinclair QL | ||
173 | manufactured in Germany. There is an official Q40 home page at | ||
174 | <http://www.q40.de/>. This option enables support for the Q40 and | ||
175 | Q60. Select your CPU below. For 68LC060 don't forget to enable FPU | ||
176 | emulation. | ||
177 | |||
178 | config SUN3 | ||
179 | bool "Sun3 support" | ||
180 | depends on !MMU_MOTOROLA | ||
181 | select MMU_SUN3 if MMU | ||
182 | select M68020 | ||
183 | help | ||
184 | This option enables support for the Sun 3 series of workstations | ||
185 | (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires | ||
186 | that all other hardware types must be disabled, as Sun 3 kernels | ||
187 | are incompatible with all other m68k targets (including Sun 3x!). | ||
188 | |||
189 | If you don't want to compile a kernel exclusively for a Sun 3, say N. | ||
190 | |||
191 | config NATFEAT | ||
192 | bool "ARAnyM emulator support" | ||
193 | depends on ATARI | ||
194 | help | ||
195 | This option enables support for ARAnyM native features, such as | ||
196 | access to a disk image as /dev/hda. | ||
197 | |||
198 | config NFBLOCK | ||
199 | tristate "NatFeat block device support" | ||
200 | depends on BLOCK && NATFEAT | ||
201 | help | ||
202 | Say Y to include support for the ARAnyM NatFeat block device | ||
203 | which allows direct access to the hard drives without using | ||
204 | the hardware emulation. | ||
205 | |||
206 | config NFCON | ||
207 | tristate "NatFeat console driver" | ||
208 | depends on NATFEAT | ||
209 | help | ||
210 | Say Y to include support for the ARAnyM NatFeat console driver | ||
211 | which allows the console output to be redirected to the stderr | ||
212 | output of ARAnyM. | ||
213 | |||
214 | config NFETH | ||
215 | tristate "NatFeat Ethernet support" | ||
216 | depends on NET_ETHERNET && NATFEAT | ||
217 | help | ||
218 | Say Y to include support for the ARAnyM NatFeat network device | ||
219 | which will emulate a regular ethernet device while presenting an | ||
220 | ethertap device to the host system. | ||
221 | |||
222 | comment "Processor type" | ||
223 | |||
224 | config M68020 | ||
225 | bool "68020 support" | ||
226 | help | ||
227 | If you anticipate running this kernel on a computer with a MC68020 | ||
228 | processor, say Y. Otherwise, say N. Note that the 68020 requires a | ||
229 | 68851 MMU (Memory Management Unit) to run Linux/m68k, except on the | ||
230 | Sun 3, which provides its own version. | ||
231 | |||
232 | config M68030 | ||
233 | bool "68030 support" | ||
234 | depends on !MMU_SUN3 | ||
235 | help | ||
236 | If you anticipate running this kernel on a computer with a MC68030 | ||
237 | processor, say Y. Otherwise, say N. Note that a MC68EC030 will not | ||
238 | work, as it does not include an MMU (Memory Management Unit). | ||
239 | |||
240 | config M68040 | ||
241 | bool "68040 support" | ||
242 | depends on !MMU_SUN3 | ||
243 | help | ||
244 | If you anticipate running this kernel on a computer with a MC68LC040 | ||
245 | or MC68040 processor, say Y. Otherwise, say N. Note that an | ||
246 | MC68EC040 will not work, as it does not include an MMU (Memory | ||
247 | Management Unit). | ||
248 | |||
249 | config M68060 | ||
250 | bool "68060 support" | ||
251 | depends on !MMU_SUN3 | ||
252 | help | ||
253 | If you anticipate running this kernel on a computer with a MC68060 | ||
254 | processor, say Y. Otherwise, say N. | ||
255 | |||
256 | config MMU_MOTOROLA | ||
257 | bool | ||
258 | |||
259 | config MMU_SUN3 | ||
260 | bool | ||
261 | depends on MMU && !MMU_MOTOROLA | ||
262 | |||
263 | config M68KFPU_EMU | ||
264 | bool "Math emulation support (EXPERIMENTAL)" | ||
265 | depends on EXPERIMENTAL | ||
266 | help | ||
267 | At some point in the future, this will cause floating-point math | ||
268 | instructions to be emulated by the kernel on machines that lack a | ||
269 | floating-point math coprocessor. Thrill-seekers and chronically | ||
270 | sleep-deprived psychotic hacker types can say Y now, everyone else | ||
271 | should probably wait a while. | ||
272 | |||
273 | config M68KFPU_EMU_EXTRAPREC | ||
274 | bool "Math emulation extra precision" | ||
275 | depends on M68KFPU_EMU | ||
276 | help | ||
277 | The fpu uses normally a few bit more during calculations for | ||
278 | correct rounding, the emulator can (often) do the same but this | ||
279 | extra calculation can cost quite some time, so you can disable | ||
280 | it here. The emulator will then "only" calculate with a 64 bit | ||
281 | mantissa and round slightly incorrect, what is more than enough | ||
282 | for normal usage. | ||
283 | |||
284 | config M68KFPU_EMU_ONLY | ||
285 | bool "Math emulation only kernel" | ||
286 | depends on M68KFPU_EMU | ||
287 | help | ||
288 | This option prevents any floating-point instructions from being | ||
289 | compiled into the kernel, thereby the kernel doesn't save any | ||
290 | floating point context anymore during task switches, so this | ||
291 | kernel will only be usable on machines without a floating-point | ||
292 | math coprocessor. This makes the kernel a bit faster as no tests | ||
293 | needs to be executed whether a floating-point instruction in the | ||
294 | kernel should be executed or not. | ||
295 | |||
296 | config ADVANCED | ||
297 | bool "Advanced configuration options" | ||
298 | ---help--- | ||
299 | This gives you access to some advanced options for the CPU. The | ||
300 | defaults should be fine for most users, but these options may make | ||
301 | it possible for you to improve performance somewhat if you know what | ||
302 | you are doing. | ||
303 | |||
304 | Note that the answer to this question won't directly affect the | ||
305 | kernel: saying N will just cause the configurator to skip all | ||
306 | the questions about these options. | ||
307 | |||
308 | Most users should say N to this question. | ||
309 | |||
310 | config RMW_INSNS | ||
311 | bool "Use read-modify-write instructions" | ||
312 | depends on ADVANCED | ||
313 | ---help--- | ||
314 | This allows to use certain instructions that work with indivisible | ||
315 | read-modify-write bus cycles. While this is faster than the | ||
316 | workaround of disabling interrupts, it can conflict with DMA | ||
317 | ( = direct memory access) on many Amiga systems, and it is also said | ||
318 | to destabilize other machines. It is very likely that this will | ||
319 | cause serious problems on any Amiga or Atari Medusa if set. The only | ||
320 | configuration where it should work are 68030-based Ataris, where it | ||
321 | apparently improves performance. But you've been warned! Unless you | ||
322 | really know what you are doing, say N. Try Y only if you're quite | ||
323 | adventurous. | ||
324 | |||
325 | config SINGLE_MEMORY_CHUNK | ||
326 | bool "Use one physical chunk of memory only" if ADVANCED && !SUN3 | ||
327 | default y if SUN3 | ||
328 | select NEED_MULTIPLE_NODES | ||
329 | help | ||
330 | Ignore all but the first contiguous chunk of physical memory for VM | ||
331 | purposes. This will save a few bytes kernel size and may speed up | ||
332 | some operations. Say N if not sure. | ||
333 | |||
334 | config 060_WRITETHROUGH | ||
335 | bool "Use write-through caching for 68060 supervisor accesses" | ||
336 | depends on ADVANCED && M68060 | ||
337 | ---help--- | ||
338 | The 68060 generally uses copyback caching of recently accessed data. | ||
339 | Copyback caching means that memory writes will be held in an on-chip | ||
340 | cache and only written back to memory some time later. Saying Y | ||
341 | here will force supervisor (kernel) accesses to use writethrough | ||
342 | caching. Writethrough caching means that data is written to memory | ||
343 | straight away, so that cache and memory data always agree. | ||
344 | Writethrough caching is less efficient, but is needed for some | ||
345 | drivers on 68060 based systems where the 68060 bus snooping signal | ||
346 | is hardwired on. The 53c710 SCSI driver is known to suffer from | ||
347 | this problem. | ||
348 | |||
349 | config ARCH_DISCONTIGMEM_ENABLE | ||
350 | def_bool !SINGLE_MEMORY_CHUNK | ||
351 | |||
352 | config NODES_SHIFT | ||
353 | int | ||
354 | default "3" | ||
355 | depends on !SINGLE_MEMORY_CHUNK | ||
356 | |||
357 | config ZORRO | ||
358 | bool "Amiga Zorro (AutoConfig) bus support" | ||
359 | depends on AMIGA | ||
360 | help | ||
361 | This enables support for the Zorro bus in the Amiga. If you have | ||
362 | expansion cards in your Amiga that conform to the Amiga | ||
363 | AutoConfig(tm) specification, say Y, otherwise N. Note that even | ||
364 | expansion cards that do not fit in the Zorro slots but fit in e.g. | ||
365 | the CPU slot may fall in this category, so you have to say Y to let | ||
366 | Linux use these. | ||
367 | |||
368 | config AMIGA_PCMCIA | ||
369 | bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)" | ||
370 | depends on AMIGA && EXPERIMENTAL | ||
371 | help | ||
372 | Include support in the kernel for pcmcia on Amiga 1200 and Amiga | ||
373 | 600. If you intend to use pcmcia cards say Y; otherwise say N. | ||
374 | |||
375 | config STRAM_PROC | ||
376 | bool "ST-RAM statistics in /proc" | ||
377 | depends on ATARI | ||
378 | help | ||
379 | Say Y here to report ST-RAM usage statistics in /proc/stram. | ||
380 | |||
381 | config HEARTBEAT | ||
382 | bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 | ||
383 | default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 | ||
384 | help | ||
385 | Use the power-on LED on your machine as a load meter. The exact | ||
386 | behavior is platform-dependent, but normally the flash frequency is | ||
387 | a hyperbolic function of the 5-minute load average. | ||
388 | |||
389 | # We have a dedicated heartbeat LED. :-) | ||
390 | config PROC_HARDWARE | ||
391 | bool "/proc/hardware support" | ||
392 | help | ||
393 | Say Y here to support the /proc/hardware file, which gives you | ||
394 | access to information about the machine you're running on, | ||
395 | including the model, CPU, MMU, clock speed, BogoMIPS rating, | ||
396 | and memory size. | ||
397 | |||
398 | config ISA | ||
399 | bool | ||
400 | depends on Q40 || AMIGA_PCMCIA | ||
401 | default y | ||
402 | help | ||
403 | Find out whether you have ISA slots on your motherboard. ISA is the | ||
404 | name of a bus system, i.e. the way the CPU talks to the other stuff | ||
405 | inside your box. Other bus systems are PCI, EISA, MicroChannel | ||
406 | (MCA) or VESA. ISA is an older system, now being displaced by PCI; | ||
407 | newer boards don't support it. If you have ISA, say Y, otherwise N. | ||
408 | |||
409 | config GENERIC_ISA_DMA | ||
410 | bool | ||
411 | depends on Q40 || AMIGA_PCMCIA | ||
412 | default y | ||
413 | |||
414 | source "drivers/pci/Kconfig" | ||
415 | |||
416 | source "drivers/zorro/Kconfig" | ||
417 | |||
diff --git a/arch/m68knommu/Kconfig b/arch/m68k/Kconfig.nommu index b5424cf948e6..273bccab9517 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68k/Kconfig.nommu | |||
@@ -1,43 +1,7 @@ | |||
1 | config M68K | ||
2 | bool | ||
3 | default y | ||
4 | select HAVE_IDE | ||
5 | select HAVE_GENERIC_HARDIRQS | ||
6 | select GENERIC_HARDIRQS_NO_DEPRECATED | ||
7 | |||
8 | config MMU | ||
9 | bool | ||
10 | default n | ||
11 | |||
12 | config NO_DMA | ||
13 | bool | ||
14 | depends on !COLDFIRE | ||
15 | default y | ||
16 | |||
17 | config FPU | 1 | config FPU |
18 | bool | 2 | bool |
19 | default n | 3 | default n |
20 | 4 | ||
21 | config ZONE_DMA | ||
22 | bool | ||
23 | default y | ||
24 | |||
25 | config RWSEM_GENERIC_SPINLOCK | ||
26 | bool | ||
27 | default y | ||
28 | |||
29 | config RWSEM_XCHGADD_ALGORITHM | ||
30 | bool | ||
31 | default n | ||
32 | |||
33 | config ARCH_HAS_ILOG2_U32 | ||
34 | bool | ||
35 | default n | ||
36 | |||
37 | config ARCH_HAS_ILOG2_U64 | ||
38 | bool | ||
39 | default n | ||
40 | |||
41 | config GENERIC_FIND_NEXT_BIT | 5 | config GENERIC_FIND_NEXT_BIT |
42 | bool | 6 | bool |
43 | default y | 7 | default y |
@@ -46,29 +10,14 @@ config GENERIC_GPIO | |||
46 | bool | 10 | bool |
47 | default n | 11 | default n |
48 | 12 | ||
49 | config GENERIC_HWEIGHT | ||
50 | bool | ||
51 | default y | ||
52 | |||
53 | config GENERIC_CALIBRATE_DELAY | ||
54 | bool | ||
55 | default y | ||
56 | |||
57 | config GENERIC_CMOS_UPDATE | 13 | config GENERIC_CMOS_UPDATE |
58 | bool | 14 | bool |
59 | default y | 15 | default y |
60 | 16 | ||
61 | config TIME_LOW_RES | ||
62 | bool | ||
63 | default y | ||
64 | |||
65 | config GENERIC_CLOCKEVENTS | 17 | config GENERIC_CLOCKEVENTS |
66 | bool | 18 | bool |
67 | default n | 19 | default n |
68 | 20 | ||
69 | config NO_IOPORT | ||
70 | def_bool y | ||
71 | |||
72 | config COLDFIRE_SW_A7 | 21 | config COLDFIRE_SW_A7 |
73 | bool | 22 | bool |
74 | default n | 23 | default n |
@@ -85,12 +34,6 @@ config HAVE_MBAR | |||
85 | config HAVE_IPSBAR | 34 | config HAVE_IPSBAR |
86 | bool | 35 | bool |
87 | 36 | ||
88 | source "init/Kconfig" | ||
89 | |||
90 | source "kernel/Kconfig.freezer" | ||
91 | |||
92 | menu "Processor type and features" | ||
93 | |||
94 | choice | 37 | choice |
95 | prompt "CPU" | 38 | prompt "CPU" |
96 | default M68EZ328 | 39 | default M68EZ328 |
@@ -630,11 +573,6 @@ config 4KSTACKS | |||
630 | running more threads on a system and also reduces the pressure | 573 | running more threads on a system and also reduces the pressure |
631 | on the VM subsystem for higher order allocations. | 574 | on the VM subsystem for higher order allocations. |
632 | 575 | ||
633 | config HZ | ||
634 | int | ||
635 | default 1000 if CLEOPATRA | ||
636 | default 100 | ||
637 | |||
638 | comment "RAM configuration" | 576 | comment "RAM configuration" |
639 | 577 | ||
640 | config RAMBASE | 578 | config RAMBASE |
@@ -803,10 +741,6 @@ endif | |||
803 | 741 | ||
804 | source "kernel/time/Kconfig" | 742 | source "kernel/time/Kconfig" |
805 | 743 | ||
806 | source "mm/Kconfig" | ||
807 | |||
808 | endmenu | ||
809 | |||
810 | config ISA_DMA_API | 744 | config ISA_DMA_API |
811 | bool | 745 | bool |
812 | depends on !M5272 | 746 | depends on !M5272 |
@@ -814,31 +748,3 @@ config ISA_DMA_API | |||
814 | 748 | ||
815 | source "drivers/pcmcia/Kconfig" | 749 | source "drivers/pcmcia/Kconfig" |
816 | 750 | ||
817 | menu "Executable file formats" | ||
818 | |||
819 | source "fs/Kconfig.binfmt" | ||
820 | |||
821 | endmenu | ||
822 | |||
823 | menu "Power management options" | ||
824 | |||
825 | config PM | ||
826 | bool "Power Management support" | ||
827 | help | ||
828 | Support processor power management modes | ||
829 | |||
830 | endmenu | ||
831 | |||
832 | source "net/Kconfig" | ||
833 | |||
834 | source "drivers/Kconfig" | ||
835 | |||
836 | source "fs/Kconfig" | ||
837 | |||
838 | source "arch/m68knommu/Kconfig.debug" | ||
839 | |||
840 | source "security/Kconfig" | ||
841 | |||
842 | source "crypto/Kconfig" | ||
843 | |||
844 | source "lib/Kconfig" | ||
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index b793163abc61..be46cadd4017 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile | |||
@@ -1,123 +1,7 @@ | |||
1 | # | ||
2 | # m68k/Makefile | ||
3 | # | ||
4 | # This file is included by the global makefile so that you can add your own | ||
5 | # architecture-specific flags and dependencies. Remember to do have actions | ||
6 | # for "archclean" and "archdep" for cleaning up and making dependencies for | ||
7 | # this architecture | ||
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 | # Copyright (C) 1994 by Hamish Macdonald | ||
14 | # | ||
15 | |||
16 | KBUILD_DEFCONFIG := multi_defconfig | 1 | KBUILD_DEFCONFIG := multi_defconfig |
17 | 2 | ||
18 | # override top level makefile | 3 | ifdef CONFIG_MMU |
19 | AS += -m68020 | 4 | include $(srctree)/arch/m68k/Makefile_mm |
20 | LDFLAGS := -m m68kelf | ||
21 | KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds | ||
22 | ifneq ($(SUBARCH),$(ARCH)) | ||
23 | ifeq ($(CROSS_COMPILE),) | ||
24 | CROSS_COMPILE := $(call cc-cross-prefix, \ | ||
25 | m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) | ||
26 | endif | ||
27 | endif | ||
28 | |||
29 | ifdef CONFIG_SUN3 | ||
30 | LDFLAGS_vmlinux = -N | ||
31 | endif | ||
32 | |||
33 | CHECKFLAGS += -D__mc68000__ | ||
34 | |||
35 | # without -fno-strength-reduce the 53c7xx.c driver fails ;-( | ||
36 | KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2 | ||
37 | |||
38 | # enable processor switch if compiled only for a single cpu | ||
39 | ifndef CONFIG_M68020 | ||
40 | ifndef CONFIG_M68030 | ||
41 | |||
42 | ifndef CONFIG_M68060 | ||
43 | KBUILD_CFLAGS += -m68040 | ||
44 | endif | ||
45 | |||
46 | ifndef CONFIG_M68040 | ||
47 | KBUILD_CFLAGS += -m68060 | ||
48 | endif | ||
49 | |||
50 | endif | ||
51 | endif | ||
52 | |||
53 | ifdef CONFIG_KGDB | ||
54 | # If configured for kgdb support, include debugging infos and keep the | ||
55 | # frame pointer | ||
56 | KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g | ||
57 | endif | ||
58 | |||
59 | ifndef CONFIG_SUN3 | ||
60 | head-y := arch/m68k/kernel/head.o | ||
61 | else | 5 | else |
62 | head-y := arch/m68k/kernel/sun3-head.o | 6 | include $(srctree)/arch/m68k/Makefile_no |
63 | endif | 7 | endif |
64 | |||
65 | core-y += arch/m68k/kernel/ arch/m68k/mm/ | ||
66 | libs-y += arch/m68k/lib/ | ||
67 | |||
68 | core-$(CONFIG_Q40) += arch/m68k/q40/ | ||
69 | core-$(CONFIG_AMIGA) += arch/m68k/amiga/ | ||
70 | core-$(CONFIG_ATARI) += arch/m68k/atari/ | ||
71 | core-$(CONFIG_MAC) += arch/m68k/mac/ | ||
72 | core-$(CONFIG_HP300) += arch/m68k/hp300/ | ||
73 | core-$(CONFIG_APOLLO) += arch/m68k/apollo/ | ||
74 | core-$(CONFIG_MVME147) += arch/m68k/mvme147/ | ||
75 | core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/ | ||
76 | core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/ | ||
77 | core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/ | ||
78 | core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/ | ||
79 | core-$(CONFIG_NATFEAT) += arch/m68k/emu/ | ||
80 | core-$(CONFIG_M68040) += arch/m68k/fpsp040/ | ||
81 | core-$(CONFIG_M68060) += arch/m68k/ifpsp060/ | ||
82 | core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/ | ||
83 | |||
84 | all: zImage | ||
85 | |||
86 | lilo: vmlinux | ||
87 | if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi | ||
88 | if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi | ||
89 | cat vmlinux > $(INSTALL_PATH)/vmlinux | ||
90 | cp System.map $(INSTALL_PATH)/System.map | ||
91 | if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi | ||
92 | |||
93 | zImage compressed: vmlinux.gz | ||
94 | |||
95 | vmlinux.gz: vmlinux | ||
96 | |||
97 | ifndef CONFIG_KGDB | ||
98 | cp vmlinux vmlinux.tmp | ||
99 | $(STRIP) vmlinux.tmp | ||
100 | gzip -9c vmlinux.tmp >vmlinux.gz | ||
101 | rm vmlinux.tmp | ||
102 | else | ||
103 | gzip -9c vmlinux >vmlinux.gz | ||
104 | endif | ||
105 | |||
106 | bzImage: vmlinux.bz2 | ||
107 | |||
108 | vmlinux.bz2: vmlinux | ||
109 | |||
110 | ifndef CONFIG_KGDB | ||
111 | cp vmlinux vmlinux.tmp | ||
112 | $(STRIP) vmlinux.tmp | ||
113 | bzip2 -1c vmlinux.tmp >vmlinux.bz2 | ||
114 | rm vmlinux.tmp | ||
115 | else | ||
116 | bzip2 -1c vmlinux >vmlinux.bz2 | ||
117 | endif | ||
118 | |||
119 | archclean: | ||
120 | rm -f vmlinux.gz vmlinux.bz2 | ||
121 | |||
122 | install: | ||
123 | sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" | ||
diff --git a/arch/m68k/Makefile_mm b/arch/m68k/Makefile_mm new file mode 100644 index 000000000000..d449b6d5aecf --- /dev/null +++ b/arch/m68k/Makefile_mm | |||
@@ -0,0 +1,121 @@ | |||
1 | # | ||
2 | # m68k/Makefile | ||
3 | # | ||
4 | # This file is included by the global makefile so that you can add your own | ||
5 | # architecture-specific flags and dependencies. Remember to do have actions | ||
6 | # for "archclean" and "archdep" for cleaning up and making dependencies for | ||
7 | # this architecture | ||
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 | # Copyright (C) 1994 by Hamish Macdonald | ||
14 | # | ||
15 | |||
16 | # override top level makefile | ||
17 | AS += -m68020 | ||
18 | LDFLAGS := -m m68kelf | ||
19 | KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds | ||
20 | ifneq ($(SUBARCH),$(ARCH)) | ||
21 | ifeq ($(CROSS_COMPILE),) | ||
22 | CROSS_COMPILE := $(call cc-cross-prefix, \ | ||
23 | m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) | ||
24 | endif | ||
25 | endif | ||
26 | |||
27 | ifdef CONFIG_SUN3 | ||
28 | LDFLAGS_vmlinux = -N | ||
29 | endif | ||
30 | |||
31 | CHECKFLAGS += -D__mc68000__ | ||
32 | |||
33 | # without -fno-strength-reduce the 53c7xx.c driver fails ;-( | ||
34 | KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2 | ||
35 | |||
36 | # enable processor switch if compiled only for a single cpu | ||
37 | ifndef CONFIG_M68020 | ||
38 | ifndef CONFIG_M68030 | ||
39 | |||
40 | ifndef CONFIG_M68060 | ||
41 | KBUILD_CFLAGS += -m68040 | ||
42 | endif | ||
43 | |||
44 | ifndef CONFIG_M68040 | ||
45 | KBUILD_CFLAGS += -m68060 | ||
46 | endif | ||
47 | |||
48 | endif | ||
49 | endif | ||
50 | |||
51 | ifdef CONFIG_KGDB | ||
52 | # If configured for kgdb support, include debugging infos and keep the | ||
53 | # frame pointer | ||
54 | KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g | ||
55 | endif | ||
56 | |||
57 | ifndef CONFIG_SUN3 | ||
58 | head-y := arch/m68k/kernel/head.o | ||
59 | else | ||
60 | head-y := arch/m68k/kernel/sun3-head.o | ||
61 | endif | ||
62 | |||
63 | core-y += arch/m68k/kernel/ arch/m68k/mm/ | ||
64 | libs-y += arch/m68k/lib/ | ||
65 | |||
66 | core-$(CONFIG_Q40) += arch/m68k/q40/ | ||
67 | core-$(CONFIG_AMIGA) += arch/m68k/amiga/ | ||
68 | core-$(CONFIG_ATARI) += arch/m68k/atari/ | ||
69 | core-$(CONFIG_MAC) += arch/m68k/mac/ | ||
70 | core-$(CONFIG_HP300) += arch/m68k/hp300/ | ||
71 | core-$(CONFIG_APOLLO) += arch/m68k/apollo/ | ||
72 | core-$(CONFIG_MVME147) += arch/m68k/mvme147/ | ||
73 | core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/ | ||
74 | core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/ | ||
75 | core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/ | ||
76 | core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/ | ||
77 | core-$(CONFIG_NATFEAT) += arch/m68k/emu/ | ||
78 | core-$(CONFIG_M68040) += arch/m68k/fpsp040/ | ||
79 | core-$(CONFIG_M68060) += arch/m68k/ifpsp060/ | ||
80 | core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/ | ||
81 | |||
82 | all: zImage | ||
83 | |||
84 | lilo: vmlinux | ||
85 | if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi | ||
86 | if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi | ||
87 | cat vmlinux > $(INSTALL_PATH)/vmlinux | ||
88 | cp System.map $(INSTALL_PATH)/System.map | ||
89 | if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi | ||
90 | |||
91 | zImage compressed: vmlinux.gz | ||
92 | |||
93 | vmlinux.gz: vmlinux | ||
94 | |||
95 | ifndef CONFIG_KGDB | ||
96 | cp vmlinux vmlinux.tmp | ||
97 | $(STRIP) vmlinux.tmp | ||
98 | gzip -9c vmlinux.tmp >vmlinux.gz | ||
99 | rm vmlinux.tmp | ||
100 | else | ||
101 | gzip -9c vmlinux >vmlinux.gz | ||
102 | endif | ||
103 | |||
104 | bzImage: vmlinux.bz2 | ||
105 | |||
106 | vmlinux.bz2: vmlinux | ||
107 | |||
108 | ifndef CONFIG_KGDB | ||
109 | cp vmlinux vmlinux.tmp | ||
110 | $(STRIP) vmlinux.tmp | ||
111 | bzip2 -1c vmlinux.tmp >vmlinux.bz2 | ||
112 | rm vmlinux.tmp | ||
113 | else | ||
114 | bzip2 -1c vmlinux >vmlinux.bz2 | ||
115 | endif | ||
116 | |||
117 | archclean: | ||
118 | rm -f vmlinux.gz vmlinux.bz2 | ||
119 | |||
120 | install: | ||
121 | sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" | ||
diff --git a/arch/m68knommu/Makefile b/arch/m68k/Makefile_no index 589613fed31d..81652ab893e1 100644 --- a/arch/m68knommu/Makefile +++ b/arch/m68k/Makefile_no | |||
@@ -1,5 +1,5 @@ | |||
1 | # | 1 | # |
2 | # arch/m68knommu/Makefile | 2 | # arch/m68k/Makefile |
3 | # | 3 | # |
4 | # This file is subject to the terms and conditions of the GNU General Public | 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 | 5 | # License. See the file "COPYING" in the main directory of this archive |
@@ -8,8 +8,6 @@ | |||
8 | # (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com> | 8 | # (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com> |
9 | # | 9 | # |
10 | 10 | ||
11 | KBUILD_DEFCONFIG := m5208evb_defconfig | ||
12 | |||
13 | platform-$(CONFIG_M68328) := 68328 | 11 | platform-$(CONFIG_M68328) := 68328 |
14 | platform-$(CONFIG_M68EZ328) := 68EZ328 | 12 | platform-$(CONFIG_M68EZ328) := 68EZ328 |
15 | platform-$(CONFIG_M68VZ328) := 68VZ328 | 13 | platform-$(CONFIG_M68VZ328) := 68VZ328 |
@@ -82,7 +80,7 @@ cpuclass-$(CONFIG_M68360) := 68360 | |||
82 | CPUCLASS := $(cpuclass-y) | 80 | CPUCLASS := $(cpuclass-y) |
83 | 81 | ||
84 | ifneq ($(CPUCLASS),$(PLATFORM)) | 82 | ifneq ($(CPUCLASS),$(PLATFORM)) |
85 | CLASSDIR := arch/m68knommu/platform/$(cpuclass-y)/ | 83 | CLASSDIR := arch/m68k/platform/$(cpuclass-y)/ |
86 | endif | 84 | endif |
87 | 85 | ||
88 | export PLATFORM BOARD MODEL CPUCLASS | 86 | export PLATFORM BOARD MODEL CPUCLASS |
@@ -114,13 +112,13 @@ KBUILD_CFLAGS += $(cflags-y) | |||
114 | KBUILD_CFLAGS += -D__linux__ | 112 | KBUILD_CFLAGS += -D__linux__ |
115 | KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\" | 113 | KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\" |
116 | 114 | ||
117 | head-y := arch/m68knommu/platform/$(cpuclass-y)/head.o | 115 | head-y := arch/m68k/platform/$(cpuclass-y)/head.o |
118 | 116 | ||
119 | core-y += arch/m68knommu/kernel/ \ | 117 | core-y += arch/m68k/kernel/ \ |
120 | arch/m68knommu/mm/ \ | 118 | arch/m68k/mm/ \ |
121 | $(CLASSDIR) \ | 119 | $(CLASSDIR) \ |
122 | arch/m68knommu/platform/$(PLATFORM)/ | 120 | arch/m68k/platform/$(PLATFORM)/ |
123 | libs-y += arch/m68knommu/lib/ | 121 | libs-y += arch/m68k/lib/ |
124 | 122 | ||
125 | archclean: | 123 | archclean: |
126 | 124 | ||
diff --git a/arch/m68knommu/configs/m5208evb_defconfig b/arch/m68k/configs/m5208evb_defconfig index 2f5655c577af..c1616824e201 100644 --- a/arch/m68knommu/configs/m5208evb_defconfig +++ b/arch/m68k/configs/m5208evb_defconfig | |||
@@ -1,3 +1,4 @@ | |||
1 | # CONFIG_MMU is not set | ||
1 | CONFIG_EXPERIMENTAL=y | 2 | CONFIG_EXPERIMENTAL=y |
2 | CONFIG_LOG_BUF_SHIFT=14 | 3 | CONFIG_LOG_BUF_SHIFT=14 |
3 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 4 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -37,6 +38,7 @@ CONFIG_INET=y | |||
37 | # CONFIG_INET_LRO is not set | 38 | # CONFIG_INET_LRO is not set |
38 | # CONFIG_INET_DIAG is not set | 39 | # CONFIG_INET_DIAG is not set |
39 | # CONFIG_IPV6 is not set | 40 | # CONFIG_IPV6 is not set |
41 | # CONFIG_FW_LOADER is not set | ||
40 | CONFIG_MTD=y | 42 | CONFIG_MTD=y |
41 | CONFIG_MTD_PARTITIONS=y | 43 | CONFIG_MTD_PARTITIONS=y |
42 | CONFIG_MTD_CHAR=y | 44 | CONFIG_MTD_CHAR=y |
diff --git a/arch/m68knommu/configs/m5249evb_defconfig b/arch/m68k/configs/m5249evb_defconfig index 16df72bfbd45..a6599e42facf 100644 --- a/arch/m68knommu/configs/m5249evb_defconfig +++ b/arch/m68k/configs/m5249evb_defconfig | |||
@@ -1,3 +1,4 @@ | |||
1 | # CONFIG_MMU is not set | ||
1 | CONFIG_EXPERIMENTAL=y | 2 | CONFIG_EXPERIMENTAL=y |
2 | CONFIG_LOG_BUF_SHIFT=14 | 3 | CONFIG_LOG_BUF_SHIFT=14 |
3 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 4 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -35,6 +36,7 @@ CONFIG_INET=y | |||
35 | # CONFIG_INET_LRO is not set | 36 | # CONFIG_INET_LRO is not set |
36 | # CONFIG_INET_DIAG is not set | 37 | # CONFIG_INET_DIAG is not set |
37 | # CONFIG_IPV6 is not set | 38 | # CONFIG_IPV6 is not set |
39 | # CONFIG_FW_LOADER is not set | ||
38 | CONFIG_MTD=y | 40 | CONFIG_MTD=y |
39 | CONFIG_MTD_PARTITIONS=y | 41 | CONFIG_MTD_PARTITIONS=y |
40 | CONFIG_MTD_CHAR=y | 42 | CONFIG_MTD_CHAR=y |
diff --git a/arch/m68knommu/configs/m5272c3_defconfig b/arch/m68k/configs/m5272c3_defconfig index 4e6ea50c7f33..3fa60a57a0f9 100644 --- a/arch/m68knommu/configs/m5272c3_defconfig +++ b/arch/m68k/configs/m5272c3_defconfig | |||
@@ -1,3 +1,4 @@ | |||
1 | # CONFIG_MMU is not set | ||
1 | CONFIG_EXPERIMENTAL=y | 2 | CONFIG_EXPERIMENTAL=y |
2 | CONFIG_LOG_BUF_SHIFT=14 | 3 | CONFIG_LOG_BUF_SHIFT=14 |
3 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 4 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -33,6 +34,7 @@ CONFIG_INET=y | |||
33 | # CONFIG_INET_LRO is not set | 34 | # CONFIG_INET_LRO is not set |
34 | # CONFIG_INET_DIAG is not set | 35 | # CONFIG_INET_DIAG is not set |
35 | # CONFIG_IPV6 is not set | 36 | # CONFIG_IPV6 is not set |
37 | # CONFIG_FW_LOADER is not set | ||
36 | CONFIG_MTD=y | 38 | CONFIG_MTD=y |
37 | CONFIG_MTD_PARTITIONS=y | 39 | CONFIG_MTD_PARTITIONS=y |
38 | CONFIG_MTD_CHAR=y | 40 | CONFIG_MTD_CHAR=y |
diff --git a/arch/m68knommu/configs/m5275evb_defconfig b/arch/m68k/configs/m5275evb_defconfig index f3dd74115a34..33c32aeca12b 100644 --- a/arch/m68knommu/configs/m5275evb_defconfig +++ b/arch/m68k/configs/m5275evb_defconfig | |||
@@ -1,3 +1,4 @@ | |||
1 | # CONFIG_MMU is not set | ||
1 | CONFIG_EXPERIMENTAL=y | 2 | CONFIG_EXPERIMENTAL=y |
2 | CONFIG_LOG_BUF_SHIFT=14 | 3 | CONFIG_LOG_BUF_SHIFT=14 |
3 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 4 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -36,6 +37,7 @@ CONFIG_INET=y | |||
36 | # CONFIG_INET_LRO is not set | 37 | # CONFIG_INET_LRO is not set |
37 | # CONFIG_INET_DIAG is not set | 38 | # CONFIG_INET_DIAG is not set |
38 | # CONFIG_IPV6 is not set | 39 | # CONFIG_IPV6 is not set |
40 | # CONFIG_FW_LOADER is not set | ||
39 | CONFIG_MTD=y | 41 | CONFIG_MTD=y |
40 | CONFIG_MTD_PARTITIONS=y | 42 | CONFIG_MTD_PARTITIONS=y |
41 | CONFIG_MTD_CHAR=y | 43 | CONFIG_MTD_CHAR=y |
diff --git a/arch/m68knommu/configs/m5307c3_defconfig b/arch/m68k/configs/m5307c3_defconfig index bce0a20c3737..43795f41f7c7 100644 --- a/arch/m68knommu/configs/m5307c3_defconfig +++ b/arch/m68k/configs/m5307c3_defconfig | |||
@@ -1,3 +1,4 @@ | |||
1 | # CONFIG_MMU is not set | ||
1 | CONFIG_EXPERIMENTAL=y | 2 | CONFIG_EXPERIMENTAL=y |
2 | CONFIG_LOG_BUF_SHIFT=14 | 3 | CONFIG_LOG_BUF_SHIFT=14 |
3 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 4 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -35,6 +36,7 @@ CONFIG_INET=y | |||
35 | # CONFIG_INET_LRO is not set | 36 | # CONFIG_INET_LRO is not set |
36 | # CONFIG_INET_DIAG is not set | 37 | # CONFIG_INET_DIAG is not set |
37 | # CONFIG_IPV6 is not set | 38 | # CONFIG_IPV6 is not set |
39 | # CONFIG_FW_LOADER is not set | ||
38 | CONFIG_MTD=y | 40 | CONFIG_MTD=y |
39 | CONFIG_MTD_PARTITIONS=y | 41 | CONFIG_MTD_PARTITIONS=y |
40 | CONFIG_MTD_CHAR=y | 42 | CONFIG_MTD_CHAR=y |
diff --git a/arch/m68knommu/configs/m5407c3_defconfig b/arch/m68k/configs/m5407c3_defconfig index 618cc32691f2..72746c57a571 100644 --- a/arch/m68knommu/configs/m5407c3_defconfig +++ b/arch/m68k/configs/m5407c3_defconfig | |||
@@ -1,3 +1,4 @@ | |||
1 | # CONFIG_MMU is not set | ||
1 | CONFIG_EXPERIMENTAL=y | 2 | CONFIG_EXPERIMENTAL=y |
2 | CONFIG_LOG_BUF_SHIFT=14 | 3 | CONFIG_LOG_BUF_SHIFT=14 |
3 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 4 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -35,6 +36,7 @@ CONFIG_INET=y | |||
35 | # CONFIG_INET_LRO is not set | 36 | # CONFIG_INET_LRO is not set |
36 | # CONFIG_INET_DIAG is not set | 37 | # CONFIG_INET_DIAG is not set |
37 | # CONFIG_IPV6 is not set | 38 | # CONFIG_IPV6 is not set |
39 | # CONFIG_FW_LOADER is not set | ||
38 | CONFIG_MTD=y | 40 | CONFIG_MTD=y |
39 | CONFIG_MTD_PARTITIONS=y | 41 | CONFIG_MTD_PARTITIONS=y |
40 | CONFIG_MTD_CHAR=y | 42 | CONFIG_MTD_CHAR=y |
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 55d5d6b680a2..c482ebc9dd54 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile | |||
@@ -1,17 +1,5 @@ | |||
1 | # | 1 | ifdef CONFIG_MMU |
2 | # Makefile for the linux kernel. | 2 | include arch/m68k/kernel/Makefile_mm |
3 | # | ||
4 | |||
5 | ifndef CONFIG_SUN3 | ||
6 | extra-y := head.o | ||
7 | else | 3 | else |
8 | extra-y := sun3-head.o | 4 | include arch/m68k/kernel/Makefile_no |
9 | endif | 5 | endif |
10 | extra-y += vmlinux.lds | ||
11 | |||
12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ | ||
13 | sys_m68k.o time.o setup.o m68k_ksyms.o devres.o | ||
14 | |||
15 | devres-y = ../../../kernel/irq/devres.o | ||
16 | |||
17 | obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo | ||
diff --git a/arch/m68k/kernel/Makefile_mm b/arch/m68k/kernel/Makefile_mm new file mode 100644 index 000000000000..55d5d6b680a2 --- /dev/null +++ b/arch/m68k/kernel/Makefile_mm | |||
@@ -0,0 +1,17 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel. | ||
3 | # | ||
4 | |||
5 | ifndef CONFIG_SUN3 | ||
6 | extra-y := head.o | ||
7 | else | ||
8 | extra-y := sun3-head.o | ||
9 | endif | ||
10 | extra-y += vmlinux.lds | ||
11 | |||
12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ | ||
13 | sys_m68k.o time.o setup.o m68k_ksyms.o devres.o | ||
14 | |||
15 | devres-y = ../../../kernel/irq/devres.o | ||
16 | |||
17 | obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo | ||
diff --git a/arch/m68knommu/kernel/Makefile b/arch/m68k/kernel/Makefile_no index 37c3fc074c0a..37c3fc074c0a 100644 --- a/arch/m68knommu/kernel/Makefile +++ b/arch/m68k/kernel/Makefile_no | |||
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c index 78e59b82ebc3..59a69a5c62f2 100644 --- a/arch/m68k/kernel/asm-offsets.c +++ b/arch/m68k/kernel/asm-offsets.c | |||
@@ -1,100 +1,5 @@ | |||
1 | /* | ||
2 | * This program is used to generate definitions needed by | ||
3 | * assembly language modules. | ||
4 | * | ||
5 | * We use the technique used in the OSF Mach kernel code: | ||
6 | * generate asm statements containing #defines, | ||
7 | * compile this file to assembler, and then extract the | ||
8 | * #defines from the assembly-language output. | ||
9 | */ | ||
10 | |||
11 | #define ASM_OFFSETS_C | ||
12 | |||
13 | #include <linux/stddef.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/kernel_stat.h> | ||
16 | #include <linux/kbuild.h> | ||
17 | #include <asm/bootinfo.h> | ||
18 | #include <asm/irq.h> | ||
19 | #include <asm/amigahw.h> | ||
20 | #include <linux/font.h> | ||
21 | |||
22 | int main(void) | ||
23 | { | ||
24 | /* offsets into the task struct */ | ||
25 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); | ||
26 | DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); | ||
27 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); | ||
28 | #ifdef CONFIG_MMU | 1 | #ifdef CONFIG_MMU |
29 | DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); | 2 | #include "asm-offsets_mm.c" |
3 | #else | ||
4 | #include "asm-offsets_no.c" | ||
30 | #endif | 5 | #endif |
31 | |||
32 | /* offsets into the thread struct */ | ||
33 | DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); | ||
34 | DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); | ||
35 | DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); | ||
36 | DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); | ||
37 | DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); | ||
38 | DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); | ||
39 | DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); | ||
40 | DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); | ||
41 | DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); | ||
42 | |||
43 | /* offsets into the thread_info struct */ | ||
44 | DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); | ||
45 | DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); | ||
46 | |||
47 | /* offsets into the pt_regs */ | ||
48 | DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); | ||
49 | DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); | ||
50 | DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); | ||
51 | DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); | ||
52 | DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); | ||
53 | DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); | ||
54 | DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); | ||
55 | DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); | ||
56 | DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); | ||
57 | DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); | ||
58 | DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); | ||
59 | DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); | ||
60 | /* bitfields are a bit difficult */ | ||
61 | DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); | ||
62 | |||
63 | /* offsets into the irq_cpustat_t struct */ | ||
64 | DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); | ||
65 | |||
66 | /* offsets into the bi_record struct */ | ||
67 | DEFINE(BIR_TAG, offsetof(struct bi_record, tag)); | ||
68 | DEFINE(BIR_SIZE, offsetof(struct bi_record, size)); | ||
69 | DEFINE(BIR_DATA, offsetof(struct bi_record, data)); | ||
70 | |||
71 | /* offsets into font_desc (drivers/video/console/font.h) */ | ||
72 | DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx)); | ||
73 | DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name)); | ||
74 | DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width)); | ||
75 | DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height)); | ||
76 | DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data)); | ||
77 | DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); | ||
78 | |||
79 | /* signal defines */ | ||
80 | DEFINE(LSIGSEGV, SIGSEGV); | ||
81 | DEFINE(LSEGV_MAPERR, SEGV_MAPERR); | ||
82 | DEFINE(LSIGTRAP, SIGTRAP); | ||
83 | DEFINE(LTRAP_TRACE, TRAP_TRACE); | ||
84 | |||
85 | /* offsets into the custom struct */ | ||
86 | DEFINE(CUSTOMBASE, &amiga_custom); | ||
87 | DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar)); | ||
88 | DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr)); | ||
89 | DEFINE(C_INTENA, offsetof(struct CUSTOM, intena)); | ||
90 | DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq)); | ||
91 | DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr)); | ||
92 | DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat)); | ||
93 | DEFINE(C_SERPER, offsetof(struct CUSTOM, serper)); | ||
94 | DEFINE(CIAABASE, &ciaa); | ||
95 | DEFINE(CIABBASE, &ciab); | ||
96 | DEFINE(C_PRA, offsetof(struct CIA, pra)); | ||
97 | DEFINE(ZTWOBASE, zTwoBase); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
diff --git a/arch/m68k/kernel/asm-offsets_mm.c b/arch/m68k/kernel/asm-offsets_mm.c new file mode 100644 index 000000000000..78e59b82ebc3 --- /dev/null +++ b/arch/m68k/kernel/asm-offsets_mm.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * This program is used to generate definitions needed by | ||
3 | * assembly language modules. | ||
4 | * | ||
5 | * We use the technique used in the OSF Mach kernel code: | ||
6 | * generate asm statements containing #defines, | ||
7 | * compile this file to assembler, and then extract the | ||
8 | * #defines from the assembly-language output. | ||
9 | */ | ||
10 | |||
11 | #define ASM_OFFSETS_C | ||
12 | |||
13 | #include <linux/stddef.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/kernel_stat.h> | ||
16 | #include <linux/kbuild.h> | ||
17 | #include <asm/bootinfo.h> | ||
18 | #include <asm/irq.h> | ||
19 | #include <asm/amigahw.h> | ||
20 | #include <linux/font.h> | ||
21 | |||
22 | int main(void) | ||
23 | { | ||
24 | /* offsets into the task struct */ | ||
25 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); | ||
26 | DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); | ||
27 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); | ||
28 | #ifdef CONFIG_MMU | ||
29 | DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); | ||
30 | #endif | ||
31 | |||
32 | /* offsets into the thread struct */ | ||
33 | DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); | ||
34 | DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); | ||
35 | DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); | ||
36 | DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); | ||
37 | DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); | ||
38 | DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); | ||
39 | DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); | ||
40 | DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); | ||
41 | DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); | ||
42 | |||
43 | /* offsets into the thread_info struct */ | ||
44 | DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); | ||
45 | DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); | ||
46 | |||
47 | /* offsets into the pt_regs */ | ||
48 | DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); | ||
49 | DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); | ||
50 | DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); | ||
51 | DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); | ||
52 | DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); | ||
53 | DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); | ||
54 | DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); | ||
55 | DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); | ||
56 | DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); | ||
57 | DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); | ||
58 | DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); | ||
59 | DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); | ||
60 | /* bitfields are a bit difficult */ | ||
61 | DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); | ||
62 | |||
63 | /* offsets into the irq_cpustat_t struct */ | ||
64 | DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); | ||
65 | |||
66 | /* offsets into the bi_record struct */ | ||
67 | DEFINE(BIR_TAG, offsetof(struct bi_record, tag)); | ||
68 | DEFINE(BIR_SIZE, offsetof(struct bi_record, size)); | ||
69 | DEFINE(BIR_DATA, offsetof(struct bi_record, data)); | ||
70 | |||
71 | /* offsets into font_desc (drivers/video/console/font.h) */ | ||
72 | DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx)); | ||
73 | DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name)); | ||
74 | DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width)); | ||
75 | DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height)); | ||
76 | DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data)); | ||
77 | DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); | ||
78 | |||
79 | /* signal defines */ | ||
80 | DEFINE(LSIGSEGV, SIGSEGV); | ||
81 | DEFINE(LSEGV_MAPERR, SEGV_MAPERR); | ||
82 | DEFINE(LSIGTRAP, SIGTRAP); | ||
83 | DEFINE(LTRAP_TRACE, TRAP_TRACE); | ||
84 | |||
85 | /* offsets into the custom struct */ | ||
86 | DEFINE(CUSTOMBASE, &amiga_custom); | ||
87 | DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar)); | ||
88 | DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr)); | ||
89 | DEFINE(C_INTENA, offsetof(struct CUSTOM, intena)); | ||
90 | DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq)); | ||
91 | DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr)); | ||
92 | DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat)); | ||
93 | DEFINE(C_SERPER, offsetof(struct CUSTOM, serper)); | ||
94 | DEFINE(CIAABASE, &ciaa); | ||
95 | DEFINE(CIABBASE, &ciab); | ||
96 | DEFINE(C_PRA, offsetof(struct CIA, pra)); | ||
97 | DEFINE(ZTWOBASE, zTwoBase); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets_no.c index ffe02f41ad46..ffe02f41ad46 100644 --- a/arch/m68knommu/kernel/asm-offsets.c +++ b/arch/m68k/kernel/asm-offsets_no.c | |||
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c index 4bbb3c2a8880..90e8cb726c8c 100644 --- a/arch/m68k/kernel/dma.c +++ b/arch/m68k/kernel/dma.c | |||
@@ -1,130 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * This file is subject to the terms and conditions of the GNU General Public | 2 | #include "dma_mm.c" |
3 | * License. See the file COPYING in the main directory of this archive | 3 | #else |
4 | * for more details. | 4 | #include "dma_no.c" |
5 | */ | 5 | #endif |
6 | |||
7 | #undef DEBUG | ||
8 | |||
9 | #include <linux/dma-mapping.h> | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/scatterlist.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/vmalloc.h> | ||
15 | |||
16 | #include <asm/pgalloc.h> | ||
17 | |||
18 | void *dma_alloc_coherent(struct device *dev, size_t size, | ||
19 | dma_addr_t *handle, gfp_t flag) | ||
20 | { | ||
21 | struct page *page, **map; | ||
22 | pgprot_t pgprot; | ||
23 | void *addr; | ||
24 | int i, order; | ||
25 | |||
26 | pr_debug("dma_alloc_coherent: %d,%x\n", size, flag); | ||
27 | |||
28 | size = PAGE_ALIGN(size); | ||
29 | order = get_order(size); | ||
30 | |||
31 | page = alloc_pages(flag, order); | ||
32 | if (!page) | ||
33 | return NULL; | ||
34 | |||
35 | *handle = page_to_phys(page); | ||
36 | map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA); | ||
37 | if (!map) { | ||
38 | __free_pages(page, order); | ||
39 | return NULL; | ||
40 | } | ||
41 | split_page(page, order); | ||
42 | |||
43 | order = 1 << order; | ||
44 | size >>= PAGE_SHIFT; | ||
45 | map[0] = page; | ||
46 | for (i = 1; i < size; i++) | ||
47 | map[i] = page + i; | ||
48 | for (; i < order; i++) | ||
49 | __free_page(page + i); | ||
50 | pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); | ||
51 | if (CPU_IS_040_OR_060) | ||
52 | pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; | ||
53 | else | ||
54 | pgprot_val(pgprot) |= _PAGE_NOCACHE030; | ||
55 | addr = vmap(map, size, VM_MAP, pgprot); | ||
56 | kfree(map); | ||
57 | |||
58 | return addr; | ||
59 | } | ||
60 | EXPORT_SYMBOL(dma_alloc_coherent); | ||
61 | |||
62 | void dma_free_coherent(struct device *dev, size_t size, | ||
63 | void *addr, dma_addr_t handle) | ||
64 | { | ||
65 | pr_debug("dma_free_coherent: %p, %x\n", addr, handle); | ||
66 | vfree(addr); | ||
67 | } | ||
68 | EXPORT_SYMBOL(dma_free_coherent); | ||
69 | |||
70 | void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, | ||
71 | size_t size, enum dma_data_direction dir) | ||
72 | { | ||
73 | switch (dir) { | ||
74 | case DMA_TO_DEVICE: | ||
75 | cache_push(handle, size); | ||
76 | break; | ||
77 | case DMA_FROM_DEVICE: | ||
78 | cache_clear(handle, size); | ||
79 | break; | ||
80 | default: | ||
81 | if (printk_ratelimit()) | ||
82 | printk("dma_sync_single_for_device: unsupported dir %u\n", dir); | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | EXPORT_SYMBOL(dma_sync_single_for_device); | ||
87 | |||
88 | void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, | ||
89 | enum dma_data_direction dir) | ||
90 | { | ||
91 | int i; | ||
92 | |||
93 | for (i = 0; i < nents; sg++, i++) | ||
94 | dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); | ||
95 | } | ||
96 | EXPORT_SYMBOL(dma_sync_sg_for_device); | ||
97 | |||
98 | dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, | ||
99 | enum dma_data_direction dir) | ||
100 | { | ||
101 | dma_addr_t handle = virt_to_bus(addr); | ||
102 | |||
103 | dma_sync_single_for_device(dev, handle, size, dir); | ||
104 | return handle; | ||
105 | } | ||
106 | EXPORT_SYMBOL(dma_map_single); | ||
107 | |||
108 | dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
109 | unsigned long offset, size_t size, | ||
110 | enum dma_data_direction dir) | ||
111 | { | ||
112 | dma_addr_t handle = page_to_phys(page) + offset; | ||
113 | |||
114 | dma_sync_single_for_device(dev, handle, size, dir); | ||
115 | return handle; | ||
116 | } | ||
117 | EXPORT_SYMBOL(dma_map_page); | ||
118 | |||
119 | int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
120 | enum dma_data_direction dir) | ||
121 | { | ||
122 | int i; | ||
123 | |||
124 | for (i = 0; i < nents; sg++, i++) { | ||
125 | sg->dma_address = sg_phys(sg); | ||
126 | dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); | ||
127 | } | ||
128 | return nents; | ||
129 | } | ||
130 | EXPORT_SYMBOL(dma_map_sg); | ||
diff --git a/arch/m68k/kernel/dma_mm.c b/arch/m68k/kernel/dma_mm.c new file mode 100644 index 000000000000..4bbb3c2a8880 --- /dev/null +++ b/arch/m68k/kernel/dma_mm.c | |||
@@ -0,0 +1,130 @@ | |||
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 | |||
7 | #undef DEBUG | ||
8 | |||
9 | #include <linux/dma-mapping.h> | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/scatterlist.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/vmalloc.h> | ||
15 | |||
16 | #include <asm/pgalloc.h> | ||
17 | |||
18 | void *dma_alloc_coherent(struct device *dev, size_t size, | ||
19 | dma_addr_t *handle, gfp_t flag) | ||
20 | { | ||
21 | struct page *page, **map; | ||
22 | pgprot_t pgprot; | ||
23 | void *addr; | ||
24 | int i, order; | ||
25 | |||
26 | pr_debug("dma_alloc_coherent: %d,%x\n", size, flag); | ||
27 | |||
28 | size = PAGE_ALIGN(size); | ||
29 | order = get_order(size); | ||
30 | |||
31 | page = alloc_pages(flag, order); | ||
32 | if (!page) | ||
33 | return NULL; | ||
34 | |||
35 | *handle = page_to_phys(page); | ||
36 | map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA); | ||
37 | if (!map) { | ||
38 | __free_pages(page, order); | ||
39 | return NULL; | ||
40 | } | ||
41 | split_page(page, order); | ||
42 | |||
43 | order = 1 << order; | ||
44 | size >>= PAGE_SHIFT; | ||
45 | map[0] = page; | ||
46 | for (i = 1; i < size; i++) | ||
47 | map[i] = page + i; | ||
48 | for (; i < order; i++) | ||
49 | __free_page(page + i); | ||
50 | pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); | ||
51 | if (CPU_IS_040_OR_060) | ||
52 | pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; | ||
53 | else | ||
54 | pgprot_val(pgprot) |= _PAGE_NOCACHE030; | ||
55 | addr = vmap(map, size, VM_MAP, pgprot); | ||
56 | kfree(map); | ||
57 | |||
58 | return addr; | ||
59 | } | ||
60 | EXPORT_SYMBOL(dma_alloc_coherent); | ||
61 | |||
62 | void dma_free_coherent(struct device *dev, size_t size, | ||
63 | void *addr, dma_addr_t handle) | ||
64 | { | ||
65 | pr_debug("dma_free_coherent: %p, %x\n", addr, handle); | ||
66 | vfree(addr); | ||
67 | } | ||
68 | EXPORT_SYMBOL(dma_free_coherent); | ||
69 | |||
70 | void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, | ||
71 | size_t size, enum dma_data_direction dir) | ||
72 | { | ||
73 | switch (dir) { | ||
74 | case DMA_TO_DEVICE: | ||
75 | cache_push(handle, size); | ||
76 | break; | ||
77 | case DMA_FROM_DEVICE: | ||
78 | cache_clear(handle, size); | ||
79 | break; | ||
80 | default: | ||
81 | if (printk_ratelimit()) | ||
82 | printk("dma_sync_single_for_device: unsupported dir %u\n", dir); | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | EXPORT_SYMBOL(dma_sync_single_for_device); | ||
87 | |||
88 | void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, | ||
89 | enum dma_data_direction dir) | ||
90 | { | ||
91 | int i; | ||
92 | |||
93 | for (i = 0; i < nents; sg++, i++) | ||
94 | dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); | ||
95 | } | ||
96 | EXPORT_SYMBOL(dma_sync_sg_for_device); | ||
97 | |||
98 | dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, | ||
99 | enum dma_data_direction dir) | ||
100 | { | ||
101 | dma_addr_t handle = virt_to_bus(addr); | ||
102 | |||
103 | dma_sync_single_for_device(dev, handle, size, dir); | ||
104 | return handle; | ||
105 | } | ||
106 | EXPORT_SYMBOL(dma_map_single); | ||
107 | |||
108 | dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
109 | unsigned long offset, size_t size, | ||
110 | enum dma_data_direction dir) | ||
111 | { | ||
112 | dma_addr_t handle = page_to_phys(page) + offset; | ||
113 | |||
114 | dma_sync_single_for_device(dev, handle, size, dir); | ||
115 | return handle; | ||
116 | } | ||
117 | EXPORT_SYMBOL(dma_map_page); | ||
118 | |||
119 | int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
120 | enum dma_data_direction dir) | ||
121 | { | ||
122 | int i; | ||
123 | |||
124 | for (i = 0; i < nents; sg++, i++) { | ||
125 | sg->dma_address = sg_phys(sg); | ||
126 | dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); | ||
127 | } | ||
128 | return nents; | ||
129 | } | ||
130 | EXPORT_SYMBOL(dma_map_sg); | ||
diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68k/kernel/dma_no.c index fc61541aeb71..fc61541aeb71 100644 --- a/arch/m68knommu/kernel/dma.c +++ b/arch/m68k/kernel/dma_no.c | |||
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 1559dea36e55..081cf96f243b 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S | |||
@@ -1,753 +1,5 @@ | |||
1 | /* -*- mode: asm -*- | 1 | #ifdef CONFIG_MMU |
2 | * | 2 | #include "entry_mm.S" |
3 | * linux/arch/m68k/kernel/entry.S | 3 | #else |
4 | * | 4 | #include "entry_no.S" |
5 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License. See the file README.legal in the main directory of this archive | ||
9 | * for more details. | ||
10 | * | ||
11 | * Linux/m68k support by Hamish Macdonald | ||
12 | * | ||
13 | * 68060 fixes by Jesper Skov | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * entry.S contains the system-call and fault low-level handling routines. | ||
19 | * This also contains the timer-interrupt handler, as well as all interrupts | ||
20 | * and faults that can result in a task-switch. | ||
21 | * | ||
22 | * NOTE: This code handles signal-recognition, which happens every time | ||
23 | * after a timer-interrupt and after each system call. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so | ||
29 | * all pointers that used to be 'current' are now entry | ||
30 | * number 0 in the 'current_set' list. | ||
31 | * | ||
32 | * 6/05/00 RZ: addedd writeback completion after return from sighandler | ||
33 | * for 68040 | ||
34 | */ | ||
35 | |||
36 | #include <linux/linkage.h> | ||
37 | #include <asm/entry.h> | ||
38 | #include <asm/errno.h> | ||
39 | #include <asm/setup.h> | ||
40 | #include <asm/segment.h> | ||
41 | #include <asm/traps.h> | ||
42 | #include <asm/unistd.h> | ||
43 | |||
44 | #include <asm/asm-offsets.h> | ||
45 | |||
46 | .globl system_call, buserr, trap, resume | ||
47 | .globl sys_call_table | ||
48 | .globl sys_fork, sys_clone, sys_vfork | ||
49 | .globl ret_from_interrupt, bad_interrupt | ||
50 | .globl auto_irqhandler_fixup | ||
51 | .globl user_irqvec_fixup, user_irqhandler_fixup | ||
52 | |||
53 | .text | ||
54 | ENTRY(buserr) | ||
55 | SAVE_ALL_INT | ||
56 | GET_CURRENT(%d0) | ||
57 | movel %sp,%sp@- | stack frame pointer argument | ||
58 | bsrl buserr_c | ||
59 | addql #4,%sp | ||
60 | jra .Lret_from_exception | ||
61 | |||
62 | ENTRY(trap) | ||
63 | SAVE_ALL_INT | ||
64 | GET_CURRENT(%d0) | ||
65 | movel %sp,%sp@- | stack frame pointer argument | ||
66 | bsrl trap_c | ||
67 | addql #4,%sp | ||
68 | jra .Lret_from_exception | ||
69 | |||
70 | | After a fork we jump here directly from resume, | ||
71 | | so that %d1 contains the previous task | ||
72 | | schedule_tail now used regardless of CONFIG_SMP | ||
73 | ENTRY(ret_from_fork) | ||
74 | movel %d1,%sp@- | ||
75 | jsr schedule_tail | ||
76 | addql #4,%sp | ||
77 | jra .Lret_from_exception | ||
78 | |||
79 | do_trace_entry: | ||
80 | movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace | ||
81 | subql #4,%sp | ||
82 | SAVE_SWITCH_STACK | ||
83 | jbsr syscall_trace | ||
84 | RESTORE_SWITCH_STACK | ||
85 | addql #4,%sp | ||
86 | movel %sp@(PT_OFF_ORIG_D0),%d0 | ||
87 | cmpl #NR_syscalls,%d0 | ||
88 | jcs syscall | ||
89 | badsys: | ||
90 | movel #-ENOSYS,%sp@(PT_OFF_D0) | ||
91 | jra ret_from_syscall | ||
92 | |||
93 | do_trace_exit: | ||
94 | subql #4,%sp | ||
95 | SAVE_SWITCH_STACK | ||
96 | jbsr syscall_trace | ||
97 | RESTORE_SWITCH_STACK | ||
98 | addql #4,%sp | ||
99 | jra .Lret_from_exception | ||
100 | |||
101 | ENTRY(ret_from_signal) | ||
102 | tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) | ||
103 | jge 1f | ||
104 | jbsr syscall_trace | ||
105 | 1: RESTORE_SWITCH_STACK | ||
106 | addql #4,%sp | ||
107 | /* on 68040 complete pending writebacks if any */ | ||
108 | #ifdef CONFIG_M68040 | ||
109 | bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0 | ||
110 | subql #7,%d0 | bus error frame ? | ||
111 | jbne 1f | ||
112 | movel %sp,%sp@- | ||
113 | jbsr berr_040cleanup | ||
114 | addql #4,%sp | ||
115 | 1: | ||
116 | #endif | 5 | #endif |
117 | jra .Lret_from_exception | ||
118 | |||
119 | ENTRY(system_call) | ||
120 | SAVE_ALL_SYS | ||
121 | |||
122 | GET_CURRENT(%d1) | ||
123 | | save top of frame | ||
124 | movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) | ||
125 | |||
126 | | syscall trace? | ||
127 | tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) | ||
128 | jmi do_trace_entry | ||
129 | cmpl #NR_syscalls,%d0 | ||
130 | jcc badsys | ||
131 | syscall: | ||
132 | jbsr @(sys_call_table,%d0:l:4)@(0) | ||
133 | movel %d0,%sp@(PT_OFF_D0) | save the return value | ||
134 | ret_from_syscall: | ||
135 | |oriw #0x0700,%sr | ||
136 | movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 | ||
137 | jne syscall_exit_work | ||
138 | 1: RESTORE_ALL | ||
139 | |||
140 | syscall_exit_work: | ||
141 | btst #5,%sp@(PT_OFF_SR) | check if returning to kernel | ||
142 | bnes 1b | if so, skip resched, signals | ||
143 | lslw #1,%d0 | ||
144 | jcs do_trace_exit | ||
145 | jmi do_delayed_trace | ||
146 | lslw #8,%d0 | ||
147 | jmi do_signal_return | ||
148 | pea resume_userspace | ||
149 | jra schedule | ||
150 | |||
151 | |||
152 | ENTRY(ret_from_exception) | ||
153 | .Lret_from_exception: | ||
154 | btst #5,%sp@(PT_OFF_SR) | check if returning to kernel | ||
155 | bnes 1f | if so, skip resched, signals | ||
156 | | only allow interrupts when we are really the last one on the | ||
157 | | kernel stack, otherwise stack overflow can occur during | ||
158 | | heavy interrupt load | ||
159 | andw #ALLOWINT,%sr | ||
160 | |||
161 | resume_userspace: | ||
162 | moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0 | ||
163 | jne exit_work | ||
164 | 1: RESTORE_ALL | ||
165 | |||
166 | exit_work: | ||
167 | | save top of frame | ||
168 | movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) | ||
169 | lslb #1,%d0 | ||
170 | jmi do_signal_return | ||
171 | pea resume_userspace | ||
172 | jra schedule | ||
173 | |||
174 | |||
175 | do_signal_return: | ||
176 | |andw #ALLOWINT,%sr | ||
177 | subql #4,%sp | dummy return address | ||
178 | SAVE_SWITCH_STACK | ||
179 | pea %sp@(SWITCH_STACK_SIZE) | ||
180 | bsrl do_signal | ||
181 | addql #4,%sp | ||
182 | RESTORE_SWITCH_STACK | ||
183 | addql #4,%sp | ||
184 | jbra resume_userspace | ||
185 | |||
186 | do_delayed_trace: | ||
187 | bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR | ||
188 | pea 1 | send SIGTRAP | ||
189 | movel %curptr,%sp@- | ||
190 | pea LSIGTRAP | ||
191 | jbsr send_sig | ||
192 | addql #8,%sp | ||
193 | addql #4,%sp | ||
194 | jbra resume_userspace | ||
195 | |||
196 | |||
197 | /* This is the main interrupt handler for autovector interrupts */ | ||
198 | |||
199 | ENTRY(auto_inthandler) | ||
200 | SAVE_ALL_INT | ||
201 | GET_CURRENT(%d0) | ||
202 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
203 | | put exception # in d0 | ||
204 | bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 | ||
205 | subw #VEC_SPUR,%d0 | ||
206 | |||
207 | movel %sp,%sp@- | ||
208 | movel %d0,%sp@- | put vector # on stack | ||
209 | auto_irqhandler_fixup = . + 2 | ||
210 | jsr __m68k_handle_int | process the IRQ | ||
211 | addql #8,%sp | pop parameters off stack | ||
212 | |||
213 | ret_from_interrupt: | ||
214 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
215 | jeq ret_from_last_interrupt | ||
216 | 2: RESTORE_ALL | ||
217 | |||
218 | ALIGN | ||
219 | ret_from_last_interrupt: | ||
220 | moveq #(~ALLOWINT>>8)&0xff,%d0 | ||
221 | andb %sp@(PT_OFF_SR),%d0 | ||
222 | jne 2b | ||
223 | |||
224 | /* check if we need to do software interrupts */ | ||
225 | tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING | ||
226 | jeq .Lret_from_exception | ||
227 | pea ret_from_exception | ||
228 | jra do_softirq | ||
229 | |||
230 | /* Handler for user defined interrupt vectors */ | ||
231 | |||
232 | ENTRY(user_inthandler) | ||
233 | SAVE_ALL_INT | ||
234 | GET_CURRENT(%d0) | ||
235 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
236 | | put exception # in d0 | ||
237 | bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 | ||
238 | user_irqvec_fixup = . + 2 | ||
239 | subw #VEC_USER,%d0 | ||
240 | |||
241 | movel %sp,%sp@- | ||
242 | movel %d0,%sp@- | put vector # on stack | ||
243 | user_irqhandler_fixup = . + 2 | ||
244 | jsr __m68k_handle_int | process the IRQ | ||
245 | addql #8,%sp | pop parameters off stack | ||
246 | |||
247 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
248 | jeq ret_from_last_interrupt | ||
249 | RESTORE_ALL | ||
250 | |||
251 | /* Handler for uninitialized and spurious interrupts */ | ||
252 | |||
253 | ENTRY(bad_inthandler) | ||
254 | SAVE_ALL_INT | ||
255 | GET_CURRENT(%d0) | ||
256 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
257 | |||
258 | movel %sp,%sp@- | ||
259 | jsr handle_badint | ||
260 | addql #4,%sp | ||
261 | |||
262 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
263 | jeq ret_from_last_interrupt | ||
264 | RESTORE_ALL | ||
265 | |||
266 | |||
267 | ENTRY(sys_fork) | ||
268 | SAVE_SWITCH_STACK | ||
269 | pea %sp@(SWITCH_STACK_SIZE) | ||
270 | jbsr m68k_fork | ||
271 | addql #4,%sp | ||
272 | RESTORE_SWITCH_STACK | ||
273 | rts | ||
274 | |||
275 | ENTRY(sys_clone) | ||
276 | SAVE_SWITCH_STACK | ||
277 | pea %sp@(SWITCH_STACK_SIZE) | ||
278 | jbsr m68k_clone | ||
279 | addql #4,%sp | ||
280 | RESTORE_SWITCH_STACK | ||
281 | rts | ||
282 | |||
283 | ENTRY(sys_vfork) | ||
284 | SAVE_SWITCH_STACK | ||
285 | pea %sp@(SWITCH_STACK_SIZE) | ||
286 | jbsr m68k_vfork | ||
287 | addql #4,%sp | ||
288 | RESTORE_SWITCH_STACK | ||
289 | rts | ||
290 | |||
291 | ENTRY(sys_sigreturn) | ||
292 | SAVE_SWITCH_STACK | ||
293 | jbsr do_sigreturn | ||
294 | RESTORE_SWITCH_STACK | ||
295 | rts | ||
296 | |||
297 | ENTRY(sys_rt_sigreturn) | ||
298 | SAVE_SWITCH_STACK | ||
299 | jbsr do_rt_sigreturn | ||
300 | RESTORE_SWITCH_STACK | ||
301 | rts | ||
302 | |||
303 | resume: | ||
304 | /* | ||
305 | * Beware - when entering resume, prev (the current task) is | ||
306 | * in a0, next (the new task) is in a1,so don't change these | ||
307 | * registers until their contents are no longer needed. | ||
308 | */ | ||
309 | |||
310 | /* save sr */ | ||
311 | movew %sr,%a0@(TASK_THREAD+THREAD_SR) | ||
312 | |||
313 | /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ | ||
314 | movec %sfc,%d0 | ||
315 | movew %d0,%a0@(TASK_THREAD+THREAD_FS) | ||
316 | |||
317 | /* save usp */ | ||
318 | /* it is better to use a movel here instead of a movew 8*) */ | ||
319 | movec %usp,%d0 | ||
320 | movel %d0,%a0@(TASK_THREAD+THREAD_USP) | ||
321 | |||
322 | /* save non-scratch registers on stack */ | ||
323 | SAVE_SWITCH_STACK | ||
324 | |||
325 | /* save current kernel stack pointer */ | ||
326 | movel %sp,%a0@(TASK_THREAD+THREAD_KSP) | ||
327 | |||
328 | /* save floating point context */ | ||
329 | #ifndef CONFIG_M68KFPU_EMU_ONLY | ||
330 | #ifdef CONFIG_M68KFPU_EMU | ||
331 | tstl m68k_fputype | ||
332 | jeq 3f | ||
333 | #endif | ||
334 | fsave %a0@(TASK_THREAD+THREAD_FPSTATE) | ||
335 | |||
336 | #if defined(CONFIG_M68060) | ||
337 | #if !defined(CPU_M68060_ONLY) | ||
338 | btst #3,m68k_cputype+3 | ||
339 | beqs 1f | ||
340 | #endif | ||
341 | /* The 060 FPU keeps status in bits 15-8 of the first longword */ | ||
342 | tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2) | ||
343 | jeq 3f | ||
344 | #if !defined(CPU_M68060_ONLY) | ||
345 | jra 2f | ||
346 | #endif | ||
347 | #endif /* CONFIG_M68060 */ | ||
348 | #if !defined(CPU_M68060_ONLY) | ||
349 | 1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE) | ||
350 | jeq 3f | ||
351 | #endif | ||
352 | 2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) | ||
353 | fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) | ||
354 | 3: | ||
355 | #endif /* CONFIG_M68KFPU_EMU_ONLY */ | ||
356 | /* Return previous task in %d1 */ | ||
357 | movel %curptr,%d1 | ||
358 | |||
359 | /* switch to new task (a1 contains new task) */ | ||
360 | movel %a1,%curptr | ||
361 | |||
362 | /* restore floating point context */ | ||
363 | #ifndef CONFIG_M68KFPU_EMU_ONLY | ||
364 | #ifdef CONFIG_M68KFPU_EMU | ||
365 | tstl m68k_fputype | ||
366 | jeq 4f | ||
367 | #endif | ||
368 | #if defined(CONFIG_M68060) | ||
369 | #if !defined(CPU_M68060_ONLY) | ||
370 | btst #3,m68k_cputype+3 | ||
371 | beqs 1f | ||
372 | #endif | ||
373 | /* The 060 FPU keeps status in bits 15-8 of the first longword */ | ||
374 | tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2) | ||
375 | jeq 3f | ||
376 | #if !defined(CPU_M68060_ONLY) | ||
377 | jra 2f | ||
378 | #endif | ||
379 | #endif /* CONFIG_M68060 */ | ||
380 | #if !defined(CPU_M68060_ONLY) | ||
381 | 1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE) | ||
382 | jeq 3f | ||
383 | #endif | ||
384 | 2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 | ||
385 | fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar | ||
386 | 3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) | ||
387 | 4: | ||
388 | #endif /* CONFIG_M68KFPU_EMU_ONLY */ | ||
389 | |||
390 | /* restore the kernel stack pointer */ | ||
391 | movel %a1@(TASK_THREAD+THREAD_KSP),%sp | ||
392 | |||
393 | /* restore non-scratch registers */ | ||
394 | RESTORE_SWITCH_STACK | ||
395 | |||
396 | /* restore user stack pointer */ | ||
397 | movel %a1@(TASK_THREAD+THREAD_USP),%a0 | ||
398 | movel %a0,%usp | ||
399 | |||
400 | /* restore fs (sfc,%dfc) */ | ||
401 | movew %a1@(TASK_THREAD+THREAD_FS),%a0 | ||
402 | movec %a0,%sfc | ||
403 | movec %a0,%dfc | ||
404 | |||
405 | /* restore status register */ | ||
406 | movew %a1@(TASK_THREAD+THREAD_SR),%sr | ||
407 | |||
408 | rts | ||
409 | |||
410 | .data | ||
411 | ALIGN | ||
412 | sys_call_table: | ||
413 | .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ | ||
414 | .long sys_exit | ||
415 | .long sys_fork | ||
416 | .long sys_read | ||
417 | .long sys_write | ||
418 | .long sys_open /* 5 */ | ||
419 | .long sys_close | ||
420 | .long sys_waitpid | ||
421 | .long sys_creat | ||
422 | .long sys_link | ||
423 | .long sys_unlink /* 10 */ | ||
424 | .long sys_execve | ||
425 | .long sys_chdir | ||
426 | .long sys_time | ||
427 | .long sys_mknod | ||
428 | .long sys_chmod /* 15 */ | ||
429 | .long sys_chown16 | ||
430 | .long sys_ni_syscall /* old break syscall holder */ | ||
431 | .long sys_stat | ||
432 | .long sys_lseek | ||
433 | .long sys_getpid /* 20 */ | ||
434 | .long sys_mount | ||
435 | .long sys_oldumount | ||
436 | .long sys_setuid16 | ||
437 | .long sys_getuid16 | ||
438 | .long sys_stime /* 25 */ | ||
439 | .long sys_ptrace | ||
440 | .long sys_alarm | ||
441 | .long sys_fstat | ||
442 | .long sys_pause | ||
443 | .long sys_utime /* 30 */ | ||
444 | .long sys_ni_syscall /* old stty syscall holder */ | ||
445 | .long sys_ni_syscall /* old gtty syscall holder */ | ||
446 | .long sys_access | ||
447 | .long sys_nice | ||
448 | .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ | ||
449 | .long sys_sync | ||
450 | .long sys_kill | ||
451 | .long sys_rename | ||
452 | .long sys_mkdir | ||
453 | .long sys_rmdir /* 40 */ | ||
454 | .long sys_dup | ||
455 | .long sys_pipe | ||
456 | .long sys_times | ||
457 | .long sys_ni_syscall /* old prof syscall holder */ | ||
458 | .long sys_brk /* 45 */ | ||
459 | .long sys_setgid16 | ||
460 | .long sys_getgid16 | ||
461 | .long sys_signal | ||
462 | .long sys_geteuid16 | ||
463 | .long sys_getegid16 /* 50 */ | ||
464 | .long sys_acct | ||
465 | .long sys_umount /* recycled never used phys() */ | ||
466 | .long sys_ni_syscall /* old lock syscall holder */ | ||
467 | .long sys_ioctl | ||
468 | .long sys_fcntl /* 55 */ | ||
469 | .long sys_ni_syscall /* old mpx syscall holder */ | ||
470 | .long sys_setpgid | ||
471 | .long sys_ni_syscall /* old ulimit syscall holder */ | ||
472 | .long sys_ni_syscall | ||
473 | .long sys_umask /* 60 */ | ||
474 | .long sys_chroot | ||
475 | .long sys_ustat | ||
476 | .long sys_dup2 | ||
477 | .long sys_getppid | ||
478 | .long sys_getpgrp /* 65 */ | ||
479 | .long sys_setsid | ||
480 | .long sys_sigaction | ||
481 | .long sys_sgetmask | ||
482 | .long sys_ssetmask | ||
483 | .long sys_setreuid16 /* 70 */ | ||
484 | .long sys_setregid16 | ||
485 | .long sys_sigsuspend | ||
486 | .long sys_sigpending | ||
487 | .long sys_sethostname | ||
488 | .long sys_setrlimit /* 75 */ | ||
489 | .long sys_old_getrlimit | ||
490 | .long sys_getrusage | ||
491 | .long sys_gettimeofday | ||
492 | .long sys_settimeofday | ||
493 | .long sys_getgroups16 /* 80 */ | ||
494 | .long sys_setgroups16 | ||
495 | .long sys_old_select | ||
496 | .long sys_symlink | ||
497 | .long sys_lstat | ||
498 | .long sys_readlink /* 85 */ | ||
499 | .long sys_uselib | ||
500 | .long sys_swapon | ||
501 | .long sys_reboot | ||
502 | .long sys_old_readdir | ||
503 | .long sys_old_mmap /* 90 */ | ||
504 | .long sys_munmap | ||
505 | .long sys_truncate | ||
506 | .long sys_ftruncate | ||
507 | .long sys_fchmod | ||
508 | .long sys_fchown16 /* 95 */ | ||
509 | .long sys_getpriority | ||
510 | .long sys_setpriority | ||
511 | .long sys_ni_syscall /* old profil syscall holder */ | ||
512 | .long sys_statfs | ||
513 | .long sys_fstatfs /* 100 */ | ||
514 | .long sys_ni_syscall /* ioperm for i386 */ | ||
515 | .long sys_socketcall | ||
516 | .long sys_syslog | ||
517 | .long sys_setitimer | ||
518 | .long sys_getitimer /* 105 */ | ||
519 | .long sys_newstat | ||
520 | .long sys_newlstat | ||
521 | .long sys_newfstat | ||
522 | .long sys_ni_syscall | ||
523 | .long sys_ni_syscall /* 110 */ /* iopl for i386 */ | ||
524 | .long sys_vhangup | ||
525 | .long sys_ni_syscall /* obsolete idle() syscall */ | ||
526 | .long sys_ni_syscall /* vm86old for i386 */ | ||
527 | .long sys_wait4 | ||
528 | .long sys_swapoff /* 115 */ | ||
529 | .long sys_sysinfo | ||
530 | .long sys_ipc | ||
531 | .long sys_fsync | ||
532 | .long sys_sigreturn | ||
533 | .long sys_clone /* 120 */ | ||
534 | .long sys_setdomainname | ||
535 | .long sys_newuname | ||
536 | .long sys_cacheflush /* modify_ldt for i386 */ | ||
537 | .long sys_adjtimex | ||
538 | .long sys_mprotect /* 125 */ | ||
539 | .long sys_sigprocmask | ||
540 | .long sys_ni_syscall /* old "create_module" */ | ||
541 | .long sys_init_module | ||
542 | .long sys_delete_module | ||
543 | .long sys_ni_syscall /* 130 - old "get_kernel_syms" */ | ||
544 | .long sys_quotactl | ||
545 | .long sys_getpgid | ||
546 | .long sys_fchdir | ||
547 | .long sys_bdflush | ||
548 | .long sys_sysfs /* 135 */ | ||
549 | .long sys_personality | ||
550 | .long sys_ni_syscall /* for afs_syscall */ | ||
551 | .long sys_setfsuid16 | ||
552 | .long sys_setfsgid16 | ||
553 | .long sys_llseek /* 140 */ | ||
554 | .long sys_getdents | ||
555 | .long sys_select | ||
556 | .long sys_flock | ||
557 | .long sys_msync | ||
558 | .long sys_readv /* 145 */ | ||
559 | .long sys_writev | ||
560 | .long sys_getsid | ||
561 | .long sys_fdatasync | ||
562 | .long sys_sysctl | ||
563 | .long sys_mlock /* 150 */ | ||
564 | .long sys_munlock | ||
565 | .long sys_mlockall | ||
566 | .long sys_munlockall | ||
567 | .long sys_sched_setparam | ||
568 | .long sys_sched_getparam /* 155 */ | ||
569 | .long sys_sched_setscheduler | ||
570 | .long sys_sched_getscheduler | ||
571 | .long sys_sched_yield | ||
572 | .long sys_sched_get_priority_max | ||
573 | .long sys_sched_get_priority_min /* 160 */ | ||
574 | .long sys_sched_rr_get_interval | ||
575 | .long sys_nanosleep | ||
576 | .long sys_mremap | ||
577 | .long sys_setresuid16 | ||
578 | .long sys_getresuid16 /* 165 */ | ||
579 | .long sys_getpagesize | ||
580 | .long sys_ni_syscall /* old sys_query_module */ | ||
581 | .long sys_poll | ||
582 | .long sys_nfsservctl | ||
583 | .long sys_setresgid16 /* 170 */ | ||
584 | .long sys_getresgid16 | ||
585 | .long sys_prctl | ||
586 | .long sys_rt_sigreturn | ||
587 | .long sys_rt_sigaction | ||
588 | .long sys_rt_sigprocmask /* 175 */ | ||
589 | .long sys_rt_sigpending | ||
590 | .long sys_rt_sigtimedwait | ||
591 | .long sys_rt_sigqueueinfo | ||
592 | .long sys_rt_sigsuspend | ||
593 | .long sys_pread64 /* 180 */ | ||
594 | .long sys_pwrite64 | ||
595 | .long sys_lchown16; | ||
596 | .long sys_getcwd | ||
597 | .long sys_capget | ||
598 | .long sys_capset /* 185 */ | ||
599 | .long sys_sigaltstack | ||
600 | .long sys_sendfile | ||
601 | .long sys_ni_syscall /* streams1 */ | ||
602 | .long sys_ni_syscall /* streams2 */ | ||
603 | .long sys_vfork /* 190 */ | ||
604 | .long sys_getrlimit | ||
605 | .long sys_mmap2 | ||
606 | .long sys_truncate64 | ||
607 | .long sys_ftruncate64 | ||
608 | .long sys_stat64 /* 195 */ | ||
609 | .long sys_lstat64 | ||
610 | .long sys_fstat64 | ||
611 | .long sys_chown | ||
612 | .long sys_getuid | ||
613 | .long sys_getgid /* 200 */ | ||
614 | .long sys_geteuid | ||
615 | .long sys_getegid | ||
616 | .long sys_setreuid | ||
617 | .long sys_setregid | ||
618 | .long sys_getgroups /* 205 */ | ||
619 | .long sys_setgroups | ||
620 | .long sys_fchown | ||
621 | .long sys_setresuid | ||
622 | .long sys_getresuid | ||
623 | .long sys_setresgid /* 210 */ | ||
624 | .long sys_getresgid | ||
625 | .long sys_lchown | ||
626 | .long sys_setuid | ||
627 | .long sys_setgid | ||
628 | .long sys_setfsuid /* 215 */ | ||
629 | .long sys_setfsgid | ||
630 | .long sys_pivot_root | ||
631 | .long sys_ni_syscall | ||
632 | .long sys_ni_syscall | ||
633 | .long sys_getdents64 /* 220 */ | ||
634 | .long sys_gettid | ||
635 | .long sys_tkill | ||
636 | .long sys_setxattr | ||
637 | .long sys_lsetxattr | ||
638 | .long sys_fsetxattr /* 225 */ | ||
639 | .long sys_getxattr | ||
640 | .long sys_lgetxattr | ||
641 | .long sys_fgetxattr | ||
642 | .long sys_listxattr | ||
643 | .long sys_llistxattr /* 230 */ | ||
644 | .long sys_flistxattr | ||
645 | .long sys_removexattr | ||
646 | .long sys_lremovexattr | ||
647 | .long sys_fremovexattr | ||
648 | .long sys_futex /* 235 */ | ||
649 | .long sys_sendfile64 | ||
650 | .long sys_mincore | ||
651 | .long sys_madvise | ||
652 | .long sys_fcntl64 | ||
653 | .long sys_readahead /* 240 */ | ||
654 | .long sys_io_setup | ||
655 | .long sys_io_destroy | ||
656 | .long sys_io_getevents | ||
657 | .long sys_io_submit | ||
658 | .long sys_io_cancel /* 245 */ | ||
659 | .long sys_fadvise64 | ||
660 | .long sys_exit_group | ||
661 | .long sys_lookup_dcookie | ||
662 | .long sys_epoll_create | ||
663 | .long sys_epoll_ctl /* 250 */ | ||
664 | .long sys_epoll_wait | ||
665 | .long sys_remap_file_pages | ||
666 | .long sys_set_tid_address | ||
667 | .long sys_timer_create | ||
668 | .long sys_timer_settime /* 255 */ | ||
669 | .long sys_timer_gettime | ||
670 | .long sys_timer_getoverrun | ||
671 | .long sys_timer_delete | ||
672 | .long sys_clock_settime | ||
673 | .long sys_clock_gettime /* 260 */ | ||
674 | .long sys_clock_getres | ||
675 | .long sys_clock_nanosleep | ||
676 | .long sys_statfs64 | ||
677 | .long sys_fstatfs64 | ||
678 | .long sys_tgkill /* 265 */ | ||
679 | .long sys_utimes | ||
680 | .long sys_fadvise64_64 | ||
681 | .long sys_mbind | ||
682 | .long sys_get_mempolicy | ||
683 | .long sys_set_mempolicy /* 270 */ | ||
684 | .long sys_mq_open | ||
685 | .long sys_mq_unlink | ||
686 | .long sys_mq_timedsend | ||
687 | .long sys_mq_timedreceive | ||
688 | .long sys_mq_notify /* 275 */ | ||
689 | .long sys_mq_getsetattr | ||
690 | .long sys_waitid | ||
691 | .long sys_ni_syscall /* for sys_vserver */ | ||
692 | .long sys_add_key | ||
693 | .long sys_request_key /* 280 */ | ||
694 | .long sys_keyctl | ||
695 | .long sys_ioprio_set | ||
696 | .long sys_ioprio_get | ||
697 | .long sys_inotify_init | ||
698 | .long sys_inotify_add_watch /* 285 */ | ||
699 | .long sys_inotify_rm_watch | ||
700 | .long sys_migrate_pages | ||
701 | .long sys_openat | ||
702 | .long sys_mkdirat | ||
703 | .long sys_mknodat /* 290 */ | ||
704 | .long sys_fchownat | ||
705 | .long sys_futimesat | ||
706 | .long sys_fstatat64 | ||
707 | .long sys_unlinkat | ||
708 | .long sys_renameat /* 295 */ | ||
709 | .long sys_linkat | ||
710 | .long sys_symlinkat | ||
711 | .long sys_readlinkat | ||
712 | .long sys_fchmodat | ||
713 | .long sys_faccessat /* 300 */ | ||
714 | .long sys_ni_syscall /* Reserved for pselect6 */ | ||
715 | .long sys_ni_syscall /* Reserved for ppoll */ | ||
716 | .long sys_unshare | ||
717 | .long sys_set_robust_list | ||
718 | .long sys_get_robust_list /* 305 */ | ||
719 | .long sys_splice | ||
720 | .long sys_sync_file_range | ||
721 | .long sys_tee | ||
722 | .long sys_vmsplice | ||
723 | .long sys_move_pages /* 310 */ | ||
724 | .long sys_sched_setaffinity | ||
725 | .long sys_sched_getaffinity | ||
726 | .long sys_kexec_load | ||
727 | .long sys_getcpu | ||
728 | .long sys_epoll_pwait /* 315 */ | ||
729 | .long sys_utimensat | ||
730 | .long sys_signalfd | ||
731 | .long sys_timerfd_create | ||
732 | .long sys_eventfd | ||
733 | .long sys_fallocate /* 320 */ | ||
734 | .long sys_timerfd_settime | ||
735 | .long sys_timerfd_gettime | ||
736 | .long sys_signalfd4 | ||
737 | .long sys_eventfd2 | ||
738 | .long sys_epoll_create1 /* 325 */ | ||
739 | .long sys_dup3 | ||
740 | .long sys_pipe2 | ||
741 | .long sys_inotify_init1 | ||
742 | .long sys_preadv | ||
743 | .long sys_pwritev /* 330 */ | ||
744 | .long sys_rt_tgsigqueueinfo | ||
745 | .long sys_perf_event_open | ||
746 | .long sys_get_thread_area | ||
747 | .long sys_set_thread_area | ||
748 | .long sys_atomic_cmpxchg_32 /* 335 */ | ||
749 | .long sys_atomic_barrier | ||
750 | .long sys_fanotify_init | ||
751 | .long sys_fanotify_mark | ||
752 | .long sys_prlimit64 | ||
753 | |||
diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S new file mode 100644 index 000000000000..1559dea36e55 --- /dev/null +++ b/arch/m68k/kernel/entry_mm.S | |||
@@ -0,0 +1,753 @@ | |||
1 | /* -*- mode: asm -*- | ||
2 | * | ||
3 | * linux/arch/m68k/kernel/entry.S | ||
4 | * | ||
5 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License. See the file README.legal in the main directory of this archive | ||
9 | * for more details. | ||
10 | * | ||
11 | * Linux/m68k support by Hamish Macdonald | ||
12 | * | ||
13 | * 68060 fixes by Jesper Skov | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * entry.S contains the system-call and fault low-level handling routines. | ||
19 | * This also contains the timer-interrupt handler, as well as all interrupts | ||
20 | * and faults that can result in a task-switch. | ||
21 | * | ||
22 | * NOTE: This code handles signal-recognition, which happens every time | ||
23 | * after a timer-interrupt and after each system call. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so | ||
29 | * all pointers that used to be 'current' are now entry | ||
30 | * number 0 in the 'current_set' list. | ||
31 | * | ||
32 | * 6/05/00 RZ: addedd writeback completion after return from sighandler | ||
33 | * for 68040 | ||
34 | */ | ||
35 | |||
36 | #include <linux/linkage.h> | ||
37 | #include <asm/entry.h> | ||
38 | #include <asm/errno.h> | ||
39 | #include <asm/setup.h> | ||
40 | #include <asm/segment.h> | ||
41 | #include <asm/traps.h> | ||
42 | #include <asm/unistd.h> | ||
43 | |||
44 | #include <asm/asm-offsets.h> | ||
45 | |||
46 | .globl system_call, buserr, trap, resume | ||
47 | .globl sys_call_table | ||
48 | .globl sys_fork, sys_clone, sys_vfork | ||
49 | .globl ret_from_interrupt, bad_interrupt | ||
50 | .globl auto_irqhandler_fixup | ||
51 | .globl user_irqvec_fixup, user_irqhandler_fixup | ||
52 | |||
53 | .text | ||
54 | ENTRY(buserr) | ||
55 | SAVE_ALL_INT | ||
56 | GET_CURRENT(%d0) | ||
57 | movel %sp,%sp@- | stack frame pointer argument | ||
58 | bsrl buserr_c | ||
59 | addql #4,%sp | ||
60 | jra .Lret_from_exception | ||
61 | |||
62 | ENTRY(trap) | ||
63 | SAVE_ALL_INT | ||
64 | GET_CURRENT(%d0) | ||
65 | movel %sp,%sp@- | stack frame pointer argument | ||
66 | bsrl trap_c | ||
67 | addql #4,%sp | ||
68 | jra .Lret_from_exception | ||
69 | |||
70 | | After a fork we jump here directly from resume, | ||
71 | | so that %d1 contains the previous task | ||
72 | | schedule_tail now used regardless of CONFIG_SMP | ||
73 | ENTRY(ret_from_fork) | ||
74 | movel %d1,%sp@- | ||
75 | jsr schedule_tail | ||
76 | addql #4,%sp | ||
77 | jra .Lret_from_exception | ||
78 | |||
79 | do_trace_entry: | ||
80 | movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace | ||
81 | subql #4,%sp | ||
82 | SAVE_SWITCH_STACK | ||
83 | jbsr syscall_trace | ||
84 | RESTORE_SWITCH_STACK | ||
85 | addql #4,%sp | ||
86 | movel %sp@(PT_OFF_ORIG_D0),%d0 | ||
87 | cmpl #NR_syscalls,%d0 | ||
88 | jcs syscall | ||
89 | badsys: | ||
90 | movel #-ENOSYS,%sp@(PT_OFF_D0) | ||
91 | jra ret_from_syscall | ||
92 | |||
93 | do_trace_exit: | ||
94 | subql #4,%sp | ||
95 | SAVE_SWITCH_STACK | ||
96 | jbsr syscall_trace | ||
97 | RESTORE_SWITCH_STACK | ||
98 | addql #4,%sp | ||
99 | jra .Lret_from_exception | ||
100 | |||
101 | ENTRY(ret_from_signal) | ||
102 | tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) | ||
103 | jge 1f | ||
104 | jbsr syscall_trace | ||
105 | 1: RESTORE_SWITCH_STACK | ||
106 | addql #4,%sp | ||
107 | /* on 68040 complete pending writebacks if any */ | ||
108 | #ifdef CONFIG_M68040 | ||
109 | bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0 | ||
110 | subql #7,%d0 | bus error frame ? | ||
111 | jbne 1f | ||
112 | movel %sp,%sp@- | ||
113 | jbsr berr_040cleanup | ||
114 | addql #4,%sp | ||
115 | 1: | ||
116 | #endif | ||
117 | jra .Lret_from_exception | ||
118 | |||
119 | ENTRY(system_call) | ||
120 | SAVE_ALL_SYS | ||
121 | |||
122 | GET_CURRENT(%d1) | ||
123 | | save top of frame | ||
124 | movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) | ||
125 | |||
126 | | syscall trace? | ||
127 | tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) | ||
128 | jmi do_trace_entry | ||
129 | cmpl #NR_syscalls,%d0 | ||
130 | jcc badsys | ||
131 | syscall: | ||
132 | jbsr @(sys_call_table,%d0:l:4)@(0) | ||
133 | movel %d0,%sp@(PT_OFF_D0) | save the return value | ||
134 | ret_from_syscall: | ||
135 | |oriw #0x0700,%sr | ||
136 | movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 | ||
137 | jne syscall_exit_work | ||
138 | 1: RESTORE_ALL | ||
139 | |||
140 | syscall_exit_work: | ||
141 | btst #5,%sp@(PT_OFF_SR) | check if returning to kernel | ||
142 | bnes 1b | if so, skip resched, signals | ||
143 | lslw #1,%d0 | ||
144 | jcs do_trace_exit | ||
145 | jmi do_delayed_trace | ||
146 | lslw #8,%d0 | ||
147 | jmi do_signal_return | ||
148 | pea resume_userspace | ||
149 | jra schedule | ||
150 | |||
151 | |||
152 | ENTRY(ret_from_exception) | ||
153 | .Lret_from_exception: | ||
154 | btst #5,%sp@(PT_OFF_SR) | check if returning to kernel | ||
155 | bnes 1f | if so, skip resched, signals | ||
156 | | only allow interrupts when we are really the last one on the | ||
157 | | kernel stack, otherwise stack overflow can occur during | ||
158 | | heavy interrupt load | ||
159 | andw #ALLOWINT,%sr | ||
160 | |||
161 | resume_userspace: | ||
162 | moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0 | ||
163 | jne exit_work | ||
164 | 1: RESTORE_ALL | ||
165 | |||
166 | exit_work: | ||
167 | | save top of frame | ||
168 | movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) | ||
169 | lslb #1,%d0 | ||
170 | jmi do_signal_return | ||
171 | pea resume_userspace | ||
172 | jra schedule | ||
173 | |||
174 | |||
175 | do_signal_return: | ||
176 | |andw #ALLOWINT,%sr | ||
177 | subql #4,%sp | dummy return address | ||
178 | SAVE_SWITCH_STACK | ||
179 | pea %sp@(SWITCH_STACK_SIZE) | ||
180 | bsrl do_signal | ||
181 | addql #4,%sp | ||
182 | RESTORE_SWITCH_STACK | ||
183 | addql #4,%sp | ||
184 | jbra resume_userspace | ||
185 | |||
186 | do_delayed_trace: | ||
187 | bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR | ||
188 | pea 1 | send SIGTRAP | ||
189 | movel %curptr,%sp@- | ||
190 | pea LSIGTRAP | ||
191 | jbsr send_sig | ||
192 | addql #8,%sp | ||
193 | addql #4,%sp | ||
194 | jbra resume_userspace | ||
195 | |||
196 | |||
197 | /* This is the main interrupt handler for autovector interrupts */ | ||
198 | |||
199 | ENTRY(auto_inthandler) | ||
200 | SAVE_ALL_INT | ||
201 | GET_CURRENT(%d0) | ||
202 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
203 | | put exception # in d0 | ||
204 | bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 | ||
205 | subw #VEC_SPUR,%d0 | ||
206 | |||
207 | movel %sp,%sp@- | ||
208 | movel %d0,%sp@- | put vector # on stack | ||
209 | auto_irqhandler_fixup = . + 2 | ||
210 | jsr __m68k_handle_int | process the IRQ | ||
211 | addql #8,%sp | pop parameters off stack | ||
212 | |||
213 | ret_from_interrupt: | ||
214 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
215 | jeq ret_from_last_interrupt | ||
216 | 2: RESTORE_ALL | ||
217 | |||
218 | ALIGN | ||
219 | ret_from_last_interrupt: | ||
220 | moveq #(~ALLOWINT>>8)&0xff,%d0 | ||
221 | andb %sp@(PT_OFF_SR),%d0 | ||
222 | jne 2b | ||
223 | |||
224 | /* check if we need to do software interrupts */ | ||
225 | tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING | ||
226 | jeq .Lret_from_exception | ||
227 | pea ret_from_exception | ||
228 | jra do_softirq | ||
229 | |||
230 | /* Handler for user defined interrupt vectors */ | ||
231 | |||
232 | ENTRY(user_inthandler) | ||
233 | SAVE_ALL_INT | ||
234 | GET_CURRENT(%d0) | ||
235 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
236 | | put exception # in d0 | ||
237 | bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 | ||
238 | user_irqvec_fixup = . + 2 | ||
239 | subw #VEC_USER,%d0 | ||
240 | |||
241 | movel %sp,%sp@- | ||
242 | movel %d0,%sp@- | put vector # on stack | ||
243 | user_irqhandler_fixup = . + 2 | ||
244 | jsr __m68k_handle_int | process the IRQ | ||
245 | addql #8,%sp | pop parameters off stack | ||
246 | |||
247 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
248 | jeq ret_from_last_interrupt | ||
249 | RESTORE_ALL | ||
250 | |||
251 | /* Handler for uninitialized and spurious interrupts */ | ||
252 | |||
253 | ENTRY(bad_inthandler) | ||
254 | SAVE_ALL_INT | ||
255 | GET_CURRENT(%d0) | ||
256 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
257 | |||
258 | movel %sp,%sp@- | ||
259 | jsr handle_badint | ||
260 | addql #4,%sp | ||
261 | |||
262 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | ||
263 | jeq ret_from_last_interrupt | ||
264 | RESTORE_ALL | ||
265 | |||
266 | |||
267 | ENTRY(sys_fork) | ||
268 | SAVE_SWITCH_STACK | ||
269 | pea %sp@(SWITCH_STACK_SIZE) | ||
270 | jbsr m68k_fork | ||
271 | addql #4,%sp | ||
272 | RESTORE_SWITCH_STACK | ||
273 | rts | ||
274 | |||
275 | ENTRY(sys_clone) | ||
276 | SAVE_SWITCH_STACK | ||
277 | pea %sp@(SWITCH_STACK_SIZE) | ||
278 | jbsr m68k_clone | ||
279 | addql #4,%sp | ||
280 | RESTORE_SWITCH_STACK | ||
281 | rts | ||
282 | |||
283 | ENTRY(sys_vfork) | ||
284 | SAVE_SWITCH_STACK | ||
285 | pea %sp@(SWITCH_STACK_SIZE) | ||
286 | jbsr m68k_vfork | ||
287 | addql #4,%sp | ||
288 | RESTORE_SWITCH_STACK | ||
289 | rts | ||
290 | |||
291 | ENTRY(sys_sigreturn) | ||
292 | SAVE_SWITCH_STACK | ||
293 | jbsr do_sigreturn | ||
294 | RESTORE_SWITCH_STACK | ||
295 | rts | ||
296 | |||
297 | ENTRY(sys_rt_sigreturn) | ||
298 | SAVE_SWITCH_STACK | ||
299 | jbsr do_rt_sigreturn | ||
300 | RESTORE_SWITCH_STACK | ||
301 | rts | ||
302 | |||
303 | resume: | ||
304 | /* | ||
305 | * Beware - when entering resume, prev (the current task) is | ||
306 | * in a0, next (the new task) is in a1,so don't change these | ||
307 | * registers until their contents are no longer needed. | ||
308 | */ | ||
309 | |||
310 | /* save sr */ | ||
311 | movew %sr,%a0@(TASK_THREAD+THREAD_SR) | ||
312 | |||
313 | /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ | ||
314 | movec %sfc,%d0 | ||
315 | movew %d0,%a0@(TASK_THREAD+THREAD_FS) | ||
316 | |||
317 | /* save usp */ | ||
318 | /* it is better to use a movel here instead of a movew 8*) */ | ||
319 | movec %usp,%d0 | ||
320 | movel %d0,%a0@(TASK_THREAD+THREAD_USP) | ||
321 | |||
322 | /* save non-scratch registers on stack */ | ||
323 | SAVE_SWITCH_STACK | ||
324 | |||
325 | /* save current kernel stack pointer */ | ||
326 | movel %sp,%a0@(TASK_THREAD+THREAD_KSP) | ||
327 | |||
328 | /* save floating point context */ | ||
329 | #ifndef CONFIG_M68KFPU_EMU_ONLY | ||
330 | #ifdef CONFIG_M68KFPU_EMU | ||
331 | tstl m68k_fputype | ||
332 | jeq 3f | ||
333 | #endif | ||
334 | fsave %a0@(TASK_THREAD+THREAD_FPSTATE) | ||
335 | |||
336 | #if defined(CONFIG_M68060) | ||
337 | #if !defined(CPU_M68060_ONLY) | ||
338 | btst #3,m68k_cputype+3 | ||
339 | beqs 1f | ||
340 | #endif | ||
341 | /* The 060 FPU keeps status in bits 15-8 of the first longword */ | ||
342 | tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2) | ||
343 | jeq 3f | ||
344 | #if !defined(CPU_M68060_ONLY) | ||
345 | jra 2f | ||
346 | #endif | ||
347 | #endif /* CONFIG_M68060 */ | ||
348 | #if !defined(CPU_M68060_ONLY) | ||
349 | 1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE) | ||
350 | jeq 3f | ||
351 | #endif | ||
352 | 2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) | ||
353 | fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) | ||
354 | 3: | ||
355 | #endif /* CONFIG_M68KFPU_EMU_ONLY */ | ||
356 | /* Return previous task in %d1 */ | ||
357 | movel %curptr,%d1 | ||
358 | |||
359 | /* switch to new task (a1 contains new task) */ | ||
360 | movel %a1,%curptr | ||
361 | |||
362 | /* restore floating point context */ | ||
363 | #ifndef CONFIG_M68KFPU_EMU_ONLY | ||
364 | #ifdef CONFIG_M68KFPU_EMU | ||
365 | tstl m68k_fputype | ||
366 | jeq 4f | ||
367 | #endif | ||
368 | #if defined(CONFIG_M68060) | ||
369 | #if !defined(CPU_M68060_ONLY) | ||
370 | btst #3,m68k_cputype+3 | ||
371 | beqs 1f | ||
372 | #endif | ||
373 | /* The 060 FPU keeps status in bits 15-8 of the first longword */ | ||
374 | tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2) | ||
375 | jeq 3f | ||
376 | #if !defined(CPU_M68060_ONLY) | ||
377 | jra 2f | ||
378 | #endif | ||
379 | #endif /* CONFIG_M68060 */ | ||
380 | #if !defined(CPU_M68060_ONLY) | ||
381 | 1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE) | ||
382 | jeq 3f | ||
383 | #endif | ||
384 | 2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 | ||
385 | fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar | ||
386 | 3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) | ||
387 | 4: | ||
388 | #endif /* CONFIG_M68KFPU_EMU_ONLY */ | ||
389 | |||
390 | /* restore the kernel stack pointer */ | ||
391 | movel %a1@(TASK_THREAD+THREAD_KSP),%sp | ||
392 | |||
393 | /* restore non-scratch registers */ | ||
394 | RESTORE_SWITCH_STACK | ||
395 | |||
396 | /* restore user stack pointer */ | ||
397 | movel %a1@(TASK_THREAD+THREAD_USP),%a0 | ||
398 | movel %a0,%usp | ||
399 | |||
400 | /* restore fs (sfc,%dfc) */ | ||
401 | movew %a1@(TASK_THREAD+THREAD_FS),%a0 | ||
402 | movec %a0,%sfc | ||
403 | movec %a0,%dfc | ||
404 | |||
405 | /* restore status register */ | ||
406 | movew %a1@(TASK_THREAD+THREAD_SR),%sr | ||
407 | |||
408 | rts | ||
409 | |||
410 | .data | ||
411 | ALIGN | ||
412 | sys_call_table: | ||
413 | .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ | ||
414 | .long sys_exit | ||
415 | .long sys_fork | ||
416 | .long sys_read | ||
417 | .long sys_write | ||
418 | .long sys_open /* 5 */ | ||
419 | .long sys_close | ||
420 | .long sys_waitpid | ||
421 | .long sys_creat | ||
422 | .long sys_link | ||
423 | .long sys_unlink /* 10 */ | ||
424 | .long sys_execve | ||
425 | .long sys_chdir | ||
426 | .long sys_time | ||
427 | .long sys_mknod | ||
428 | .long sys_chmod /* 15 */ | ||
429 | .long sys_chown16 | ||
430 | .long sys_ni_syscall /* old break syscall holder */ | ||
431 | .long sys_stat | ||
432 | .long sys_lseek | ||
433 | .long sys_getpid /* 20 */ | ||
434 | .long sys_mount | ||
435 | .long sys_oldumount | ||
436 | .long sys_setuid16 | ||
437 | .long sys_getuid16 | ||
438 | .long sys_stime /* 25 */ | ||
439 | .long sys_ptrace | ||
440 | .long sys_alarm | ||
441 | .long sys_fstat | ||
442 | .long sys_pause | ||
443 | .long sys_utime /* 30 */ | ||
444 | .long sys_ni_syscall /* old stty syscall holder */ | ||
445 | .long sys_ni_syscall /* old gtty syscall holder */ | ||
446 | .long sys_access | ||
447 | .long sys_nice | ||
448 | .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ | ||
449 | .long sys_sync | ||
450 | .long sys_kill | ||
451 | .long sys_rename | ||
452 | .long sys_mkdir | ||
453 | .long sys_rmdir /* 40 */ | ||
454 | .long sys_dup | ||
455 | .long sys_pipe | ||
456 | .long sys_times | ||
457 | .long sys_ni_syscall /* old prof syscall holder */ | ||
458 | .long sys_brk /* 45 */ | ||
459 | .long sys_setgid16 | ||
460 | .long sys_getgid16 | ||
461 | .long sys_signal | ||
462 | .long sys_geteuid16 | ||
463 | .long sys_getegid16 /* 50 */ | ||
464 | .long sys_acct | ||
465 | .long sys_umount /* recycled never used phys() */ | ||
466 | .long sys_ni_syscall /* old lock syscall holder */ | ||
467 | .long sys_ioctl | ||
468 | .long sys_fcntl /* 55 */ | ||
469 | .long sys_ni_syscall /* old mpx syscall holder */ | ||
470 | .long sys_setpgid | ||
471 | .long sys_ni_syscall /* old ulimit syscall holder */ | ||
472 | .long sys_ni_syscall | ||
473 | .long sys_umask /* 60 */ | ||
474 | .long sys_chroot | ||
475 | .long sys_ustat | ||
476 | .long sys_dup2 | ||
477 | .long sys_getppid | ||
478 | .long sys_getpgrp /* 65 */ | ||
479 | .long sys_setsid | ||
480 | .long sys_sigaction | ||
481 | .long sys_sgetmask | ||
482 | .long sys_ssetmask | ||
483 | .long sys_setreuid16 /* 70 */ | ||
484 | .long sys_setregid16 | ||
485 | .long sys_sigsuspend | ||
486 | .long sys_sigpending | ||
487 | .long sys_sethostname | ||
488 | .long sys_setrlimit /* 75 */ | ||
489 | .long sys_old_getrlimit | ||
490 | .long sys_getrusage | ||
491 | .long sys_gettimeofday | ||
492 | .long sys_settimeofday | ||
493 | .long sys_getgroups16 /* 80 */ | ||
494 | .long sys_setgroups16 | ||
495 | .long sys_old_select | ||
496 | .long sys_symlink | ||
497 | .long sys_lstat | ||
498 | .long sys_readlink /* 85 */ | ||
499 | .long sys_uselib | ||
500 | .long sys_swapon | ||
501 | .long sys_reboot | ||
502 | .long sys_old_readdir | ||
503 | .long sys_old_mmap /* 90 */ | ||
504 | .long sys_munmap | ||
505 | .long sys_truncate | ||
506 | .long sys_ftruncate | ||
507 | .long sys_fchmod | ||
508 | .long sys_fchown16 /* 95 */ | ||
509 | .long sys_getpriority | ||
510 | .long sys_setpriority | ||
511 | .long sys_ni_syscall /* old profil syscall holder */ | ||
512 | .long sys_statfs | ||
513 | .long sys_fstatfs /* 100 */ | ||
514 | .long sys_ni_syscall /* ioperm for i386 */ | ||
515 | .long sys_socketcall | ||
516 | .long sys_syslog | ||
517 | .long sys_setitimer | ||
518 | .long sys_getitimer /* 105 */ | ||
519 | .long sys_newstat | ||
520 | .long sys_newlstat | ||
521 | .long sys_newfstat | ||
522 | .long sys_ni_syscall | ||
523 | .long sys_ni_syscall /* 110 */ /* iopl for i386 */ | ||
524 | .long sys_vhangup | ||
525 | .long sys_ni_syscall /* obsolete idle() syscall */ | ||
526 | .long sys_ni_syscall /* vm86old for i386 */ | ||
527 | .long sys_wait4 | ||
528 | .long sys_swapoff /* 115 */ | ||
529 | .long sys_sysinfo | ||
530 | .long sys_ipc | ||
531 | .long sys_fsync | ||
532 | .long sys_sigreturn | ||
533 | .long sys_clone /* 120 */ | ||
534 | .long sys_setdomainname | ||
535 | .long sys_newuname | ||
536 | .long sys_cacheflush /* modify_ldt for i386 */ | ||
537 | .long sys_adjtimex | ||
538 | .long sys_mprotect /* 125 */ | ||
539 | .long sys_sigprocmask | ||
540 | .long sys_ni_syscall /* old "create_module" */ | ||
541 | .long sys_init_module | ||
542 | .long sys_delete_module | ||
543 | .long sys_ni_syscall /* 130 - old "get_kernel_syms" */ | ||
544 | .long sys_quotactl | ||
545 | .long sys_getpgid | ||
546 | .long sys_fchdir | ||
547 | .long sys_bdflush | ||
548 | .long sys_sysfs /* 135 */ | ||
549 | .long sys_personality | ||
550 | .long sys_ni_syscall /* for afs_syscall */ | ||
551 | .long sys_setfsuid16 | ||
552 | .long sys_setfsgid16 | ||
553 | .long sys_llseek /* 140 */ | ||
554 | .long sys_getdents | ||
555 | .long sys_select | ||
556 | .long sys_flock | ||
557 | .long sys_msync | ||
558 | .long sys_readv /* 145 */ | ||
559 | .long sys_writev | ||
560 | .long sys_getsid | ||
561 | .long sys_fdatasync | ||
562 | .long sys_sysctl | ||
563 | .long sys_mlock /* 150 */ | ||
564 | .long sys_munlock | ||
565 | .long sys_mlockall | ||
566 | .long sys_munlockall | ||
567 | .long sys_sched_setparam | ||
568 | .long sys_sched_getparam /* 155 */ | ||
569 | .long sys_sched_setscheduler | ||
570 | .long sys_sched_getscheduler | ||
571 | .long sys_sched_yield | ||
572 | .long sys_sched_get_priority_max | ||
573 | .long sys_sched_get_priority_min /* 160 */ | ||
574 | .long sys_sched_rr_get_interval | ||
575 | .long sys_nanosleep | ||
576 | .long sys_mremap | ||
577 | .long sys_setresuid16 | ||
578 | .long sys_getresuid16 /* 165 */ | ||
579 | .long sys_getpagesize | ||
580 | .long sys_ni_syscall /* old sys_query_module */ | ||
581 | .long sys_poll | ||
582 | .long sys_nfsservctl | ||
583 | .long sys_setresgid16 /* 170 */ | ||
584 | .long sys_getresgid16 | ||
585 | .long sys_prctl | ||
586 | .long sys_rt_sigreturn | ||
587 | .long sys_rt_sigaction | ||
588 | .long sys_rt_sigprocmask /* 175 */ | ||
589 | .long sys_rt_sigpending | ||
590 | .long sys_rt_sigtimedwait | ||
591 | .long sys_rt_sigqueueinfo | ||
592 | .long sys_rt_sigsuspend | ||
593 | .long sys_pread64 /* 180 */ | ||
594 | .long sys_pwrite64 | ||
595 | .long sys_lchown16; | ||
596 | .long sys_getcwd | ||
597 | .long sys_capget | ||
598 | .long sys_capset /* 185 */ | ||
599 | .long sys_sigaltstack | ||
600 | .long sys_sendfile | ||
601 | .long sys_ni_syscall /* streams1 */ | ||
602 | .long sys_ni_syscall /* streams2 */ | ||
603 | .long sys_vfork /* 190 */ | ||
604 | .long sys_getrlimit | ||
605 | .long sys_mmap2 | ||
606 | .long sys_truncate64 | ||
607 | .long sys_ftruncate64 | ||
608 | .long sys_stat64 /* 195 */ | ||
609 | .long sys_lstat64 | ||
610 | .long sys_fstat64 | ||
611 | .long sys_chown | ||
612 | .long sys_getuid | ||
613 | .long sys_getgid /* 200 */ | ||
614 | .long sys_geteuid | ||
615 | .long sys_getegid | ||
616 | .long sys_setreuid | ||
617 | .long sys_setregid | ||
618 | .long sys_getgroups /* 205 */ | ||
619 | .long sys_setgroups | ||
620 | .long sys_fchown | ||
621 | .long sys_setresuid | ||
622 | .long sys_getresuid | ||
623 | .long sys_setresgid /* 210 */ | ||
624 | .long sys_getresgid | ||
625 | .long sys_lchown | ||
626 | .long sys_setuid | ||
627 | .long sys_setgid | ||
628 | .long sys_setfsuid /* 215 */ | ||
629 | .long sys_setfsgid | ||
630 | .long sys_pivot_root | ||
631 | .long sys_ni_syscall | ||
632 | .long sys_ni_syscall | ||
633 | .long sys_getdents64 /* 220 */ | ||
634 | .long sys_gettid | ||
635 | .long sys_tkill | ||
636 | .long sys_setxattr | ||
637 | .long sys_lsetxattr | ||
638 | .long sys_fsetxattr /* 225 */ | ||
639 | .long sys_getxattr | ||
640 | .long sys_lgetxattr | ||
641 | .long sys_fgetxattr | ||
642 | .long sys_listxattr | ||
643 | .long sys_llistxattr /* 230 */ | ||
644 | .long sys_flistxattr | ||
645 | .long sys_removexattr | ||
646 | .long sys_lremovexattr | ||
647 | .long sys_fremovexattr | ||
648 | .long sys_futex /* 235 */ | ||
649 | .long sys_sendfile64 | ||
650 | .long sys_mincore | ||
651 | .long sys_madvise | ||
652 | .long sys_fcntl64 | ||
653 | .long sys_readahead /* 240 */ | ||
654 | .long sys_io_setup | ||
655 | .long sys_io_destroy | ||
656 | .long sys_io_getevents | ||
657 | .long sys_io_submit | ||
658 | .long sys_io_cancel /* 245 */ | ||
659 | .long sys_fadvise64 | ||
660 | .long sys_exit_group | ||
661 | .long sys_lookup_dcookie | ||
662 | .long sys_epoll_create | ||
663 | .long sys_epoll_ctl /* 250 */ | ||
664 | .long sys_epoll_wait | ||
665 | .long sys_remap_file_pages | ||
666 | .long sys_set_tid_address | ||
667 | .long sys_timer_create | ||
668 | .long sys_timer_settime /* 255 */ | ||
669 | .long sys_timer_gettime | ||
670 | .long sys_timer_getoverrun | ||
671 | .long sys_timer_delete | ||
672 | .long sys_clock_settime | ||
673 | .long sys_clock_gettime /* 260 */ | ||
674 | .long sys_clock_getres | ||
675 | .long sys_clock_nanosleep | ||
676 | .long sys_statfs64 | ||
677 | .long sys_fstatfs64 | ||
678 | .long sys_tgkill /* 265 */ | ||
679 | .long sys_utimes | ||
680 | .long sys_fadvise64_64 | ||
681 | .long sys_mbind | ||
682 | .long sys_get_mempolicy | ||
683 | .long sys_set_mempolicy /* 270 */ | ||
684 | .long sys_mq_open | ||
685 | .long sys_mq_unlink | ||
686 | .long sys_mq_timedsend | ||
687 | .long sys_mq_timedreceive | ||
688 | .long sys_mq_notify /* 275 */ | ||
689 | .long sys_mq_getsetattr | ||
690 | .long sys_waitid | ||
691 | .long sys_ni_syscall /* for sys_vserver */ | ||
692 | .long sys_add_key | ||
693 | .long sys_request_key /* 280 */ | ||
694 | .long sys_keyctl | ||
695 | .long sys_ioprio_set | ||
696 | .long sys_ioprio_get | ||
697 | .long sys_inotify_init | ||
698 | .long sys_inotify_add_watch /* 285 */ | ||
699 | .long sys_inotify_rm_watch | ||
700 | .long sys_migrate_pages | ||
701 | .long sys_openat | ||
702 | .long sys_mkdirat | ||
703 | .long sys_mknodat /* 290 */ | ||
704 | .long sys_fchownat | ||
705 | .long sys_futimesat | ||
706 | .long sys_fstatat64 | ||
707 | .long sys_unlinkat | ||
708 | .long sys_renameat /* 295 */ | ||
709 | .long sys_linkat | ||
710 | .long sys_symlinkat | ||
711 | .long sys_readlinkat | ||
712 | .long sys_fchmodat | ||
713 | .long sys_faccessat /* 300 */ | ||
714 | .long sys_ni_syscall /* Reserved for pselect6 */ | ||
715 | .long sys_ni_syscall /* Reserved for ppoll */ | ||
716 | .long sys_unshare | ||
717 | .long sys_set_robust_list | ||
718 | .long sys_get_robust_list /* 305 */ | ||
719 | .long sys_splice | ||
720 | .long sys_sync_file_range | ||
721 | .long sys_tee | ||
722 | .long sys_vmsplice | ||
723 | .long sys_move_pages /* 310 */ | ||
724 | .long sys_sched_setaffinity | ||
725 | .long sys_sched_getaffinity | ||
726 | .long sys_kexec_load | ||
727 | .long sys_getcpu | ||
728 | .long sys_epoll_pwait /* 315 */ | ||
729 | .long sys_utimensat | ||
730 | .long sys_signalfd | ||
731 | .long sys_timerfd_create | ||
732 | .long sys_eventfd | ||
733 | .long sys_fallocate /* 320 */ | ||
734 | .long sys_timerfd_settime | ||
735 | .long sys_timerfd_gettime | ||
736 | .long sys_signalfd4 | ||
737 | .long sys_eventfd2 | ||
738 | .long sys_epoll_create1 /* 325 */ | ||
739 | .long sys_dup3 | ||
740 | .long sys_pipe2 | ||
741 | .long sys_inotify_init1 | ||
742 | .long sys_preadv | ||
743 | .long sys_pwritev /* 330 */ | ||
744 | .long sys_rt_tgsigqueueinfo | ||
745 | .long sys_perf_event_open | ||
746 | .long sys_get_thread_area | ||
747 | .long sys_set_thread_area | ||
748 | .long sys_atomic_cmpxchg_32 /* 335 */ | ||
749 | .long sys_atomic_barrier | ||
750 | .long sys_fanotify_init | ||
751 | .long sys_fanotify_mark | ||
752 | .long sys_prlimit64 | ||
753 | |||
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68k/kernel/entry_no.S index 2783f25e38bd..2783f25e38bd 100644 --- a/arch/m68knommu/kernel/entry.S +++ b/arch/m68k/kernel/entry_no.S | |||
diff --git a/arch/m68knommu/kernel/init_task.c b/arch/m68k/kernel/init_task.c index cbf9dc3cc51d..cbf9dc3cc51d 100644 --- a/arch/m68knommu/kernel/init_task.c +++ b/arch/m68k/kernel/init_task.c | |||
diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68k/kernel/irq.c index c7dd48f37bee..c7dd48f37bee 100644 --- a/arch/m68knommu/kernel/irq.c +++ b/arch/m68k/kernel/irq.c | |||
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index d900e77e5363..4752c28ce0ac 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c | |||
@@ -1,16 +1,5 @@ | |||
1 | #include <linux/module.h> | 1 | #ifdef CONFIG_MMU |
2 | 2 | #include "m68k_ksyms_mm.c" | |
3 | asmlinkage long long __ashldi3 (long long, int); | 3 | #else |
4 | asmlinkage long long __ashrdi3 (long long, int); | 4 | #include "m68k_ksyms_no.c" |
5 | asmlinkage long long __lshrdi3 (long long, int); | 5 | #endif |
6 | asmlinkage long long __muldi3 (long long, long long); | ||
7 | |||
8 | /* The following are special because they're not called | ||
9 | explicitly (the C compiler generates them). Fortunately, | ||
10 | their interface isn't gonna change any time soon now, so | ||
11 | it's OK to leave it out of version control. */ | ||
12 | EXPORT_SYMBOL(__ashldi3); | ||
13 | EXPORT_SYMBOL(__ashrdi3); | ||
14 | EXPORT_SYMBOL(__lshrdi3); | ||
15 | EXPORT_SYMBOL(__muldi3); | ||
16 | |||
diff --git a/arch/m68k/kernel/m68k_ksyms_mm.c b/arch/m68k/kernel/m68k_ksyms_mm.c new file mode 100644 index 000000000000..d900e77e5363 --- /dev/null +++ b/arch/m68k/kernel/m68k_ksyms_mm.c | |||
@@ -0,0 +1,16 @@ | |||
1 | #include <linux/module.h> | ||
2 | |||
3 | asmlinkage long long __ashldi3 (long long, int); | ||
4 | asmlinkage long long __ashrdi3 (long long, int); | ||
5 | asmlinkage long long __lshrdi3 (long long, int); | ||
6 | asmlinkage long long __muldi3 (long long, long long); | ||
7 | |||
8 | /* The following are special because they're not called | ||
9 | explicitly (the C compiler generates them). Fortunately, | ||
10 | their interface isn't gonna change any time soon now, so | ||
11 | it's OK to leave it out of version control. */ | ||
12 | EXPORT_SYMBOL(__ashldi3); | ||
13 | EXPORT_SYMBOL(__ashrdi3); | ||
14 | EXPORT_SYMBOL(__lshrdi3); | ||
15 | EXPORT_SYMBOL(__muldi3); | ||
16 | |||
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms_no.c index 39fe0a7aec32..39fe0a7aec32 100644 --- a/arch/m68knommu/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c | |||
diff --git a/arch/m68k/kernel/module.c b/arch/m68k/kernel/module.c index cd6bcb1c957e..7ea203ce6b1a 100644 --- a/arch/m68k/kernel/module.c +++ b/arch/m68k/kernel/module.c | |||
@@ -1,155 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * This file is subject to the terms and conditions of the GNU General Public | 2 | #include "module_mm.c" |
3 | * License. See the file COPYING in the main directory of this archive | ||
4 | * for more details. | ||
5 | */ | ||
6 | |||
7 | #include <linux/moduleloader.h> | ||
8 | #include <linux/elf.h> | ||
9 | #include <linux/vmalloc.h> | ||
10 | #include <linux/fs.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/kernel.h> | ||
13 | |||
14 | #if 0 | ||
15 | #define DEBUGP printk | ||
16 | #else | 3 | #else |
17 | #define DEBUGP(fmt...) | 4 | #include "module_no.c" |
18 | #endif | 5 | #endif |
19 | |||
20 | #ifdef CONFIG_MODULES | ||
21 | |||
22 | void *module_alloc(unsigned long size) | ||
23 | { | ||
24 | if (size == 0) | ||
25 | return NULL; | ||
26 | return vmalloc(size); | ||
27 | } | ||
28 | |||
29 | |||
30 | /* Free memory returned from module_alloc */ | ||
31 | void module_free(struct module *mod, void *module_region) | ||
32 | { | ||
33 | vfree(module_region); | ||
34 | } | ||
35 | |||
36 | /* We don't need anything special. */ | ||
37 | int module_frob_arch_sections(Elf_Ehdr *hdr, | ||
38 | Elf_Shdr *sechdrs, | ||
39 | char *secstrings, | ||
40 | struct module *mod) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | int apply_relocate(Elf32_Shdr *sechdrs, | ||
46 | const char *strtab, | ||
47 | unsigned int symindex, | ||
48 | unsigned int relsec, | ||
49 | struct module *me) | ||
50 | { | ||
51 | unsigned int i; | ||
52 | Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; | ||
53 | Elf32_Sym *sym; | ||
54 | uint32_t *location; | ||
55 | |||
56 | DEBUGP("Applying relocate section %u to %u\n", relsec, | ||
57 | sechdrs[relsec].sh_info); | ||
58 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { | ||
59 | /* This is where to make the change */ | ||
60 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | ||
61 | + rel[i].r_offset; | ||
62 | /* This is the symbol it is referring to. Note that all | ||
63 | undefined symbols have been resolved. */ | ||
64 | sym = (Elf32_Sym *)sechdrs[symindex].sh_addr | ||
65 | + ELF32_R_SYM(rel[i].r_info); | ||
66 | |||
67 | switch (ELF32_R_TYPE(rel[i].r_info)) { | ||
68 | case R_68K_32: | ||
69 | /* We add the value into the location given */ | ||
70 | *location += sym->st_value; | ||
71 | break; | ||
72 | case R_68K_PC32: | ||
73 | /* Add the value, subtract its postition */ | ||
74 | *location += sym->st_value - (uint32_t)location; | ||
75 | break; | ||
76 | default: | ||
77 | printk(KERN_ERR "module %s: Unknown relocation: %u\n", | ||
78 | me->name, ELF32_R_TYPE(rel[i].r_info)); | ||
79 | return -ENOEXEC; | ||
80 | } | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | int apply_relocate_add(Elf32_Shdr *sechdrs, | ||
86 | const char *strtab, | ||
87 | unsigned int symindex, | ||
88 | unsigned int relsec, | ||
89 | struct module *me) | ||
90 | { | ||
91 | unsigned int i; | ||
92 | Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; | ||
93 | Elf32_Sym *sym; | ||
94 | uint32_t *location; | ||
95 | |||
96 | DEBUGP("Applying relocate_add section %u to %u\n", relsec, | ||
97 | sechdrs[relsec].sh_info); | ||
98 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { | ||
99 | /* This is where to make the change */ | ||
100 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | ||
101 | + rel[i].r_offset; | ||
102 | /* This is the symbol it is referring to. Note that all | ||
103 | undefined symbols have been resolved. */ | ||
104 | sym = (Elf32_Sym *)sechdrs[symindex].sh_addr | ||
105 | + ELF32_R_SYM(rel[i].r_info); | ||
106 | |||
107 | switch (ELF32_R_TYPE(rel[i].r_info)) { | ||
108 | case R_68K_32: | ||
109 | /* We add the value into the location given */ | ||
110 | *location = rel[i].r_addend + sym->st_value; | ||
111 | break; | ||
112 | case R_68K_PC32: | ||
113 | /* Add the value, subtract its postition */ | ||
114 | *location = rel[i].r_addend + sym->st_value - (uint32_t)location; | ||
115 | break; | ||
116 | default: | ||
117 | printk(KERN_ERR "module %s: Unknown relocation: %u\n", | ||
118 | me->name, ELF32_R_TYPE(rel[i].r_info)); | ||
119 | return -ENOEXEC; | ||
120 | } | ||
121 | } | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | int module_finalize(const Elf_Ehdr *hdr, | ||
126 | const Elf_Shdr *sechdrs, | ||
127 | struct module *mod) | ||
128 | { | ||
129 | module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | void module_arch_cleanup(struct module *mod) | ||
135 | { | ||
136 | } | ||
137 | |||
138 | #endif /* CONFIG_MODULES */ | ||
139 | |||
140 | void module_fixup(struct module *mod, struct m68k_fixup_info *start, | ||
141 | struct m68k_fixup_info *end) | ||
142 | { | ||
143 | struct m68k_fixup_info *fixup; | ||
144 | |||
145 | for (fixup = start; fixup < end; fixup++) { | ||
146 | switch (fixup->type) { | ||
147 | case m68k_fixup_memoffset: | ||
148 | *(u32 *)fixup->addr = m68k_memoffset; | ||
149 | break; | ||
150 | case m68k_fixup_vnode_shift: | ||
151 | *(u16 *)fixup->addr += m68k_virt_to_node_shift; | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | } | ||
diff --git a/arch/m68k/kernel/module_mm.c b/arch/m68k/kernel/module_mm.c new file mode 100644 index 000000000000..cd6bcb1c957e --- /dev/null +++ b/arch/m68k/kernel/module_mm.c | |||
@@ -0,0 +1,155 @@ | |||
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 | |||
7 | #include <linux/moduleloader.h> | ||
8 | #include <linux/elf.h> | ||
9 | #include <linux/vmalloc.h> | ||
10 | #include <linux/fs.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/kernel.h> | ||
13 | |||
14 | #if 0 | ||
15 | #define DEBUGP printk | ||
16 | #else | ||
17 | #define DEBUGP(fmt...) | ||
18 | #endif | ||
19 | |||
20 | #ifdef CONFIG_MODULES | ||
21 | |||
22 | void *module_alloc(unsigned long size) | ||
23 | { | ||
24 | if (size == 0) | ||
25 | return NULL; | ||
26 | return vmalloc(size); | ||
27 | } | ||
28 | |||
29 | |||
30 | /* Free memory returned from module_alloc */ | ||
31 | void module_free(struct module *mod, void *module_region) | ||
32 | { | ||
33 | vfree(module_region); | ||
34 | } | ||
35 | |||
36 | /* We don't need anything special. */ | ||
37 | int module_frob_arch_sections(Elf_Ehdr *hdr, | ||
38 | Elf_Shdr *sechdrs, | ||
39 | char *secstrings, | ||
40 | struct module *mod) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | int apply_relocate(Elf32_Shdr *sechdrs, | ||
46 | const char *strtab, | ||
47 | unsigned int symindex, | ||
48 | unsigned int relsec, | ||
49 | struct module *me) | ||
50 | { | ||
51 | unsigned int i; | ||
52 | Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; | ||
53 | Elf32_Sym *sym; | ||
54 | uint32_t *location; | ||
55 | |||
56 | DEBUGP("Applying relocate section %u to %u\n", relsec, | ||
57 | sechdrs[relsec].sh_info); | ||
58 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { | ||
59 | /* This is where to make the change */ | ||
60 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | ||
61 | + rel[i].r_offset; | ||
62 | /* This is the symbol it is referring to. Note that all | ||
63 | undefined symbols have been resolved. */ | ||
64 | sym = (Elf32_Sym *)sechdrs[symindex].sh_addr | ||
65 | + ELF32_R_SYM(rel[i].r_info); | ||
66 | |||
67 | switch (ELF32_R_TYPE(rel[i].r_info)) { | ||
68 | case R_68K_32: | ||
69 | /* We add the value into the location given */ | ||
70 | *location += sym->st_value; | ||
71 | break; | ||
72 | case R_68K_PC32: | ||
73 | /* Add the value, subtract its postition */ | ||
74 | *location += sym->st_value - (uint32_t)location; | ||
75 | break; | ||
76 | default: | ||
77 | printk(KERN_ERR "module %s: Unknown relocation: %u\n", | ||
78 | me->name, ELF32_R_TYPE(rel[i].r_info)); | ||
79 | return -ENOEXEC; | ||
80 | } | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | int apply_relocate_add(Elf32_Shdr *sechdrs, | ||
86 | const char *strtab, | ||
87 | unsigned int symindex, | ||
88 | unsigned int relsec, | ||
89 | struct module *me) | ||
90 | { | ||
91 | unsigned int i; | ||
92 | Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; | ||
93 | Elf32_Sym *sym; | ||
94 | uint32_t *location; | ||
95 | |||
96 | DEBUGP("Applying relocate_add section %u to %u\n", relsec, | ||
97 | sechdrs[relsec].sh_info); | ||
98 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { | ||
99 | /* This is where to make the change */ | ||
100 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | ||
101 | + rel[i].r_offset; | ||
102 | /* This is the symbol it is referring to. Note that all | ||
103 | undefined symbols have been resolved. */ | ||
104 | sym = (Elf32_Sym *)sechdrs[symindex].sh_addr | ||
105 | + ELF32_R_SYM(rel[i].r_info); | ||
106 | |||
107 | switch (ELF32_R_TYPE(rel[i].r_info)) { | ||
108 | case R_68K_32: | ||
109 | /* We add the value into the location given */ | ||
110 | *location = rel[i].r_addend + sym->st_value; | ||
111 | break; | ||
112 | case R_68K_PC32: | ||
113 | /* Add the value, subtract its postition */ | ||
114 | *location = rel[i].r_addend + sym->st_value - (uint32_t)location; | ||
115 | break; | ||
116 | default: | ||
117 | printk(KERN_ERR "module %s: Unknown relocation: %u\n", | ||
118 | me->name, ELF32_R_TYPE(rel[i].r_info)); | ||
119 | return -ENOEXEC; | ||
120 | } | ||
121 | } | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | int module_finalize(const Elf_Ehdr *hdr, | ||
126 | const Elf_Shdr *sechdrs, | ||
127 | struct module *mod) | ||
128 | { | ||
129 | module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | void module_arch_cleanup(struct module *mod) | ||
135 | { | ||
136 | } | ||
137 | |||
138 | #endif /* CONFIG_MODULES */ | ||
139 | |||
140 | void module_fixup(struct module *mod, struct m68k_fixup_info *start, | ||
141 | struct m68k_fixup_info *end) | ||
142 | { | ||
143 | struct m68k_fixup_info *fixup; | ||
144 | |||
145 | for (fixup = start; fixup < end; fixup++) { | ||
146 | switch (fixup->type) { | ||
147 | case m68k_fixup_memoffset: | ||
148 | *(u32 *)fixup->addr = m68k_memoffset; | ||
149 | break; | ||
150 | case m68k_fixup_vnode_shift: | ||
151 | *(u16 *)fixup->addr += m68k_virt_to_node_shift; | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | } | ||
diff --git a/arch/m68knommu/kernel/module.c b/arch/m68k/kernel/module_no.c index d11ffae7956a..d11ffae7956a 100644 --- a/arch/m68knommu/kernel/module.c +++ b/arch/m68k/kernel/module_no.c | |||
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index c2a1fc23dd75..6cf4bd6e34f8 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c | |||
@@ -1,354 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/kernel/process.c | 2 | #include "process_mm.c" |
3 | * | ||
4 | * Copyright (C) 1995 Hamish Macdonald | ||
5 | * | ||
6 | * 68060 fixes by Jesper Skov | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This file handles the architecture-dependent parts of process handling.. | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/mm.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/fs.h> | ||
20 | #include <linux/smp.h> | ||
21 | #include <linux/stddef.h> | ||
22 | #include <linux/unistd.h> | ||
23 | #include <linux/ptrace.h> | ||
24 | #include <linux/user.h> | ||
25 | #include <linux/reboot.h> | ||
26 | #include <linux/init_task.h> | ||
27 | #include <linux/mqueue.h> | ||
28 | |||
29 | #include <asm/uaccess.h> | ||
30 | #include <asm/system.h> | ||
31 | #include <asm/traps.h> | ||
32 | #include <asm/machdep.h> | ||
33 | #include <asm/setup.h> | ||
34 | #include <asm/pgtable.h> | ||
35 | |||
36 | /* | ||
37 | * Initial task/thread structure. Make this a per-architecture thing, | ||
38 | * because different architectures tend to have different | ||
39 | * alignment requirements and potentially different initial | ||
40 | * setup. | ||
41 | */ | ||
42 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | ||
43 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | ||
44 | union thread_union init_thread_union __init_task_data | ||
45 | __attribute__((aligned(THREAD_SIZE))) = | ||
46 | { INIT_THREAD_INFO(init_task) }; | ||
47 | |||
48 | /* initial task structure */ | ||
49 | struct task_struct init_task = INIT_TASK(init_task); | ||
50 | |||
51 | EXPORT_SYMBOL(init_task); | ||
52 | |||
53 | asmlinkage void ret_from_fork(void); | ||
54 | |||
55 | |||
56 | /* | ||
57 | * Return saved PC from a blocked thread | ||
58 | */ | ||
59 | unsigned long thread_saved_pc(struct task_struct *tsk) | ||
60 | { | ||
61 | struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp; | ||
62 | /* Check whether the thread is blocked in resume() */ | ||
63 | if (in_sched_functions(sw->retpc)) | ||
64 | return ((unsigned long *)sw->a6)[1]; | ||
65 | else | ||
66 | return sw->retpc; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * The idle loop on an m68k.. | ||
71 | */ | ||
72 | static void default_idle(void) | ||
73 | { | ||
74 | if (!need_resched()) | ||
75 | #if defined(MACH_ATARI_ONLY) | ||
76 | /* block out HSYNC on the atari (falcon) */ | ||
77 | __asm__("stop #0x2200" : : : "cc"); | ||
78 | #else | 3 | #else |
79 | __asm__("stop #0x2000" : : : "cc"); | 4 | #include "process_no.c" |
80 | #endif | 5 | #endif |
81 | } | ||
82 | |||
83 | void (*idle)(void) = default_idle; | ||
84 | |||
85 | /* | ||
86 | * The idle thread. There's no useful work to be | ||
87 | * done, so just try to conserve power and have a | ||
88 | * low exit latency (ie sit in a loop waiting for | ||
89 | * somebody to say that they'd like to reschedule) | ||
90 | */ | ||
91 | void cpu_idle(void) | ||
92 | { | ||
93 | /* endless idle loop with no priority at all */ | ||
94 | while (1) { | ||
95 | while (!need_resched()) | ||
96 | idle(); | ||
97 | preempt_enable_no_resched(); | ||
98 | schedule(); | ||
99 | preempt_disable(); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | void machine_restart(char * __unused) | ||
104 | { | ||
105 | if (mach_reset) | ||
106 | mach_reset(); | ||
107 | for (;;); | ||
108 | } | ||
109 | |||
110 | void machine_halt(void) | ||
111 | { | ||
112 | if (mach_halt) | ||
113 | mach_halt(); | ||
114 | for (;;); | ||
115 | } | ||
116 | |||
117 | void machine_power_off(void) | ||
118 | { | ||
119 | if (mach_power_off) | ||
120 | mach_power_off(); | ||
121 | for (;;); | ||
122 | } | ||
123 | |||
124 | void (*pm_power_off)(void) = machine_power_off; | ||
125 | EXPORT_SYMBOL(pm_power_off); | ||
126 | |||
127 | void show_regs(struct pt_regs * regs) | ||
128 | { | ||
129 | printk("\n"); | ||
130 | printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n", | ||
131 | regs->format, regs->vector, regs->pc, regs->sr, print_tainted()); | ||
132 | printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n", | ||
133 | regs->orig_d0, regs->d0, regs->a2, regs->a1); | ||
134 | printk("A0: %08lx D5: %08lx D4: %08lx\n", | ||
135 | regs->a0, regs->d5, regs->d4); | ||
136 | printk("D3: %08lx D2: %08lx D1: %08lx\n", | ||
137 | regs->d3, regs->d2, regs->d1); | ||
138 | if (!(regs->sr & PS_S)) | ||
139 | printk("USP: %08lx\n", rdusp()); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Create a kernel thread | ||
144 | */ | ||
145 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
146 | { | ||
147 | int pid; | ||
148 | mm_segment_t fs; | ||
149 | |||
150 | fs = get_fs(); | ||
151 | set_fs (KERNEL_DS); | ||
152 | |||
153 | { | ||
154 | register long retval __asm__ ("d0"); | ||
155 | register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED; | ||
156 | |||
157 | retval = __NR_clone; | ||
158 | __asm__ __volatile__ | ||
159 | ("clrl %%d2\n\t" | ||
160 | "trap #0\n\t" /* Linux/m68k system call */ | ||
161 | "tstl %0\n\t" /* child or parent */ | ||
162 | "jne 1f\n\t" /* parent - jump */ | ||
163 | "lea %%sp@(%c7),%6\n\t" /* reload current */ | ||
164 | "movel %6@,%6\n\t" | ||
165 | "movel %3,%%sp@-\n\t" /* push argument */ | ||
166 | "jsr %4@\n\t" /* call fn */ | ||
167 | "movel %0,%%d1\n\t" /* pass exit value */ | ||
168 | "movel %2,%%d0\n\t" /* exit */ | ||
169 | "trap #0\n" | ||
170 | "1:" | ||
171 | : "+d" (retval) | ||
172 | : "i" (__NR_clone), "i" (__NR_exit), | ||
173 | "r" (arg), "a" (fn), "d" (clone_arg), "r" (current), | ||
174 | "i" (-THREAD_SIZE) | ||
175 | : "d2"); | ||
176 | |||
177 | pid = retval; | ||
178 | } | ||
179 | |||
180 | set_fs (fs); | ||
181 | return pid; | ||
182 | } | ||
183 | EXPORT_SYMBOL(kernel_thread); | ||
184 | |||
185 | void flush_thread(void) | ||
186 | { | ||
187 | unsigned long zero = 0; | ||
188 | set_fs(USER_DS); | ||
189 | current->thread.fs = __USER_DS; | ||
190 | if (!FPU_IS_EMU) | ||
191 | asm volatile (".chip 68k/68881\n\t" | ||
192 | "frestore %0@\n\t" | ||
193 | ".chip 68k" : : "a" (&zero)); | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * "m68k_fork()".. By the time we get here, the | ||
198 | * non-volatile registers have also been saved on the | ||
199 | * stack. We do some ugly pointer stuff here.. (see | ||
200 | * also copy_thread) | ||
201 | */ | ||
202 | |||
203 | asmlinkage int m68k_fork(struct pt_regs *regs) | ||
204 | { | ||
205 | return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); | ||
206 | } | ||
207 | |||
208 | asmlinkage int m68k_vfork(struct pt_regs *regs) | ||
209 | { | ||
210 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, | ||
211 | NULL, NULL); | ||
212 | } | ||
213 | |||
214 | asmlinkage int m68k_clone(struct pt_regs *regs) | ||
215 | { | ||
216 | unsigned long clone_flags; | ||
217 | unsigned long newsp; | ||
218 | int __user *parent_tidptr, *child_tidptr; | ||
219 | |||
220 | /* syscall2 puts clone_flags in d1 and usp in d2 */ | ||
221 | clone_flags = regs->d1; | ||
222 | newsp = regs->d2; | ||
223 | parent_tidptr = (int __user *)regs->d3; | ||
224 | child_tidptr = (int __user *)regs->d4; | ||
225 | if (!newsp) | ||
226 | newsp = rdusp(); | ||
227 | return do_fork(clone_flags, newsp, regs, 0, | ||
228 | parent_tidptr, child_tidptr); | ||
229 | } | ||
230 | |||
231 | int copy_thread(unsigned long clone_flags, unsigned long usp, | ||
232 | unsigned long unused, | ||
233 | struct task_struct * p, struct pt_regs * regs) | ||
234 | { | ||
235 | struct pt_regs * childregs; | ||
236 | struct switch_stack * childstack, *stack; | ||
237 | unsigned long *retp; | ||
238 | |||
239 | childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; | ||
240 | |||
241 | *childregs = *regs; | ||
242 | childregs->d0 = 0; | ||
243 | |||
244 | retp = ((unsigned long *) regs); | ||
245 | stack = ((struct switch_stack *) retp) - 1; | ||
246 | |||
247 | childstack = ((struct switch_stack *) childregs) - 1; | ||
248 | *childstack = *stack; | ||
249 | childstack->retpc = (unsigned long)ret_from_fork; | ||
250 | |||
251 | p->thread.usp = usp; | ||
252 | p->thread.ksp = (unsigned long)childstack; | ||
253 | |||
254 | if (clone_flags & CLONE_SETTLS) | ||
255 | task_thread_info(p)->tp_value = regs->d5; | ||
256 | |||
257 | /* | ||
258 | * Must save the current SFC/DFC value, NOT the value when | ||
259 | * the parent was last descheduled - RGH 10-08-96 | ||
260 | */ | ||
261 | p->thread.fs = get_fs().seg; | ||
262 | |||
263 | if (!FPU_IS_EMU) { | ||
264 | /* Copy the current fpu state */ | ||
265 | asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); | ||
266 | |||
267 | if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) | ||
268 | asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" | ||
269 | "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" | ||
270 | : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) | ||
271 | : "memory"); | ||
272 | /* Restore the state in case the fpu was busy */ | ||
273 | asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); | ||
274 | } | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* Fill in the fpu structure for a core dump. */ | ||
280 | |||
281 | int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) | ||
282 | { | ||
283 | char fpustate[216]; | ||
284 | |||
285 | if (FPU_IS_EMU) { | ||
286 | int i; | ||
287 | |||
288 | memcpy(fpu->fpcntl, current->thread.fpcntl, 12); | ||
289 | memcpy(fpu->fpregs, current->thread.fp, 96); | ||
290 | /* Convert internal fpu reg representation | ||
291 | * into long double format | ||
292 | */ | ||
293 | for (i = 0; i < 24; i += 3) | ||
294 | fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) | | ||
295 | ((fpu->fpregs[i] & 0x0000ffff) << 16); | ||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | /* First dump the fpu context to avoid protocol violation. */ | ||
300 | asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); | ||
301 | if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) | ||
302 | return 0; | ||
303 | |||
304 | asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" | ||
305 | :: "m" (fpu->fpcntl[0]) | ||
306 | : "memory"); | ||
307 | asm volatile ("fmovemx %/fp0-%/fp7,%0" | ||
308 | :: "m" (fpu->fpregs[0]) | ||
309 | : "memory"); | ||
310 | return 1; | ||
311 | } | ||
312 | EXPORT_SYMBOL(dump_fpu); | ||
313 | |||
314 | /* | ||
315 | * sys_execve() executes a new program. | ||
316 | */ | ||
317 | asmlinkage int sys_execve(const char __user *name, | ||
318 | const char __user *const __user *argv, | ||
319 | const char __user *const __user *envp) | ||
320 | { | ||
321 | int error; | ||
322 | char * filename; | ||
323 | struct pt_regs *regs = (struct pt_regs *) &name; | ||
324 | |||
325 | filename = getname(name); | ||
326 | error = PTR_ERR(filename); | ||
327 | if (IS_ERR(filename)) | ||
328 | return error; | ||
329 | error = do_execve(filename, argv, envp, regs); | ||
330 | putname(filename); | ||
331 | return error; | ||
332 | } | ||
333 | |||
334 | unsigned long get_wchan(struct task_struct *p) | ||
335 | { | ||
336 | unsigned long fp, pc; | ||
337 | unsigned long stack_page; | ||
338 | int count = 0; | ||
339 | if (!p || p == current || p->state == TASK_RUNNING) | ||
340 | return 0; | ||
341 | |||
342 | stack_page = (unsigned long)task_stack_page(p); | ||
343 | fp = ((struct switch_stack *)p->thread.ksp)->a6; | ||
344 | do { | ||
345 | if (fp < stack_page+sizeof(struct thread_info) || | ||
346 | fp >= 8184+stack_page) | ||
347 | return 0; | ||
348 | pc = ((unsigned long *)fp)[1]; | ||
349 | if (!in_sched_functions(pc)) | ||
350 | return pc; | ||
351 | fp = *(unsigned long *) fp; | ||
352 | } while (count++ < 16); | ||
353 | return 0; | ||
354 | } | ||
diff --git a/arch/m68k/kernel/process_mm.c b/arch/m68k/kernel/process_mm.c new file mode 100644 index 000000000000..c2a1fc23dd75 --- /dev/null +++ b/arch/m68k/kernel/process_mm.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/kernel/process.c | ||
3 | * | ||
4 | * Copyright (C) 1995 Hamish Macdonald | ||
5 | * | ||
6 | * 68060 fixes by Jesper Skov | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This file handles the architecture-dependent parts of process handling.. | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/mm.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/fs.h> | ||
20 | #include <linux/smp.h> | ||
21 | #include <linux/stddef.h> | ||
22 | #include <linux/unistd.h> | ||
23 | #include <linux/ptrace.h> | ||
24 | #include <linux/user.h> | ||
25 | #include <linux/reboot.h> | ||
26 | #include <linux/init_task.h> | ||
27 | #include <linux/mqueue.h> | ||
28 | |||
29 | #include <asm/uaccess.h> | ||
30 | #include <asm/system.h> | ||
31 | #include <asm/traps.h> | ||
32 | #include <asm/machdep.h> | ||
33 | #include <asm/setup.h> | ||
34 | #include <asm/pgtable.h> | ||
35 | |||
36 | /* | ||
37 | * Initial task/thread structure. Make this a per-architecture thing, | ||
38 | * because different architectures tend to have different | ||
39 | * alignment requirements and potentially different initial | ||
40 | * setup. | ||
41 | */ | ||
42 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | ||
43 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | ||
44 | union thread_union init_thread_union __init_task_data | ||
45 | __attribute__((aligned(THREAD_SIZE))) = | ||
46 | { INIT_THREAD_INFO(init_task) }; | ||
47 | |||
48 | /* initial task structure */ | ||
49 | struct task_struct init_task = INIT_TASK(init_task); | ||
50 | |||
51 | EXPORT_SYMBOL(init_task); | ||
52 | |||
53 | asmlinkage void ret_from_fork(void); | ||
54 | |||
55 | |||
56 | /* | ||
57 | * Return saved PC from a blocked thread | ||
58 | */ | ||
59 | unsigned long thread_saved_pc(struct task_struct *tsk) | ||
60 | { | ||
61 | struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp; | ||
62 | /* Check whether the thread is blocked in resume() */ | ||
63 | if (in_sched_functions(sw->retpc)) | ||
64 | return ((unsigned long *)sw->a6)[1]; | ||
65 | else | ||
66 | return sw->retpc; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * The idle loop on an m68k.. | ||
71 | */ | ||
72 | static void default_idle(void) | ||
73 | { | ||
74 | if (!need_resched()) | ||
75 | #if defined(MACH_ATARI_ONLY) | ||
76 | /* block out HSYNC on the atari (falcon) */ | ||
77 | __asm__("stop #0x2200" : : : "cc"); | ||
78 | #else | ||
79 | __asm__("stop #0x2000" : : : "cc"); | ||
80 | #endif | ||
81 | } | ||
82 | |||
83 | void (*idle)(void) = default_idle; | ||
84 | |||
85 | /* | ||
86 | * The idle thread. There's no useful work to be | ||
87 | * done, so just try to conserve power and have a | ||
88 | * low exit latency (ie sit in a loop waiting for | ||
89 | * somebody to say that they'd like to reschedule) | ||
90 | */ | ||
91 | void cpu_idle(void) | ||
92 | { | ||
93 | /* endless idle loop with no priority at all */ | ||
94 | while (1) { | ||
95 | while (!need_resched()) | ||
96 | idle(); | ||
97 | preempt_enable_no_resched(); | ||
98 | schedule(); | ||
99 | preempt_disable(); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | void machine_restart(char * __unused) | ||
104 | { | ||
105 | if (mach_reset) | ||
106 | mach_reset(); | ||
107 | for (;;); | ||
108 | } | ||
109 | |||
110 | void machine_halt(void) | ||
111 | { | ||
112 | if (mach_halt) | ||
113 | mach_halt(); | ||
114 | for (;;); | ||
115 | } | ||
116 | |||
117 | void machine_power_off(void) | ||
118 | { | ||
119 | if (mach_power_off) | ||
120 | mach_power_off(); | ||
121 | for (;;); | ||
122 | } | ||
123 | |||
124 | void (*pm_power_off)(void) = machine_power_off; | ||
125 | EXPORT_SYMBOL(pm_power_off); | ||
126 | |||
127 | void show_regs(struct pt_regs * regs) | ||
128 | { | ||
129 | printk("\n"); | ||
130 | printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n", | ||
131 | regs->format, regs->vector, regs->pc, regs->sr, print_tainted()); | ||
132 | printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n", | ||
133 | regs->orig_d0, regs->d0, regs->a2, regs->a1); | ||
134 | printk("A0: %08lx D5: %08lx D4: %08lx\n", | ||
135 | regs->a0, regs->d5, regs->d4); | ||
136 | printk("D3: %08lx D2: %08lx D1: %08lx\n", | ||
137 | regs->d3, regs->d2, regs->d1); | ||
138 | if (!(regs->sr & PS_S)) | ||
139 | printk("USP: %08lx\n", rdusp()); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Create a kernel thread | ||
144 | */ | ||
145 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
146 | { | ||
147 | int pid; | ||
148 | mm_segment_t fs; | ||
149 | |||
150 | fs = get_fs(); | ||
151 | set_fs (KERNEL_DS); | ||
152 | |||
153 | { | ||
154 | register long retval __asm__ ("d0"); | ||
155 | register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED; | ||
156 | |||
157 | retval = __NR_clone; | ||
158 | __asm__ __volatile__ | ||
159 | ("clrl %%d2\n\t" | ||
160 | "trap #0\n\t" /* Linux/m68k system call */ | ||
161 | "tstl %0\n\t" /* child or parent */ | ||
162 | "jne 1f\n\t" /* parent - jump */ | ||
163 | "lea %%sp@(%c7),%6\n\t" /* reload current */ | ||
164 | "movel %6@,%6\n\t" | ||
165 | "movel %3,%%sp@-\n\t" /* push argument */ | ||
166 | "jsr %4@\n\t" /* call fn */ | ||
167 | "movel %0,%%d1\n\t" /* pass exit value */ | ||
168 | "movel %2,%%d0\n\t" /* exit */ | ||
169 | "trap #0\n" | ||
170 | "1:" | ||
171 | : "+d" (retval) | ||
172 | : "i" (__NR_clone), "i" (__NR_exit), | ||
173 | "r" (arg), "a" (fn), "d" (clone_arg), "r" (current), | ||
174 | "i" (-THREAD_SIZE) | ||
175 | : "d2"); | ||
176 | |||
177 | pid = retval; | ||
178 | } | ||
179 | |||
180 | set_fs (fs); | ||
181 | return pid; | ||
182 | } | ||
183 | EXPORT_SYMBOL(kernel_thread); | ||
184 | |||
185 | void flush_thread(void) | ||
186 | { | ||
187 | unsigned long zero = 0; | ||
188 | set_fs(USER_DS); | ||
189 | current->thread.fs = __USER_DS; | ||
190 | if (!FPU_IS_EMU) | ||
191 | asm volatile (".chip 68k/68881\n\t" | ||
192 | "frestore %0@\n\t" | ||
193 | ".chip 68k" : : "a" (&zero)); | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * "m68k_fork()".. By the time we get here, the | ||
198 | * non-volatile registers have also been saved on the | ||
199 | * stack. We do some ugly pointer stuff here.. (see | ||
200 | * also copy_thread) | ||
201 | */ | ||
202 | |||
203 | asmlinkage int m68k_fork(struct pt_regs *regs) | ||
204 | { | ||
205 | return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); | ||
206 | } | ||
207 | |||
208 | asmlinkage int m68k_vfork(struct pt_regs *regs) | ||
209 | { | ||
210 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, | ||
211 | NULL, NULL); | ||
212 | } | ||
213 | |||
214 | asmlinkage int m68k_clone(struct pt_regs *regs) | ||
215 | { | ||
216 | unsigned long clone_flags; | ||
217 | unsigned long newsp; | ||
218 | int __user *parent_tidptr, *child_tidptr; | ||
219 | |||
220 | /* syscall2 puts clone_flags in d1 and usp in d2 */ | ||
221 | clone_flags = regs->d1; | ||
222 | newsp = regs->d2; | ||
223 | parent_tidptr = (int __user *)regs->d3; | ||
224 | child_tidptr = (int __user *)regs->d4; | ||
225 | if (!newsp) | ||
226 | newsp = rdusp(); | ||
227 | return do_fork(clone_flags, newsp, regs, 0, | ||
228 | parent_tidptr, child_tidptr); | ||
229 | } | ||
230 | |||
231 | int copy_thread(unsigned long clone_flags, unsigned long usp, | ||
232 | unsigned long unused, | ||
233 | struct task_struct * p, struct pt_regs * regs) | ||
234 | { | ||
235 | struct pt_regs * childregs; | ||
236 | struct switch_stack * childstack, *stack; | ||
237 | unsigned long *retp; | ||
238 | |||
239 | childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; | ||
240 | |||
241 | *childregs = *regs; | ||
242 | childregs->d0 = 0; | ||
243 | |||
244 | retp = ((unsigned long *) regs); | ||
245 | stack = ((struct switch_stack *) retp) - 1; | ||
246 | |||
247 | childstack = ((struct switch_stack *) childregs) - 1; | ||
248 | *childstack = *stack; | ||
249 | childstack->retpc = (unsigned long)ret_from_fork; | ||
250 | |||
251 | p->thread.usp = usp; | ||
252 | p->thread.ksp = (unsigned long)childstack; | ||
253 | |||
254 | if (clone_flags & CLONE_SETTLS) | ||
255 | task_thread_info(p)->tp_value = regs->d5; | ||
256 | |||
257 | /* | ||
258 | * Must save the current SFC/DFC value, NOT the value when | ||
259 | * the parent was last descheduled - RGH 10-08-96 | ||
260 | */ | ||
261 | p->thread.fs = get_fs().seg; | ||
262 | |||
263 | if (!FPU_IS_EMU) { | ||
264 | /* Copy the current fpu state */ | ||
265 | asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); | ||
266 | |||
267 | if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) | ||
268 | asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" | ||
269 | "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" | ||
270 | : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) | ||
271 | : "memory"); | ||
272 | /* Restore the state in case the fpu was busy */ | ||
273 | asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); | ||
274 | } | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* Fill in the fpu structure for a core dump. */ | ||
280 | |||
281 | int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) | ||
282 | { | ||
283 | char fpustate[216]; | ||
284 | |||
285 | if (FPU_IS_EMU) { | ||
286 | int i; | ||
287 | |||
288 | memcpy(fpu->fpcntl, current->thread.fpcntl, 12); | ||
289 | memcpy(fpu->fpregs, current->thread.fp, 96); | ||
290 | /* Convert internal fpu reg representation | ||
291 | * into long double format | ||
292 | */ | ||
293 | for (i = 0; i < 24; i += 3) | ||
294 | fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) | | ||
295 | ((fpu->fpregs[i] & 0x0000ffff) << 16); | ||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | /* First dump the fpu context to avoid protocol violation. */ | ||
300 | asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); | ||
301 | if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) | ||
302 | return 0; | ||
303 | |||
304 | asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" | ||
305 | :: "m" (fpu->fpcntl[0]) | ||
306 | : "memory"); | ||
307 | asm volatile ("fmovemx %/fp0-%/fp7,%0" | ||
308 | :: "m" (fpu->fpregs[0]) | ||
309 | : "memory"); | ||
310 | return 1; | ||
311 | } | ||
312 | EXPORT_SYMBOL(dump_fpu); | ||
313 | |||
314 | /* | ||
315 | * sys_execve() executes a new program. | ||
316 | */ | ||
317 | asmlinkage int sys_execve(const char __user *name, | ||
318 | const char __user *const __user *argv, | ||
319 | const char __user *const __user *envp) | ||
320 | { | ||
321 | int error; | ||
322 | char * filename; | ||
323 | struct pt_regs *regs = (struct pt_regs *) &name; | ||
324 | |||
325 | filename = getname(name); | ||
326 | error = PTR_ERR(filename); | ||
327 | if (IS_ERR(filename)) | ||
328 | return error; | ||
329 | error = do_execve(filename, argv, envp, regs); | ||
330 | putname(filename); | ||
331 | return error; | ||
332 | } | ||
333 | |||
334 | unsigned long get_wchan(struct task_struct *p) | ||
335 | { | ||
336 | unsigned long fp, pc; | ||
337 | unsigned long stack_page; | ||
338 | int count = 0; | ||
339 | if (!p || p == current || p->state == TASK_RUNNING) | ||
340 | return 0; | ||
341 | |||
342 | stack_page = (unsigned long)task_stack_page(p); | ||
343 | fp = ((struct switch_stack *)p->thread.ksp)->a6; | ||
344 | do { | ||
345 | if (fp < stack_page+sizeof(struct thread_info) || | ||
346 | fp >= 8184+stack_page) | ||
347 | return 0; | ||
348 | pc = ((unsigned long *)fp)[1]; | ||
349 | if (!in_sched_functions(pc)) | ||
350 | return pc; | ||
351 | fp = *(unsigned long *) fp; | ||
352 | } while (count++ < 16); | ||
353 | return 0; | ||
354 | } | ||
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68k/kernel/process_no.c index e2a63af5d517..e2a63af5d517 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68k/kernel/process_no.c | |||
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index 0b252683cefb..07a417550e94 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c | |||
@@ -1,277 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/kernel/ptrace.c | 2 | #include "ptrace_mm.c" |
3 | * | 3 | #else |
4 | * Copyright (C) 1994 by Hamish Macdonald | 4 | #include "ptrace_no.c" |
5 | * Taken from linux/kernel/ptrace.c and modified for M680x0. | 5 | #endif |
6 | * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of | ||
10 | * this archive for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/ptrace.h> | ||
19 | #include <linux/user.h> | ||
20 | #include <linux/signal.h> | ||
21 | |||
22 | #include <asm/uaccess.h> | ||
23 | #include <asm/page.h> | ||
24 | #include <asm/pgtable.h> | ||
25 | #include <asm/system.h> | ||
26 | #include <asm/processor.h> | ||
27 | |||
28 | /* | ||
29 | * does not yet catch signals sent when the child dies. | ||
30 | * in exit.c or in signal.c. | ||
31 | */ | ||
32 | |||
33 | /* determines which bits in the SR the user has access to. */ | ||
34 | /* 1 = access 0 = no access */ | ||
35 | #define SR_MASK 0x001f | ||
36 | |||
37 | /* sets the trace bits. */ | ||
38 | #define TRACE_BITS 0xC000 | ||
39 | #define T1_BIT 0x8000 | ||
40 | #define T0_BIT 0x4000 | ||
41 | |||
42 | /* Find the stack offset for a register, relative to thread.esp0. */ | ||
43 | #define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) | ||
44 | #define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \ | ||
45 | - sizeof(struct switch_stack)) | ||
46 | /* Mapping from PT_xxx to the stack offset at which the register is | ||
47 | saved. Notice that usp has no stack-slot and needs to be treated | ||
48 | specially (see get_reg/put_reg below). */ | ||
49 | static const int regoff[] = { | ||
50 | [0] = PT_REG(d1), | ||
51 | [1] = PT_REG(d2), | ||
52 | [2] = PT_REG(d3), | ||
53 | [3] = PT_REG(d4), | ||
54 | [4] = PT_REG(d5), | ||
55 | [5] = SW_REG(d6), | ||
56 | [6] = SW_REG(d7), | ||
57 | [7] = PT_REG(a0), | ||
58 | [8] = PT_REG(a1), | ||
59 | [9] = PT_REG(a2), | ||
60 | [10] = SW_REG(a3), | ||
61 | [11] = SW_REG(a4), | ||
62 | [12] = SW_REG(a5), | ||
63 | [13] = SW_REG(a6), | ||
64 | [14] = PT_REG(d0), | ||
65 | [15] = -1, | ||
66 | [16] = PT_REG(orig_d0), | ||
67 | [17] = PT_REG(sr), | ||
68 | [18] = PT_REG(pc), | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * Get contents of register REGNO in task TASK. | ||
73 | */ | ||
74 | static inline long get_reg(struct task_struct *task, int regno) | ||
75 | { | ||
76 | unsigned long *addr; | ||
77 | |||
78 | if (regno == PT_USP) | ||
79 | addr = &task->thread.usp; | ||
80 | else if (regno < ARRAY_SIZE(regoff)) | ||
81 | addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); | ||
82 | else | ||
83 | return 0; | ||
84 | /* Need to take stkadj into account. */ | ||
85 | if (regno == PT_SR || regno == PT_PC) { | ||
86 | long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); | ||
87 | addr = (unsigned long *) ((unsigned long)addr + stkadj); | ||
88 | /* The sr is actually a 16 bit register. */ | ||
89 | if (regno == PT_SR) | ||
90 | return *(unsigned short *)addr; | ||
91 | } | ||
92 | return *addr; | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * Write contents of register REGNO in task TASK. | ||
97 | */ | ||
98 | static inline int put_reg(struct task_struct *task, int regno, | ||
99 | unsigned long data) | ||
100 | { | ||
101 | unsigned long *addr; | ||
102 | |||
103 | if (regno == PT_USP) | ||
104 | addr = &task->thread.usp; | ||
105 | else if (regno < ARRAY_SIZE(regoff)) | ||
106 | addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); | ||
107 | else | ||
108 | return -1; | ||
109 | /* Need to take stkadj into account. */ | ||
110 | if (regno == PT_SR || regno == PT_PC) { | ||
111 | long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); | ||
112 | addr = (unsigned long *) ((unsigned long)addr + stkadj); | ||
113 | /* The sr is actually a 16 bit register. */ | ||
114 | if (regno == PT_SR) { | ||
115 | *(unsigned short *)addr = data; | ||
116 | return 0; | ||
117 | } | ||
118 | } | ||
119 | *addr = data; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Make sure the single step bit is not set. | ||
125 | */ | ||
126 | static inline void singlestep_disable(struct task_struct *child) | ||
127 | { | ||
128 | unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; | ||
129 | put_reg(child, PT_SR, tmp); | ||
130 | clear_tsk_thread_flag(child, TIF_DELAYED_TRACE); | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Called by kernel/ptrace.c when detaching.. | ||
135 | */ | ||
136 | void ptrace_disable(struct task_struct *child) | ||
137 | { | ||
138 | singlestep_disable(child); | ||
139 | } | ||
140 | |||
141 | void user_enable_single_step(struct task_struct *child) | ||
142 | { | ||
143 | unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; | ||
144 | put_reg(child, PT_SR, tmp | T1_BIT); | ||
145 | set_tsk_thread_flag(child, TIF_DELAYED_TRACE); | ||
146 | } | ||
147 | |||
148 | void user_enable_block_step(struct task_struct *child) | ||
149 | { | ||
150 | unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; | ||
151 | put_reg(child, PT_SR, tmp | T0_BIT); | ||
152 | } | ||
153 | |||
154 | void user_disable_single_step(struct task_struct *child) | ||
155 | { | ||
156 | singlestep_disable(child); | ||
157 | } | ||
158 | |||
159 | long arch_ptrace(struct task_struct *child, long request, | ||
160 | unsigned long addr, unsigned long data) | ||
161 | { | ||
162 | unsigned long tmp; | ||
163 | int i, ret = 0; | ||
164 | int regno = addr >> 2; /* temporary hack. */ | ||
165 | unsigned long __user *datap = (unsigned long __user *) data; | ||
166 | |||
167 | switch (request) { | ||
168 | /* read the word at location addr in the USER area. */ | ||
169 | case PTRACE_PEEKUSR: | ||
170 | if (addr & 3) | ||
171 | goto out_eio; | ||
172 | |||
173 | if (regno >= 0 && regno < 19) { | ||
174 | tmp = get_reg(child, regno); | ||
175 | } else if (regno >= 21 && regno < 49) { | ||
176 | tmp = child->thread.fp[regno - 21]; | ||
177 | /* Convert internal fpu reg representation | ||
178 | * into long double format | ||
179 | */ | ||
180 | if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) | ||
181 | tmp = ((tmp & 0xffff0000) << 15) | | ||
182 | ((tmp & 0x0000ffff) << 16); | ||
183 | } else | ||
184 | goto out_eio; | ||
185 | ret = put_user(tmp, datap); | ||
186 | break; | ||
187 | |||
188 | case PTRACE_POKEUSR: | ||
189 | /* write the word at location addr in the USER area */ | ||
190 | if (addr & 3) | ||
191 | goto out_eio; | ||
192 | |||
193 | if (regno == PT_SR) { | ||
194 | data &= SR_MASK; | ||
195 | data |= get_reg(child, PT_SR) & ~SR_MASK; | ||
196 | } | ||
197 | if (regno >= 0 && regno < 19) { | ||
198 | if (put_reg(child, regno, data)) | ||
199 | goto out_eio; | ||
200 | } else if (regno >= 21 && regno < 48) { | ||
201 | /* Convert long double format | ||
202 | * into internal fpu reg representation | ||
203 | */ | ||
204 | if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) { | ||
205 | data <<= 15; | ||
206 | data = (data & 0xffff0000) | | ||
207 | ((data & 0x0000ffff) >> 1); | ||
208 | } | ||
209 | child->thread.fp[regno - 21] = data; | ||
210 | } else | ||
211 | goto out_eio; | ||
212 | break; | ||
213 | |||
214 | case PTRACE_GETREGS: /* Get all gp regs from the child. */ | ||
215 | for (i = 0; i < 19; i++) { | ||
216 | tmp = get_reg(child, i); | ||
217 | ret = put_user(tmp, datap); | ||
218 | if (ret) | ||
219 | break; | ||
220 | datap++; | ||
221 | } | ||
222 | break; | ||
223 | |||
224 | case PTRACE_SETREGS: /* Set all gp regs in the child. */ | ||
225 | for (i = 0; i < 19; i++) { | ||
226 | ret = get_user(tmp, datap); | ||
227 | if (ret) | ||
228 | break; | ||
229 | if (i == PT_SR) { | ||
230 | tmp &= SR_MASK; | ||
231 | tmp |= get_reg(child, PT_SR) & ~SR_MASK; | ||
232 | } | ||
233 | put_reg(child, i, tmp); | ||
234 | datap++; | ||
235 | } | ||
236 | break; | ||
237 | |||
238 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ | ||
239 | if (copy_to_user(datap, &child->thread.fp, | ||
240 | sizeof(struct user_m68kfp_struct))) | ||
241 | ret = -EFAULT; | ||
242 | break; | ||
243 | |||
244 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ | ||
245 | if (copy_from_user(&child->thread.fp, datap, | ||
246 | sizeof(struct user_m68kfp_struct))) | ||
247 | ret = -EFAULT; | ||
248 | break; | ||
249 | |||
250 | case PTRACE_GET_THREAD_AREA: | ||
251 | ret = put_user(task_thread_info(child)->tp_value, datap); | ||
252 | break; | ||
253 | |||
254 | default: | ||
255 | ret = ptrace_request(child, request, addr, data); | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | return ret; | ||
260 | out_eio: | ||
261 | return -EIO; | ||
262 | } | ||
263 | |||
264 | asmlinkage void syscall_trace(void) | ||
265 | { | ||
266 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | ||
267 | ? 0x80 : 0)); | ||
268 | /* | ||
269 | * this isn't the same as continuing with a signal, but it will do | ||
270 | * for normal use. strace only continues with a signal if the | ||
271 | * stopping signal is not SIGTRAP. -brl | ||
272 | */ | ||
273 | if (current->exit_code) { | ||
274 | send_sig(current->exit_code, current, 1); | ||
275 | current->exit_code = 0; | ||
276 | } | ||
277 | } | ||
diff --git a/arch/m68k/kernel/ptrace_mm.c b/arch/m68k/kernel/ptrace_mm.c new file mode 100644 index 000000000000..0b252683cefb --- /dev/null +++ b/arch/m68k/kernel/ptrace_mm.c | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/kernel/ptrace.c | ||
3 | * | ||
4 | * Copyright (C) 1994 by Hamish Macdonald | ||
5 | * Taken from linux/kernel/ptrace.c and modified for M680x0. | ||
6 | * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of | ||
10 | * this archive for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/ptrace.h> | ||
19 | #include <linux/user.h> | ||
20 | #include <linux/signal.h> | ||
21 | |||
22 | #include <asm/uaccess.h> | ||
23 | #include <asm/page.h> | ||
24 | #include <asm/pgtable.h> | ||
25 | #include <asm/system.h> | ||
26 | #include <asm/processor.h> | ||
27 | |||
28 | /* | ||
29 | * does not yet catch signals sent when the child dies. | ||
30 | * in exit.c or in signal.c. | ||
31 | */ | ||
32 | |||
33 | /* determines which bits in the SR the user has access to. */ | ||
34 | /* 1 = access 0 = no access */ | ||
35 | #define SR_MASK 0x001f | ||
36 | |||
37 | /* sets the trace bits. */ | ||
38 | #define TRACE_BITS 0xC000 | ||
39 | #define T1_BIT 0x8000 | ||
40 | #define T0_BIT 0x4000 | ||
41 | |||
42 | /* Find the stack offset for a register, relative to thread.esp0. */ | ||
43 | #define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) | ||
44 | #define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \ | ||
45 | - sizeof(struct switch_stack)) | ||
46 | /* Mapping from PT_xxx to the stack offset at which the register is | ||
47 | saved. Notice that usp has no stack-slot and needs to be treated | ||
48 | specially (see get_reg/put_reg below). */ | ||
49 | static const int regoff[] = { | ||
50 | [0] = PT_REG(d1), | ||
51 | [1] = PT_REG(d2), | ||
52 | [2] = PT_REG(d3), | ||
53 | [3] = PT_REG(d4), | ||
54 | [4] = PT_REG(d5), | ||
55 | [5] = SW_REG(d6), | ||
56 | [6] = SW_REG(d7), | ||
57 | [7] = PT_REG(a0), | ||
58 | [8] = PT_REG(a1), | ||
59 | [9] = PT_REG(a2), | ||
60 | [10] = SW_REG(a3), | ||
61 | [11] = SW_REG(a4), | ||
62 | [12] = SW_REG(a5), | ||
63 | [13] = SW_REG(a6), | ||
64 | [14] = PT_REG(d0), | ||
65 | [15] = -1, | ||
66 | [16] = PT_REG(orig_d0), | ||
67 | [17] = PT_REG(sr), | ||
68 | [18] = PT_REG(pc), | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * Get contents of register REGNO in task TASK. | ||
73 | */ | ||
74 | static inline long get_reg(struct task_struct *task, int regno) | ||
75 | { | ||
76 | unsigned long *addr; | ||
77 | |||
78 | if (regno == PT_USP) | ||
79 | addr = &task->thread.usp; | ||
80 | else if (regno < ARRAY_SIZE(regoff)) | ||
81 | addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); | ||
82 | else | ||
83 | return 0; | ||
84 | /* Need to take stkadj into account. */ | ||
85 | if (regno == PT_SR || regno == PT_PC) { | ||
86 | long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); | ||
87 | addr = (unsigned long *) ((unsigned long)addr + stkadj); | ||
88 | /* The sr is actually a 16 bit register. */ | ||
89 | if (regno == PT_SR) | ||
90 | return *(unsigned short *)addr; | ||
91 | } | ||
92 | return *addr; | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * Write contents of register REGNO in task TASK. | ||
97 | */ | ||
98 | static inline int put_reg(struct task_struct *task, int regno, | ||
99 | unsigned long data) | ||
100 | { | ||
101 | unsigned long *addr; | ||
102 | |||
103 | if (regno == PT_USP) | ||
104 | addr = &task->thread.usp; | ||
105 | else if (regno < ARRAY_SIZE(regoff)) | ||
106 | addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); | ||
107 | else | ||
108 | return -1; | ||
109 | /* Need to take stkadj into account. */ | ||
110 | if (regno == PT_SR || regno == PT_PC) { | ||
111 | long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); | ||
112 | addr = (unsigned long *) ((unsigned long)addr + stkadj); | ||
113 | /* The sr is actually a 16 bit register. */ | ||
114 | if (regno == PT_SR) { | ||
115 | *(unsigned short *)addr = data; | ||
116 | return 0; | ||
117 | } | ||
118 | } | ||
119 | *addr = data; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Make sure the single step bit is not set. | ||
125 | */ | ||
126 | static inline void singlestep_disable(struct task_struct *child) | ||
127 | { | ||
128 | unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; | ||
129 | put_reg(child, PT_SR, tmp); | ||
130 | clear_tsk_thread_flag(child, TIF_DELAYED_TRACE); | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Called by kernel/ptrace.c when detaching.. | ||
135 | */ | ||
136 | void ptrace_disable(struct task_struct *child) | ||
137 | { | ||
138 | singlestep_disable(child); | ||
139 | } | ||
140 | |||
141 | void user_enable_single_step(struct task_struct *child) | ||
142 | { | ||
143 | unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; | ||
144 | put_reg(child, PT_SR, tmp | T1_BIT); | ||
145 | set_tsk_thread_flag(child, TIF_DELAYED_TRACE); | ||
146 | } | ||
147 | |||
148 | void user_enable_block_step(struct task_struct *child) | ||
149 | { | ||
150 | unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; | ||
151 | put_reg(child, PT_SR, tmp | T0_BIT); | ||
152 | } | ||
153 | |||
154 | void user_disable_single_step(struct task_struct *child) | ||
155 | { | ||
156 | singlestep_disable(child); | ||
157 | } | ||
158 | |||
159 | long arch_ptrace(struct task_struct *child, long request, | ||
160 | unsigned long addr, unsigned long data) | ||
161 | { | ||
162 | unsigned long tmp; | ||
163 | int i, ret = 0; | ||
164 | int regno = addr >> 2; /* temporary hack. */ | ||
165 | unsigned long __user *datap = (unsigned long __user *) data; | ||
166 | |||
167 | switch (request) { | ||
168 | /* read the word at location addr in the USER area. */ | ||
169 | case PTRACE_PEEKUSR: | ||
170 | if (addr & 3) | ||
171 | goto out_eio; | ||
172 | |||
173 | if (regno >= 0 && regno < 19) { | ||
174 | tmp = get_reg(child, regno); | ||
175 | } else if (regno >= 21 && regno < 49) { | ||
176 | tmp = child->thread.fp[regno - 21]; | ||
177 | /* Convert internal fpu reg representation | ||
178 | * into long double format | ||
179 | */ | ||
180 | if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) | ||
181 | tmp = ((tmp & 0xffff0000) << 15) | | ||
182 | ((tmp & 0x0000ffff) << 16); | ||
183 | } else | ||
184 | goto out_eio; | ||
185 | ret = put_user(tmp, datap); | ||
186 | break; | ||
187 | |||
188 | case PTRACE_POKEUSR: | ||
189 | /* write the word at location addr in the USER area */ | ||
190 | if (addr & 3) | ||
191 | goto out_eio; | ||
192 | |||
193 | if (regno == PT_SR) { | ||
194 | data &= SR_MASK; | ||
195 | data |= get_reg(child, PT_SR) & ~SR_MASK; | ||
196 | } | ||
197 | if (regno >= 0 && regno < 19) { | ||
198 | if (put_reg(child, regno, data)) | ||
199 | goto out_eio; | ||
200 | } else if (regno >= 21 && regno < 48) { | ||
201 | /* Convert long double format | ||
202 | * into internal fpu reg representation | ||
203 | */ | ||
204 | if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) { | ||
205 | data <<= 15; | ||
206 | data = (data & 0xffff0000) | | ||
207 | ((data & 0x0000ffff) >> 1); | ||
208 | } | ||
209 | child->thread.fp[regno - 21] = data; | ||
210 | } else | ||
211 | goto out_eio; | ||
212 | break; | ||
213 | |||
214 | case PTRACE_GETREGS: /* Get all gp regs from the child. */ | ||
215 | for (i = 0; i < 19; i++) { | ||
216 | tmp = get_reg(child, i); | ||
217 | ret = put_user(tmp, datap); | ||
218 | if (ret) | ||
219 | break; | ||
220 | datap++; | ||
221 | } | ||
222 | break; | ||
223 | |||
224 | case PTRACE_SETREGS: /* Set all gp regs in the child. */ | ||
225 | for (i = 0; i < 19; i++) { | ||
226 | ret = get_user(tmp, datap); | ||
227 | if (ret) | ||
228 | break; | ||
229 | if (i == PT_SR) { | ||
230 | tmp &= SR_MASK; | ||
231 | tmp |= get_reg(child, PT_SR) & ~SR_MASK; | ||
232 | } | ||
233 | put_reg(child, i, tmp); | ||
234 | datap++; | ||
235 | } | ||
236 | break; | ||
237 | |||
238 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ | ||
239 | if (copy_to_user(datap, &child->thread.fp, | ||
240 | sizeof(struct user_m68kfp_struct))) | ||
241 | ret = -EFAULT; | ||
242 | break; | ||
243 | |||
244 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ | ||
245 | if (copy_from_user(&child->thread.fp, datap, | ||
246 | sizeof(struct user_m68kfp_struct))) | ||
247 | ret = -EFAULT; | ||
248 | break; | ||
249 | |||
250 | case PTRACE_GET_THREAD_AREA: | ||
251 | ret = put_user(task_thread_info(child)->tp_value, datap); | ||
252 | break; | ||
253 | |||
254 | default: | ||
255 | ret = ptrace_request(child, request, addr, data); | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | return ret; | ||
260 | out_eio: | ||
261 | return -EIO; | ||
262 | } | ||
263 | |||
264 | asmlinkage void syscall_trace(void) | ||
265 | { | ||
266 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | ||
267 | ? 0x80 : 0)); | ||
268 | /* | ||
269 | * this isn't the same as continuing with a signal, but it will do | ||
270 | * for normal use. strace only continues with a signal if the | ||
271 | * stopping signal is not SIGTRAP. -brl | ||
272 | */ | ||
273 | if (current->exit_code) { | ||
274 | send_sig(current->exit_code, current, 1); | ||
275 | current->exit_code = 0; | ||
276 | } | ||
277 | } | ||
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68k/kernel/ptrace_no.c index 6709fb707335..6709fb707335 100644 --- a/arch/m68knommu/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace_no.c | |||
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 334d83640376..4bf129f1d2e2 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c | |||
@@ -1,533 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/kernel/setup.c | 2 | #include "setup_mm.c" |
3 | * | ||
4 | * Copyright (C) 1995 Hamish Macdonald | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * This file handles the architecture-dependent parts of system setup | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/fs.h> | ||
17 | #include <linux/console.h> | ||
18 | #include <linux/genhd.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/bootmem.h> | ||
23 | #include <linux/proc_fs.h> | ||
24 | #include <linux/seq_file.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/initrd.h> | ||
27 | |||
28 | #include <asm/bootinfo.h> | ||
29 | #include <asm/sections.h> | ||
30 | #include <asm/setup.h> | ||
31 | #include <asm/fpu.h> | ||
32 | #include <asm/irq.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/machdep.h> | ||
35 | #ifdef CONFIG_AMIGA | ||
36 | #include <asm/amigahw.h> | ||
37 | #endif | ||
38 | #ifdef CONFIG_ATARI | ||
39 | #include <asm/atarihw.h> | ||
40 | #include <asm/atari_stram.h> | ||
41 | #endif | ||
42 | #ifdef CONFIG_SUN3X | ||
43 | #include <asm/dvma.h> | ||
44 | #endif | ||
45 | #include <asm/natfeat.h> | ||
46 | |||
47 | #if !FPSTATESIZE || !NR_IRQS | ||
48 | #warning No CPU/platform type selected, your kernel will not work! | ||
49 | #warning Are you building an allnoconfig kernel? | ||
50 | #endif | ||
51 | |||
52 | unsigned long m68k_machtype; | ||
53 | EXPORT_SYMBOL(m68k_machtype); | ||
54 | unsigned long m68k_cputype; | ||
55 | EXPORT_SYMBOL(m68k_cputype); | ||
56 | unsigned long m68k_fputype; | ||
57 | unsigned long m68k_mmutype; | ||
58 | EXPORT_SYMBOL(m68k_mmutype); | ||
59 | #ifdef CONFIG_VME | ||
60 | unsigned long vme_brdtype; | ||
61 | EXPORT_SYMBOL(vme_brdtype); | ||
62 | #endif | ||
63 | |||
64 | int m68k_is040or060; | ||
65 | EXPORT_SYMBOL(m68k_is040or060); | ||
66 | |||
67 | extern unsigned long availmem; | ||
68 | |||
69 | int m68k_num_memory; | ||
70 | EXPORT_SYMBOL(m68k_num_memory); | ||
71 | int m68k_realnum_memory; | ||
72 | EXPORT_SYMBOL(m68k_realnum_memory); | ||
73 | unsigned long m68k_memoffset; | ||
74 | struct mem_info m68k_memory[NUM_MEMINFO]; | ||
75 | EXPORT_SYMBOL(m68k_memory); | ||
76 | |||
77 | struct mem_info m68k_ramdisk; | ||
78 | |||
79 | static char m68k_command_line[CL_SIZE]; | ||
80 | |||
81 | void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; | ||
82 | /* machine dependent irq functions */ | ||
83 | void (*mach_init_IRQ) (void) __initdata = NULL; | ||
84 | void (*mach_get_model) (char *model); | ||
85 | void (*mach_get_hardware_list) (struct seq_file *m); | ||
86 | /* machine dependent timer functions */ | ||
87 | unsigned long (*mach_gettimeoffset) (void); | ||
88 | int (*mach_hwclk) (int, struct rtc_time*); | ||
89 | EXPORT_SYMBOL(mach_hwclk); | ||
90 | int (*mach_set_clock_mmss) (unsigned long); | ||
91 | unsigned int (*mach_get_ss)(void); | ||
92 | int (*mach_get_rtc_pll)(struct rtc_pll_info *); | ||
93 | int (*mach_set_rtc_pll)(struct rtc_pll_info *); | ||
94 | EXPORT_SYMBOL(mach_get_ss); | ||
95 | EXPORT_SYMBOL(mach_get_rtc_pll); | ||
96 | EXPORT_SYMBOL(mach_set_rtc_pll); | ||
97 | void (*mach_reset)( void ); | ||
98 | void (*mach_halt)( void ); | ||
99 | void (*mach_power_off)( void ); | ||
100 | long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ | ||
101 | #ifdef CONFIG_HEARTBEAT | ||
102 | void (*mach_heartbeat) (int); | ||
103 | EXPORT_SYMBOL(mach_heartbeat); | ||
104 | #endif | ||
105 | #ifdef CONFIG_M68K_L2_CACHE | ||
106 | void (*mach_l2_flush) (int); | ||
107 | #endif | ||
108 | #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) | ||
109 | void (*mach_beep)(unsigned int, unsigned int); | ||
110 | EXPORT_SYMBOL(mach_beep); | ||
111 | #endif | ||
112 | #if defined(CONFIG_ISA) && defined(MULTI_ISA) | ||
113 | int isa_type; | ||
114 | int isa_sex; | ||
115 | EXPORT_SYMBOL(isa_type); | ||
116 | EXPORT_SYMBOL(isa_sex); | ||
117 | #endif | ||
118 | |||
119 | extern int amiga_parse_bootinfo(const struct bi_record *); | ||
120 | extern int atari_parse_bootinfo(const struct bi_record *); | ||
121 | extern int mac_parse_bootinfo(const struct bi_record *); | ||
122 | extern int q40_parse_bootinfo(const struct bi_record *); | ||
123 | extern int bvme6000_parse_bootinfo(const struct bi_record *); | ||
124 | extern int mvme16x_parse_bootinfo(const struct bi_record *); | ||
125 | extern int mvme147_parse_bootinfo(const struct bi_record *); | ||
126 | extern int hp300_parse_bootinfo(const struct bi_record *); | ||
127 | extern int apollo_parse_bootinfo(const struct bi_record *); | ||
128 | |||
129 | extern void config_amiga(void); | ||
130 | extern void config_atari(void); | ||
131 | extern void config_mac(void); | ||
132 | extern void config_sun3(void); | ||
133 | extern void config_apollo(void); | ||
134 | extern void config_mvme147(void); | ||
135 | extern void config_mvme16x(void); | ||
136 | extern void config_bvme6000(void); | ||
137 | extern void config_hp300(void); | ||
138 | extern void config_q40(void); | ||
139 | extern void config_sun3x(void); | ||
140 | |||
141 | #define MASK_256K 0xfffc0000 | ||
142 | |||
143 | extern void paging_init(void); | ||
144 | |||
145 | static void __init m68k_parse_bootinfo(const struct bi_record *record) | ||
146 | { | ||
147 | while (record->tag != BI_LAST) { | ||
148 | int unknown = 0; | ||
149 | const unsigned long *data = record->data; | ||
150 | |||
151 | switch (record->tag) { | ||
152 | case BI_MACHTYPE: | ||
153 | case BI_CPUTYPE: | ||
154 | case BI_FPUTYPE: | ||
155 | case BI_MMUTYPE: | ||
156 | /* Already set up by head.S */ | ||
157 | break; | ||
158 | |||
159 | case BI_MEMCHUNK: | ||
160 | if (m68k_num_memory < NUM_MEMINFO) { | ||
161 | m68k_memory[m68k_num_memory].addr = data[0]; | ||
162 | m68k_memory[m68k_num_memory].size = data[1]; | ||
163 | m68k_num_memory++; | ||
164 | } else | ||
165 | printk("m68k_parse_bootinfo: too many memory chunks\n"); | ||
166 | break; | ||
167 | |||
168 | case BI_RAMDISK: | ||
169 | m68k_ramdisk.addr = data[0]; | ||
170 | m68k_ramdisk.size = data[1]; | ||
171 | break; | ||
172 | |||
173 | case BI_COMMAND_LINE: | ||
174 | strlcpy(m68k_command_line, (const char *)data, | ||
175 | sizeof(m68k_command_line)); | ||
176 | break; | ||
177 | |||
178 | default: | ||
179 | if (MACH_IS_AMIGA) | ||
180 | unknown = amiga_parse_bootinfo(record); | ||
181 | else if (MACH_IS_ATARI) | ||
182 | unknown = atari_parse_bootinfo(record); | ||
183 | else if (MACH_IS_MAC) | ||
184 | unknown = mac_parse_bootinfo(record); | ||
185 | else if (MACH_IS_Q40) | ||
186 | unknown = q40_parse_bootinfo(record); | ||
187 | else if (MACH_IS_BVME6000) | ||
188 | unknown = bvme6000_parse_bootinfo(record); | ||
189 | else if (MACH_IS_MVME16x) | ||
190 | unknown = mvme16x_parse_bootinfo(record); | ||
191 | else if (MACH_IS_MVME147) | ||
192 | unknown = mvme147_parse_bootinfo(record); | ||
193 | else if (MACH_IS_HP300) | ||
194 | unknown = hp300_parse_bootinfo(record); | ||
195 | else if (MACH_IS_APOLLO) | ||
196 | unknown = apollo_parse_bootinfo(record); | ||
197 | else | ||
198 | unknown = 1; | ||
199 | } | ||
200 | if (unknown) | ||
201 | printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", | ||
202 | record->tag); | ||
203 | record = (struct bi_record *)((unsigned long)record + | ||
204 | record->size); | ||
205 | } | ||
206 | |||
207 | m68k_realnum_memory = m68k_num_memory; | ||
208 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK | ||
209 | if (m68k_num_memory > 1) { | ||
210 | printk("Ignoring last %i chunks of physical memory\n", | ||
211 | (m68k_num_memory - 1)); | ||
212 | m68k_num_memory = 1; | ||
213 | } | ||
214 | #endif | ||
215 | } | ||
216 | |||
217 | void __init setup_arch(char **cmdline_p) | ||
218 | { | ||
219 | int i; | ||
220 | |||
221 | /* The bootinfo is located right after the kernel bss */ | ||
222 | m68k_parse_bootinfo((const struct bi_record *)_end); | ||
223 | |||
224 | if (CPU_IS_040) | ||
225 | m68k_is040or060 = 4; | ||
226 | else if (CPU_IS_060) | ||
227 | m68k_is040or060 = 6; | ||
228 | |||
229 | /* FIXME: m68k_fputype is passed in by Penguin booter, which can | ||
230 | * be confused by software FPU emulation. BEWARE. | ||
231 | * We should really do our own FPU check at startup. | ||
232 | * [what do we do with buggy 68LC040s? if we have problems | ||
233 | * with them, we should add a test to check_bugs() below] */ | ||
234 | #ifndef CONFIG_M68KFPU_EMU_ONLY | ||
235 | /* clear the fpu if we have one */ | ||
236 | if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { | ||
237 | volatile int zero = 0; | ||
238 | asm volatile ("frestore %0" : : "m" (zero)); | ||
239 | } | ||
240 | #endif | ||
241 | |||
242 | if (CPU_IS_060) { | ||
243 | u32 pcr; | ||
244 | |||
245 | asm (".chip 68060; movec %%pcr,%0; .chip 68k" | ||
246 | : "=d" (pcr)); | ||
247 | if (((pcr >> 8) & 0xff) <= 5) { | ||
248 | printk("Enabling workaround for errata I14\n"); | ||
249 | asm (".chip 68060; movec %0,%%pcr; .chip 68k" | ||
250 | : : "d" (pcr | 0x20)); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | init_mm.start_code = PAGE_OFFSET; | ||
255 | init_mm.end_code = (unsigned long)_etext; | ||
256 | init_mm.end_data = (unsigned long)_edata; | ||
257 | init_mm.brk = (unsigned long)_end; | ||
258 | |||
259 | *cmdline_p = m68k_command_line; | ||
260 | memcpy(boot_command_line, *cmdline_p, CL_SIZE); | ||
261 | |||
262 | parse_early_param(); | ||
263 | |||
264 | #ifdef CONFIG_DUMMY_CONSOLE | ||
265 | conswitchp = &dummy_con; | ||
266 | #endif | ||
267 | |||
268 | switch (m68k_machtype) { | ||
269 | #ifdef CONFIG_AMIGA | ||
270 | case MACH_AMIGA: | ||
271 | config_amiga(); | ||
272 | break; | ||
273 | #endif | ||
274 | #ifdef CONFIG_ATARI | ||
275 | case MACH_ATARI: | ||
276 | config_atari(); | ||
277 | break; | ||
278 | #endif | ||
279 | #ifdef CONFIG_MAC | ||
280 | case MACH_MAC: | ||
281 | config_mac(); | ||
282 | break; | ||
283 | #endif | ||
284 | #ifdef CONFIG_SUN3 | ||
285 | case MACH_SUN3: | ||
286 | config_sun3(); | ||
287 | break; | ||
288 | #endif | ||
289 | #ifdef CONFIG_APOLLO | ||
290 | case MACH_APOLLO: | ||
291 | config_apollo(); | ||
292 | break; | ||
293 | #endif | ||
294 | #ifdef CONFIG_MVME147 | ||
295 | case MACH_MVME147: | ||
296 | config_mvme147(); | ||
297 | break; | ||
298 | #endif | ||
299 | #ifdef CONFIG_MVME16x | ||
300 | case MACH_MVME16x: | ||
301 | config_mvme16x(); | ||
302 | break; | ||
303 | #endif | ||
304 | #ifdef CONFIG_BVME6000 | ||
305 | case MACH_BVME6000: | ||
306 | config_bvme6000(); | ||
307 | break; | ||
308 | #endif | ||
309 | #ifdef CONFIG_HP300 | ||
310 | case MACH_HP300: | ||
311 | config_hp300(); | ||
312 | break; | ||
313 | #endif | ||
314 | #ifdef CONFIG_Q40 | ||
315 | case MACH_Q40: | ||
316 | config_q40(); | ||
317 | break; | ||
318 | #endif | ||
319 | #ifdef CONFIG_SUN3X | ||
320 | case MACH_SUN3X: | ||
321 | config_sun3x(); | ||
322 | break; | ||
323 | #endif | ||
324 | default: | ||
325 | panic("No configuration setup"); | ||
326 | } | ||
327 | |||
328 | #ifdef CONFIG_NATFEAT | ||
329 | nf_init(); | ||
330 | #endif | ||
331 | |||
332 | paging_init(); | ||
333 | |||
334 | #ifndef CONFIG_SUN3 | ||
335 | for (i = 1; i < m68k_num_memory; i++) | ||
336 | free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr, | ||
337 | m68k_memory[i].size); | ||
338 | #ifdef CONFIG_BLK_DEV_INITRD | ||
339 | if (m68k_ramdisk.size) { | ||
340 | reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)), | ||
341 | m68k_ramdisk.addr, m68k_ramdisk.size, | ||
342 | BOOTMEM_DEFAULT); | ||
343 | initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); | ||
344 | initrd_end = initrd_start + m68k_ramdisk.size; | ||
345 | printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); | ||
346 | } | ||
347 | #endif | ||
348 | |||
349 | #ifdef CONFIG_ATARI | ||
350 | if (MACH_IS_ATARI) | ||
351 | atari_stram_reserve_pages((void *)availmem); | ||
352 | #endif | ||
353 | #ifdef CONFIG_SUN3X | ||
354 | if (MACH_IS_SUN3X) { | ||
355 | dvma_init(); | ||
356 | } | ||
357 | #endif | ||
358 | |||
359 | #endif /* !CONFIG_SUN3 */ | ||
360 | |||
361 | /* set ISA defs early as possible */ | ||
362 | #if defined(CONFIG_ISA) && defined(MULTI_ISA) | ||
363 | if (MACH_IS_Q40) { | ||
364 | isa_type = ISA_TYPE_Q40; | ||
365 | isa_sex = 0; | ||
366 | } | ||
367 | #ifdef CONFIG_AMIGA_PCMCIA | ||
368 | if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) { | ||
369 | isa_type = ISA_TYPE_AG; | ||
370 | isa_sex = 1; | ||
371 | } | ||
372 | #endif | ||
373 | #endif | ||
374 | } | ||
375 | |||
376 | static int show_cpuinfo(struct seq_file *m, void *v) | ||
377 | { | ||
378 | const char *cpu, *mmu, *fpu; | ||
379 | unsigned long clockfreq, clockfactor; | ||
380 | |||
381 | #define LOOP_CYCLES_68020 (8) | ||
382 | #define LOOP_CYCLES_68030 (8) | ||
383 | #define LOOP_CYCLES_68040 (3) | ||
384 | #define LOOP_CYCLES_68060 (1) | ||
385 | |||
386 | if (CPU_IS_020) { | ||
387 | cpu = "68020"; | ||
388 | clockfactor = LOOP_CYCLES_68020; | ||
389 | } else if (CPU_IS_030) { | ||
390 | cpu = "68030"; | ||
391 | clockfactor = LOOP_CYCLES_68030; | ||
392 | } else if (CPU_IS_040) { | ||
393 | cpu = "68040"; | ||
394 | clockfactor = LOOP_CYCLES_68040; | ||
395 | } else if (CPU_IS_060) { | ||
396 | cpu = "68060"; | ||
397 | clockfactor = LOOP_CYCLES_68060; | ||
398 | } else { | ||
399 | cpu = "680x0"; | ||
400 | clockfactor = 0; | ||
401 | } | ||
402 | |||
403 | #ifdef CONFIG_M68KFPU_EMU_ONLY | ||
404 | fpu = "none(soft float)"; | ||
405 | #else | 3 | #else |
406 | if (m68k_fputype & FPU_68881) | 4 | #include "setup_no.c" |
407 | fpu = "68881"; | ||
408 | else if (m68k_fputype & FPU_68882) | ||
409 | fpu = "68882"; | ||
410 | else if (m68k_fputype & FPU_68040) | ||
411 | fpu = "68040"; | ||
412 | else if (m68k_fputype & FPU_68060) | ||
413 | fpu = "68060"; | ||
414 | else if (m68k_fputype & FPU_SUNFPA) | ||
415 | fpu = "Sun FPA"; | ||
416 | else | ||
417 | fpu = "none"; | ||
418 | #endif | ||
419 | |||
420 | if (m68k_mmutype & MMU_68851) | ||
421 | mmu = "68851"; | ||
422 | else if (m68k_mmutype & MMU_68030) | ||
423 | mmu = "68030"; | ||
424 | else if (m68k_mmutype & MMU_68040) | ||
425 | mmu = "68040"; | ||
426 | else if (m68k_mmutype & MMU_68060) | ||
427 | mmu = "68060"; | ||
428 | else if (m68k_mmutype & MMU_SUN3) | ||
429 | mmu = "Sun-3"; | ||
430 | else if (m68k_mmutype & MMU_APOLLO) | ||
431 | mmu = "Apollo"; | ||
432 | else | ||
433 | mmu = "unknown"; | ||
434 | |||
435 | clockfreq = loops_per_jiffy * HZ * clockfactor; | ||
436 | |||
437 | seq_printf(m, "CPU:\t\t%s\n" | ||
438 | "MMU:\t\t%s\n" | ||
439 | "FPU:\t\t%s\n" | ||
440 | "Clocking:\t%lu.%1luMHz\n" | ||
441 | "BogoMips:\t%lu.%02lu\n" | ||
442 | "Calibration:\t%lu loops\n", | ||
443 | cpu, mmu, fpu, | ||
444 | clockfreq/1000000,(clockfreq/100000)%10, | ||
445 | loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100, | ||
446 | loops_per_jiffy); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
451 | { | ||
452 | return *pos < 1 ? (void *)1 : NULL; | ||
453 | } | ||
454 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
455 | { | ||
456 | ++*pos; | ||
457 | return NULL; | ||
458 | } | ||
459 | static void c_stop(struct seq_file *m, void *v) | ||
460 | { | ||
461 | } | ||
462 | const struct seq_operations cpuinfo_op = { | ||
463 | .start = c_start, | ||
464 | .next = c_next, | ||
465 | .stop = c_stop, | ||
466 | .show = show_cpuinfo, | ||
467 | }; | ||
468 | |||
469 | #ifdef CONFIG_PROC_HARDWARE | ||
470 | static int hardware_proc_show(struct seq_file *m, void *v) | ||
471 | { | ||
472 | char model[80]; | ||
473 | unsigned long mem; | ||
474 | int i; | ||
475 | |||
476 | if (mach_get_model) | ||
477 | mach_get_model(model); | ||
478 | else | ||
479 | strcpy(model, "Unknown m68k"); | ||
480 | |||
481 | seq_printf(m, "Model:\t\t%s\n", model); | ||
482 | for (mem = 0, i = 0; i < m68k_num_memory; i++) | ||
483 | mem += m68k_memory[i].size; | ||
484 | seq_printf(m, "System Memory:\t%ldK\n", mem >> 10); | ||
485 | |||
486 | if (mach_get_hardware_list) | ||
487 | mach_get_hardware_list(m); | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int hardware_proc_open(struct inode *inode, struct file *file) | ||
493 | { | ||
494 | return single_open(file, hardware_proc_show, NULL); | ||
495 | } | ||
496 | |||
497 | static const struct file_operations hardware_proc_fops = { | ||
498 | .open = hardware_proc_open, | ||
499 | .read = seq_read, | ||
500 | .llseek = seq_lseek, | ||
501 | .release = single_release, | ||
502 | }; | ||
503 | |||
504 | static int __init proc_hardware_init(void) | ||
505 | { | ||
506 | proc_create("hardware", 0, NULL, &hardware_proc_fops); | ||
507 | return 0; | ||
508 | } | ||
509 | module_init(proc_hardware_init); | ||
510 | #endif | 5 | #endif |
511 | |||
512 | void check_bugs(void) | ||
513 | { | ||
514 | #ifndef CONFIG_M68KFPU_EMU | ||
515 | if (m68k_fputype == 0) { | ||
516 | printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " | ||
517 | "WHICH IS REQUIRED BY LINUX/M68K ***\n"); | ||
518 | printk(KERN_EMERG "Upgrade your hardware or join the FPU " | ||
519 | "emulation project\n"); | ||
520 | panic("no FPU"); | ||
521 | } | ||
522 | #endif /* !CONFIG_M68KFPU_EMU */ | ||
523 | } | ||
524 | |||
525 | #ifdef CONFIG_ADB | ||
526 | static int __init adb_probe_sync_enable (char *str) { | ||
527 | extern int __adb_probe_sync; | ||
528 | __adb_probe_sync = 1; | ||
529 | return 1; | ||
530 | } | ||
531 | |||
532 | __setup("adb_sync", adb_probe_sync_enable); | ||
533 | #endif /* CONFIG_ADB */ | ||
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c new file mode 100644 index 000000000000..334d83640376 --- /dev/null +++ b/arch/m68k/kernel/setup_mm.c | |||
@@ -0,0 +1,533 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/kernel/setup.c | ||
3 | * | ||
4 | * Copyright (C) 1995 Hamish Macdonald | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * This file handles the architecture-dependent parts of system setup | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/fs.h> | ||
17 | #include <linux/console.h> | ||
18 | #include <linux/genhd.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/bootmem.h> | ||
23 | #include <linux/proc_fs.h> | ||
24 | #include <linux/seq_file.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/initrd.h> | ||
27 | |||
28 | #include <asm/bootinfo.h> | ||
29 | #include <asm/sections.h> | ||
30 | #include <asm/setup.h> | ||
31 | #include <asm/fpu.h> | ||
32 | #include <asm/irq.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/machdep.h> | ||
35 | #ifdef CONFIG_AMIGA | ||
36 | #include <asm/amigahw.h> | ||
37 | #endif | ||
38 | #ifdef CONFIG_ATARI | ||
39 | #include <asm/atarihw.h> | ||
40 | #include <asm/atari_stram.h> | ||
41 | #endif | ||
42 | #ifdef CONFIG_SUN3X | ||
43 | #include <asm/dvma.h> | ||
44 | #endif | ||
45 | #include <asm/natfeat.h> | ||
46 | |||
47 | #if !FPSTATESIZE || !NR_IRQS | ||
48 | #warning No CPU/platform type selected, your kernel will not work! | ||
49 | #warning Are you building an allnoconfig kernel? | ||
50 | #endif | ||
51 | |||
52 | unsigned long m68k_machtype; | ||
53 | EXPORT_SYMBOL(m68k_machtype); | ||
54 | unsigned long m68k_cputype; | ||
55 | EXPORT_SYMBOL(m68k_cputype); | ||
56 | unsigned long m68k_fputype; | ||
57 | unsigned long m68k_mmutype; | ||
58 | EXPORT_SYMBOL(m68k_mmutype); | ||
59 | #ifdef CONFIG_VME | ||
60 | unsigned long vme_brdtype; | ||
61 | EXPORT_SYMBOL(vme_brdtype); | ||
62 | #endif | ||
63 | |||
64 | int m68k_is040or060; | ||
65 | EXPORT_SYMBOL(m68k_is040or060); | ||
66 | |||
67 | extern unsigned long availmem; | ||
68 | |||
69 | int m68k_num_memory; | ||
70 | EXPORT_SYMBOL(m68k_num_memory); | ||
71 | int m68k_realnum_memory; | ||
72 | EXPORT_SYMBOL(m68k_realnum_memory); | ||
73 | unsigned long m68k_memoffset; | ||
74 | struct mem_info m68k_memory[NUM_MEMINFO]; | ||
75 | EXPORT_SYMBOL(m68k_memory); | ||
76 | |||
77 | struct mem_info m68k_ramdisk; | ||
78 | |||
79 | static char m68k_command_line[CL_SIZE]; | ||
80 | |||
81 | void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; | ||
82 | /* machine dependent irq functions */ | ||
83 | void (*mach_init_IRQ) (void) __initdata = NULL; | ||
84 | void (*mach_get_model) (char *model); | ||
85 | void (*mach_get_hardware_list) (struct seq_file *m); | ||
86 | /* machine dependent timer functions */ | ||
87 | unsigned long (*mach_gettimeoffset) (void); | ||
88 | int (*mach_hwclk) (int, struct rtc_time*); | ||
89 | EXPORT_SYMBOL(mach_hwclk); | ||
90 | int (*mach_set_clock_mmss) (unsigned long); | ||
91 | unsigned int (*mach_get_ss)(void); | ||
92 | int (*mach_get_rtc_pll)(struct rtc_pll_info *); | ||
93 | int (*mach_set_rtc_pll)(struct rtc_pll_info *); | ||
94 | EXPORT_SYMBOL(mach_get_ss); | ||
95 | EXPORT_SYMBOL(mach_get_rtc_pll); | ||
96 | EXPORT_SYMBOL(mach_set_rtc_pll); | ||
97 | void (*mach_reset)( void ); | ||
98 | void (*mach_halt)( void ); | ||
99 | void (*mach_power_off)( void ); | ||
100 | long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ | ||
101 | #ifdef CONFIG_HEARTBEAT | ||
102 | void (*mach_heartbeat) (int); | ||
103 | EXPORT_SYMBOL(mach_heartbeat); | ||
104 | #endif | ||
105 | #ifdef CONFIG_M68K_L2_CACHE | ||
106 | void (*mach_l2_flush) (int); | ||
107 | #endif | ||
108 | #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) | ||
109 | void (*mach_beep)(unsigned int, unsigned int); | ||
110 | EXPORT_SYMBOL(mach_beep); | ||
111 | #endif | ||
112 | #if defined(CONFIG_ISA) && defined(MULTI_ISA) | ||
113 | int isa_type; | ||
114 | int isa_sex; | ||
115 | EXPORT_SYMBOL(isa_type); | ||
116 | EXPORT_SYMBOL(isa_sex); | ||
117 | #endif | ||
118 | |||
119 | extern int amiga_parse_bootinfo(const struct bi_record *); | ||
120 | extern int atari_parse_bootinfo(const struct bi_record *); | ||
121 | extern int mac_parse_bootinfo(const struct bi_record *); | ||
122 | extern int q40_parse_bootinfo(const struct bi_record *); | ||
123 | extern int bvme6000_parse_bootinfo(const struct bi_record *); | ||
124 | extern int mvme16x_parse_bootinfo(const struct bi_record *); | ||
125 | extern int mvme147_parse_bootinfo(const struct bi_record *); | ||
126 | extern int hp300_parse_bootinfo(const struct bi_record *); | ||
127 | extern int apollo_parse_bootinfo(const struct bi_record *); | ||
128 | |||
129 | extern void config_amiga(void); | ||
130 | extern void config_atari(void); | ||
131 | extern void config_mac(void); | ||
132 | extern void config_sun3(void); | ||
133 | extern void config_apollo(void); | ||
134 | extern void config_mvme147(void); | ||
135 | extern void config_mvme16x(void); | ||
136 | extern void config_bvme6000(void); | ||
137 | extern void config_hp300(void); | ||
138 | extern void config_q40(void); | ||
139 | extern void config_sun3x(void); | ||
140 | |||
141 | #define MASK_256K 0xfffc0000 | ||
142 | |||
143 | extern void paging_init(void); | ||
144 | |||
145 | static void __init m68k_parse_bootinfo(const struct bi_record *record) | ||
146 | { | ||
147 | while (record->tag != BI_LAST) { | ||
148 | int unknown = 0; | ||
149 | const unsigned long *data = record->data; | ||
150 | |||
151 | switch (record->tag) { | ||
152 | case BI_MACHTYPE: | ||
153 | case BI_CPUTYPE: | ||
154 | case BI_FPUTYPE: | ||
155 | case BI_MMUTYPE: | ||
156 | /* Already set up by head.S */ | ||
157 | break; | ||
158 | |||
159 | case BI_MEMCHUNK: | ||
160 | if (m68k_num_memory < NUM_MEMINFO) { | ||
161 | m68k_memory[m68k_num_memory].addr = data[0]; | ||
162 | m68k_memory[m68k_num_memory].size = data[1]; | ||
163 | m68k_num_memory++; | ||
164 | } else | ||
165 | printk("m68k_parse_bootinfo: too many memory chunks\n"); | ||
166 | break; | ||
167 | |||
168 | case BI_RAMDISK: | ||
169 | m68k_ramdisk.addr = data[0]; | ||
170 | m68k_ramdisk.size = data[1]; | ||
171 | break; | ||
172 | |||
173 | case BI_COMMAND_LINE: | ||
174 | strlcpy(m68k_command_line, (const char *)data, | ||
175 | sizeof(m68k_command_line)); | ||
176 | break; | ||
177 | |||
178 | default: | ||
179 | if (MACH_IS_AMIGA) | ||
180 | unknown = amiga_parse_bootinfo(record); | ||
181 | else if (MACH_IS_ATARI) | ||
182 | unknown = atari_parse_bootinfo(record); | ||
183 | else if (MACH_IS_MAC) | ||
184 | unknown = mac_parse_bootinfo(record); | ||
185 | else if (MACH_IS_Q40) | ||
186 | unknown = q40_parse_bootinfo(record); | ||
187 | else if (MACH_IS_BVME6000) | ||
188 | unknown = bvme6000_parse_bootinfo(record); | ||
189 | else if (MACH_IS_MVME16x) | ||
190 | unknown = mvme16x_parse_bootinfo(record); | ||
191 | else if (MACH_IS_MVME147) | ||
192 | unknown = mvme147_parse_bootinfo(record); | ||
193 | else if (MACH_IS_HP300) | ||
194 | unknown = hp300_parse_bootinfo(record); | ||
195 | else if (MACH_IS_APOLLO) | ||
196 | unknown = apollo_parse_bootinfo(record); | ||
197 | else | ||
198 | unknown = 1; | ||
199 | } | ||
200 | if (unknown) | ||
201 | printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", | ||
202 | record->tag); | ||
203 | record = (struct bi_record *)((unsigned long)record + | ||
204 | record->size); | ||
205 | } | ||
206 | |||
207 | m68k_realnum_memory = m68k_num_memory; | ||
208 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK | ||
209 | if (m68k_num_memory > 1) { | ||
210 | printk("Ignoring last %i chunks of physical memory\n", | ||
211 | (m68k_num_memory - 1)); | ||
212 | m68k_num_memory = 1; | ||
213 | } | ||
214 | #endif | ||
215 | } | ||
216 | |||
217 | void __init setup_arch(char **cmdline_p) | ||
218 | { | ||
219 | int i; | ||
220 | |||
221 | /* The bootinfo is located right after the kernel bss */ | ||
222 | m68k_parse_bootinfo((const struct bi_record *)_end); | ||
223 | |||
224 | if (CPU_IS_040) | ||
225 | m68k_is040or060 = 4; | ||
226 | else if (CPU_IS_060) | ||
227 | m68k_is040or060 = 6; | ||
228 | |||
229 | /* FIXME: m68k_fputype is passed in by Penguin booter, which can | ||
230 | * be confused by software FPU emulation. BEWARE. | ||
231 | * We should really do our own FPU check at startup. | ||
232 | * [what do we do with buggy 68LC040s? if we have problems | ||
233 | * with them, we should add a test to check_bugs() below] */ | ||
234 | #ifndef CONFIG_M68KFPU_EMU_ONLY | ||
235 | /* clear the fpu if we have one */ | ||
236 | if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { | ||
237 | volatile int zero = 0; | ||
238 | asm volatile ("frestore %0" : : "m" (zero)); | ||
239 | } | ||
240 | #endif | ||
241 | |||
242 | if (CPU_IS_060) { | ||
243 | u32 pcr; | ||
244 | |||
245 | asm (".chip 68060; movec %%pcr,%0; .chip 68k" | ||
246 | : "=d" (pcr)); | ||
247 | if (((pcr >> 8) & 0xff) <= 5) { | ||
248 | printk("Enabling workaround for errata I14\n"); | ||
249 | asm (".chip 68060; movec %0,%%pcr; .chip 68k" | ||
250 | : : "d" (pcr | 0x20)); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | init_mm.start_code = PAGE_OFFSET; | ||
255 | init_mm.end_code = (unsigned long)_etext; | ||
256 | init_mm.end_data = (unsigned long)_edata; | ||
257 | init_mm.brk = (unsigned long)_end; | ||
258 | |||
259 | *cmdline_p = m68k_command_line; | ||
260 | memcpy(boot_command_line, *cmdline_p, CL_SIZE); | ||
261 | |||
262 | parse_early_param(); | ||
263 | |||
264 | #ifdef CONFIG_DUMMY_CONSOLE | ||
265 | conswitchp = &dummy_con; | ||
266 | #endif | ||
267 | |||
268 | switch (m68k_machtype) { | ||
269 | #ifdef CONFIG_AMIGA | ||
270 | case MACH_AMIGA: | ||
271 | config_amiga(); | ||
272 | break; | ||
273 | #endif | ||
274 | #ifdef CONFIG_ATARI | ||
275 | case MACH_ATARI: | ||
276 | config_atari(); | ||
277 | break; | ||
278 | #endif | ||
279 | #ifdef CONFIG_MAC | ||
280 | case MACH_MAC: | ||
281 | config_mac(); | ||
282 | break; | ||
283 | #endif | ||
284 | #ifdef CONFIG_SUN3 | ||
285 | case MACH_SUN3: | ||
286 | config_sun3(); | ||
287 | break; | ||
288 | #endif | ||
289 | #ifdef CONFIG_APOLLO | ||
290 | case MACH_APOLLO: | ||
291 | config_apollo(); | ||
292 | break; | ||
293 | #endif | ||
294 | #ifdef CONFIG_MVME147 | ||
295 | case MACH_MVME147: | ||
296 | config_mvme147(); | ||
297 | break; | ||
298 | #endif | ||
299 | #ifdef CONFIG_MVME16x | ||
300 | case MACH_MVME16x: | ||
301 | config_mvme16x(); | ||
302 | break; | ||
303 | #endif | ||
304 | #ifdef CONFIG_BVME6000 | ||
305 | case MACH_BVME6000: | ||
306 | config_bvme6000(); | ||
307 | break; | ||
308 | #endif | ||
309 | #ifdef CONFIG_HP300 | ||
310 | case MACH_HP300: | ||
311 | config_hp300(); | ||
312 | break; | ||
313 | #endif | ||
314 | #ifdef CONFIG_Q40 | ||
315 | case MACH_Q40: | ||
316 | config_q40(); | ||
317 | break; | ||
318 | #endif | ||
319 | #ifdef CONFIG_SUN3X | ||
320 | case MACH_SUN3X: | ||
321 | config_sun3x(); | ||
322 | break; | ||
323 | #endif | ||
324 | default: | ||
325 | panic("No configuration setup"); | ||
326 | } | ||
327 | |||
328 | #ifdef CONFIG_NATFEAT | ||
329 | nf_init(); | ||
330 | #endif | ||
331 | |||
332 | paging_init(); | ||
333 | |||
334 | #ifndef CONFIG_SUN3 | ||
335 | for (i = 1; i < m68k_num_memory; i++) | ||
336 | free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr, | ||
337 | m68k_memory[i].size); | ||
338 | #ifdef CONFIG_BLK_DEV_INITRD | ||
339 | if (m68k_ramdisk.size) { | ||
340 | reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)), | ||
341 | m68k_ramdisk.addr, m68k_ramdisk.size, | ||
342 | BOOTMEM_DEFAULT); | ||
343 | initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); | ||
344 | initrd_end = initrd_start + m68k_ramdisk.size; | ||
345 | printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); | ||
346 | } | ||
347 | #endif | ||
348 | |||
349 | #ifdef CONFIG_ATARI | ||
350 | if (MACH_IS_ATARI) | ||
351 | atari_stram_reserve_pages((void *)availmem); | ||
352 | #endif | ||
353 | #ifdef CONFIG_SUN3X | ||
354 | if (MACH_IS_SUN3X) { | ||
355 | dvma_init(); | ||
356 | } | ||
357 | #endif | ||
358 | |||
359 | #endif /* !CONFIG_SUN3 */ | ||
360 | |||
361 | /* set ISA defs early as possible */ | ||
362 | #if defined(CONFIG_ISA) && defined(MULTI_ISA) | ||
363 | if (MACH_IS_Q40) { | ||
364 | isa_type = ISA_TYPE_Q40; | ||
365 | isa_sex = 0; | ||
366 | } | ||
367 | #ifdef CONFIG_AMIGA_PCMCIA | ||
368 | if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) { | ||
369 | isa_type = ISA_TYPE_AG; | ||
370 | isa_sex = 1; | ||
371 | } | ||
372 | #endif | ||
373 | #endif | ||
374 | } | ||
375 | |||
376 | static int show_cpuinfo(struct seq_file *m, void *v) | ||
377 | { | ||
378 | const char *cpu, *mmu, *fpu; | ||
379 | unsigned long clockfreq, clockfactor; | ||
380 | |||
381 | #define LOOP_CYCLES_68020 (8) | ||
382 | #define LOOP_CYCLES_68030 (8) | ||
383 | #define LOOP_CYCLES_68040 (3) | ||
384 | #define LOOP_CYCLES_68060 (1) | ||
385 | |||
386 | if (CPU_IS_020) { | ||
387 | cpu = "68020"; | ||
388 | clockfactor = LOOP_CYCLES_68020; | ||
389 | } else if (CPU_IS_030) { | ||
390 | cpu = "68030"; | ||
391 | clockfactor = LOOP_CYCLES_68030; | ||
392 | } else if (CPU_IS_040) { | ||
393 | cpu = "68040"; | ||
394 | clockfactor = LOOP_CYCLES_68040; | ||
395 | } else if (CPU_IS_060) { | ||
396 | cpu = "68060"; | ||
397 | clockfactor = LOOP_CYCLES_68060; | ||
398 | } else { | ||
399 | cpu = "680x0"; | ||
400 | clockfactor = 0; | ||
401 | } | ||
402 | |||
403 | #ifdef CONFIG_M68KFPU_EMU_ONLY | ||
404 | fpu = "none(soft float)"; | ||
405 | #else | ||
406 | if (m68k_fputype & FPU_68881) | ||
407 | fpu = "68881"; | ||
408 | else if (m68k_fputype & FPU_68882) | ||
409 | fpu = "68882"; | ||
410 | else if (m68k_fputype & FPU_68040) | ||
411 | fpu = "68040"; | ||
412 | else if (m68k_fputype & FPU_68060) | ||
413 | fpu = "68060"; | ||
414 | else if (m68k_fputype & FPU_SUNFPA) | ||
415 | fpu = "Sun FPA"; | ||
416 | else | ||
417 | fpu = "none"; | ||
418 | #endif | ||
419 | |||
420 | if (m68k_mmutype & MMU_68851) | ||
421 | mmu = "68851"; | ||
422 | else if (m68k_mmutype & MMU_68030) | ||
423 | mmu = "68030"; | ||
424 | else if (m68k_mmutype & MMU_68040) | ||
425 | mmu = "68040"; | ||
426 | else if (m68k_mmutype & MMU_68060) | ||
427 | mmu = "68060"; | ||
428 | else if (m68k_mmutype & MMU_SUN3) | ||
429 | mmu = "Sun-3"; | ||
430 | else if (m68k_mmutype & MMU_APOLLO) | ||
431 | mmu = "Apollo"; | ||
432 | else | ||
433 | mmu = "unknown"; | ||
434 | |||
435 | clockfreq = loops_per_jiffy * HZ * clockfactor; | ||
436 | |||
437 | seq_printf(m, "CPU:\t\t%s\n" | ||
438 | "MMU:\t\t%s\n" | ||
439 | "FPU:\t\t%s\n" | ||
440 | "Clocking:\t%lu.%1luMHz\n" | ||
441 | "BogoMips:\t%lu.%02lu\n" | ||
442 | "Calibration:\t%lu loops\n", | ||
443 | cpu, mmu, fpu, | ||
444 | clockfreq/1000000,(clockfreq/100000)%10, | ||
445 | loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100, | ||
446 | loops_per_jiffy); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
451 | { | ||
452 | return *pos < 1 ? (void *)1 : NULL; | ||
453 | } | ||
454 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
455 | { | ||
456 | ++*pos; | ||
457 | return NULL; | ||
458 | } | ||
459 | static void c_stop(struct seq_file *m, void *v) | ||
460 | { | ||
461 | } | ||
462 | const struct seq_operations cpuinfo_op = { | ||
463 | .start = c_start, | ||
464 | .next = c_next, | ||
465 | .stop = c_stop, | ||
466 | .show = show_cpuinfo, | ||
467 | }; | ||
468 | |||
469 | #ifdef CONFIG_PROC_HARDWARE | ||
470 | static int hardware_proc_show(struct seq_file *m, void *v) | ||
471 | { | ||
472 | char model[80]; | ||
473 | unsigned long mem; | ||
474 | int i; | ||
475 | |||
476 | if (mach_get_model) | ||
477 | mach_get_model(model); | ||
478 | else | ||
479 | strcpy(model, "Unknown m68k"); | ||
480 | |||
481 | seq_printf(m, "Model:\t\t%s\n", model); | ||
482 | for (mem = 0, i = 0; i < m68k_num_memory; i++) | ||
483 | mem += m68k_memory[i].size; | ||
484 | seq_printf(m, "System Memory:\t%ldK\n", mem >> 10); | ||
485 | |||
486 | if (mach_get_hardware_list) | ||
487 | mach_get_hardware_list(m); | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int hardware_proc_open(struct inode *inode, struct file *file) | ||
493 | { | ||
494 | return single_open(file, hardware_proc_show, NULL); | ||
495 | } | ||
496 | |||
497 | static const struct file_operations hardware_proc_fops = { | ||
498 | .open = hardware_proc_open, | ||
499 | .read = seq_read, | ||
500 | .llseek = seq_lseek, | ||
501 | .release = single_release, | ||
502 | }; | ||
503 | |||
504 | static int __init proc_hardware_init(void) | ||
505 | { | ||
506 | proc_create("hardware", 0, NULL, &hardware_proc_fops); | ||
507 | return 0; | ||
508 | } | ||
509 | module_init(proc_hardware_init); | ||
510 | #endif | ||
511 | |||
512 | void check_bugs(void) | ||
513 | { | ||
514 | #ifndef CONFIG_M68KFPU_EMU | ||
515 | if (m68k_fputype == 0) { | ||
516 | printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " | ||
517 | "WHICH IS REQUIRED BY LINUX/M68K ***\n"); | ||
518 | printk(KERN_EMERG "Upgrade your hardware or join the FPU " | ||
519 | "emulation project\n"); | ||
520 | panic("no FPU"); | ||
521 | } | ||
522 | #endif /* !CONFIG_M68KFPU_EMU */ | ||
523 | } | ||
524 | |||
525 | #ifdef CONFIG_ADB | ||
526 | static int __init adb_probe_sync_enable (char *str) { | ||
527 | extern int __adb_probe_sync; | ||
528 | __adb_probe_sync = 1; | ||
529 | return 1; | ||
530 | } | ||
531 | |||
532 | __setup("adb_sync", adb_probe_sync_enable); | ||
533 | #endif /* CONFIG_ADB */ | ||
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68k/kernel/setup_no.c index 16b2de7f5101..16b2de7f5101 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68k/kernel/setup_no.c | |||
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index a0afc239304e..2e25713e2ead 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c | |||
@@ -1,1017 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/kernel/signal.c | 2 | #include "signal_mm.c" |
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
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 | |||
11 | /* | ||
12 | * Linux/m68k support by Hamish Macdonald | ||
13 | * | ||
14 | * 68060 fixes by Jesper Skov | ||
15 | * | ||
16 | * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab | ||
17 | * | ||
18 | * mathemu support by Roman Zippel | ||
19 | * (Note: fpstate in the signal context is completely ignored for the emulator | ||
20 | * and the internal floating point format is put on stack) | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * ++roman (07/09/96): implemented signal stacks (specially for tosemu on | ||
25 | * Atari :-) Current limitation: Only one sigstack can be active at one time. | ||
26 | * If a second signal with SA_ONSTACK set arrives while working on a sigstack, | ||
27 | * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested | ||
28 | * signal handlers! | ||
29 | */ | ||
30 | |||
31 | #include <linux/sched.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/signal.h> | ||
35 | #include <linux/syscalls.h> | ||
36 | #include <linux/errno.h> | ||
37 | #include <linux/wait.h> | ||
38 | #include <linux/ptrace.h> | ||
39 | #include <linux/unistd.h> | ||
40 | #include <linux/stddef.h> | ||
41 | #include <linux/highuid.h> | ||
42 | #include <linux/personality.h> | ||
43 | #include <linux/tty.h> | ||
44 | #include <linux/binfmts.h> | ||
45 | #include <linux/module.h> | ||
46 | |||
47 | #include <asm/setup.h> | ||
48 | #include <asm/uaccess.h> | ||
49 | #include <asm/pgtable.h> | ||
50 | #include <asm/traps.h> | ||
51 | #include <asm/ucontext.h> | ||
52 | |||
53 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
54 | |||
55 | static const int frame_extra_sizes[16] = { | ||
56 | [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ | ||
57 | [2] = sizeof(((struct frame *)0)->un.fmt2), | ||
58 | [3] = sizeof(((struct frame *)0)->un.fmt3), | ||
59 | [4] = sizeof(((struct frame *)0)->un.fmt4), | ||
60 | [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ | ||
61 | [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ | ||
62 | [7] = sizeof(((struct frame *)0)->un.fmt7), | ||
63 | [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */ | ||
64 | [9] = sizeof(((struct frame *)0)->un.fmt9), | ||
65 | [10] = sizeof(((struct frame *)0)->un.fmta), | ||
66 | [11] = sizeof(((struct frame *)0)->un.fmtb), | ||
67 | [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */ | ||
68 | [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */ | ||
69 | [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */ | ||
70 | [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ | ||
71 | }; | ||
72 | |||
73 | int handle_kernel_fault(struct pt_regs *regs) | ||
74 | { | ||
75 | const struct exception_table_entry *fixup; | ||
76 | struct pt_regs *tregs; | ||
77 | |||
78 | /* Are we prepared to handle this kernel fault? */ | ||
79 | fixup = search_exception_tables(regs->pc); | ||
80 | if (!fixup) | ||
81 | return 0; | ||
82 | |||
83 | /* Create a new four word stack frame, discarding the old one. */ | ||
84 | regs->stkadj = frame_extra_sizes[regs->format]; | ||
85 | tregs = (struct pt_regs *)((long)regs + regs->stkadj); | ||
86 | tregs->vector = regs->vector; | ||
87 | tregs->format = 0; | ||
88 | tregs->pc = fixup->fixup; | ||
89 | tregs->sr = regs->sr; | ||
90 | |||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Atomically swap in the new signal mask, and wait for a signal. | ||
96 | */ | ||
97 | asmlinkage int | ||
98 | sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) | ||
99 | { | ||
100 | mask &= _BLOCKABLE; | ||
101 | spin_lock_irq(¤t->sighand->siglock); | ||
102 | current->saved_sigmask = current->blocked; | ||
103 | siginitset(¤t->blocked, mask); | ||
104 | recalc_sigpending(); | ||
105 | spin_unlock_irq(¤t->sighand->siglock); | ||
106 | |||
107 | current->state = TASK_INTERRUPTIBLE; | ||
108 | schedule(); | ||
109 | set_restore_sigmask(); | ||
110 | |||
111 | return -ERESTARTNOHAND; | ||
112 | } | ||
113 | |||
114 | asmlinkage int | ||
115 | sys_sigaction(int sig, const struct old_sigaction __user *act, | ||
116 | struct old_sigaction __user *oact) | ||
117 | { | ||
118 | struct k_sigaction new_ka, old_ka; | ||
119 | int ret; | ||
120 | |||
121 | if (act) { | ||
122 | old_sigset_t mask; | ||
123 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
124 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
125 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || | ||
126 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
127 | __get_user(mask, &act->sa_mask)) | ||
128 | return -EFAULT; | ||
129 | siginitset(&new_ka.sa.sa_mask, mask); | ||
130 | } | ||
131 | |||
132 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
133 | |||
134 | if (!ret && oact) { | ||
135 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
136 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
137 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || | ||
138 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
139 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
140 | return -EFAULT; | ||
141 | } | ||
142 | |||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | asmlinkage int | ||
147 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) | ||
148 | { | ||
149 | return do_sigaltstack(uss, uoss, rdusp()); | ||
150 | } | ||
151 | |||
152 | |||
153 | /* | ||
154 | * Do a signal return; undo the signal stack. | ||
155 | * | ||
156 | * Keep the return code on the stack quadword aligned! | ||
157 | * That makes the cache flush below easier. | ||
158 | */ | ||
159 | |||
160 | struct sigframe | ||
161 | { | ||
162 | char __user *pretcode; | ||
163 | int sig; | ||
164 | int code; | ||
165 | struct sigcontext __user *psc; | ||
166 | char retcode[8]; | ||
167 | unsigned long extramask[_NSIG_WORDS-1]; | ||
168 | struct sigcontext sc; | ||
169 | }; | ||
170 | |||
171 | struct rt_sigframe | ||
172 | { | ||
173 | char __user *pretcode; | ||
174 | int sig; | ||
175 | struct siginfo __user *pinfo; | ||
176 | void __user *puc; | ||
177 | char retcode[8]; | ||
178 | struct siginfo info; | ||
179 | struct ucontext uc; | ||
180 | }; | ||
181 | |||
182 | |||
183 | static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ | ||
184 | |||
185 | static inline int restore_fpu_state(struct sigcontext *sc) | ||
186 | { | ||
187 | int err = 1; | ||
188 | |||
189 | if (FPU_IS_EMU) { | ||
190 | /* restore registers */ | ||
191 | memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); | ||
192 | memcpy(current->thread.fp, sc->sc_fpregs, 24); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { | ||
197 | /* Verify the frame format. */ | ||
198 | if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) | ||
199 | goto out; | ||
200 | if (CPU_IS_020_OR_030) { | ||
201 | if (m68k_fputype & FPU_68881 && | ||
202 | !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4)) | ||
203 | goto out; | ||
204 | if (m68k_fputype & FPU_68882 && | ||
205 | !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4)) | ||
206 | goto out; | ||
207 | } else if (CPU_IS_040) { | ||
208 | if (!(sc->sc_fpstate[1] == 0x00 || | ||
209 | sc->sc_fpstate[1] == 0x28 || | ||
210 | sc->sc_fpstate[1] == 0x60)) | ||
211 | goto out; | ||
212 | } else if (CPU_IS_060) { | ||
213 | if (!(sc->sc_fpstate[3] == 0x00 || | ||
214 | sc->sc_fpstate[3] == 0x60 || | ||
215 | sc->sc_fpstate[3] == 0xe0)) | ||
216 | goto out; | ||
217 | } else | ||
218 | goto out; | ||
219 | |||
220 | __asm__ volatile (".chip 68k/68881\n\t" | ||
221 | "fmovemx %0,%%fp0-%%fp1\n\t" | ||
222 | "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" | ||
223 | ".chip 68k" | ||
224 | : /* no outputs */ | ||
225 | : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); | ||
226 | } | ||
227 | __asm__ volatile (".chip 68k/68881\n\t" | ||
228 | "frestore %0\n\t" | ||
229 | ".chip 68k" : : "m" (*sc->sc_fpstate)); | ||
230 | err = 0; | ||
231 | |||
232 | out: | ||
233 | return err; | ||
234 | } | ||
235 | |||
236 | #define FPCONTEXT_SIZE 216 | ||
237 | #define uc_fpstate uc_filler[0] | ||
238 | #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] | ||
239 | #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] | ||
240 | |||
241 | static inline int rt_restore_fpu_state(struct ucontext __user *uc) | ||
242 | { | ||
243 | unsigned char fpstate[FPCONTEXT_SIZE]; | ||
244 | int context_size = CPU_IS_060 ? 8 : 0; | ||
245 | fpregset_t fpregs; | ||
246 | int err = 1; | ||
247 | |||
248 | if (FPU_IS_EMU) { | ||
249 | /* restore fpu control register */ | ||
250 | if (__copy_from_user(current->thread.fpcntl, | ||
251 | uc->uc_mcontext.fpregs.f_fpcntl, 12)) | ||
252 | goto out; | ||
253 | /* restore all other fpu register */ | ||
254 | if (__copy_from_user(current->thread.fp, | ||
255 | uc->uc_mcontext.fpregs.f_fpregs, 96)) | ||
256 | goto out; | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) | ||
261 | goto out; | ||
262 | if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { | ||
263 | if (!CPU_IS_060) | ||
264 | context_size = fpstate[1]; | ||
265 | /* Verify the frame format. */ | ||
266 | if (!CPU_IS_060 && (fpstate[0] != fpu_version)) | ||
267 | goto out; | ||
268 | if (CPU_IS_020_OR_030) { | ||
269 | if (m68k_fputype & FPU_68881 && | ||
270 | !(context_size == 0x18 || context_size == 0xb4)) | ||
271 | goto out; | ||
272 | if (m68k_fputype & FPU_68882 && | ||
273 | !(context_size == 0x38 || context_size == 0xd4)) | ||
274 | goto out; | ||
275 | } else if (CPU_IS_040) { | ||
276 | if (!(context_size == 0x00 || | ||
277 | context_size == 0x28 || | ||
278 | context_size == 0x60)) | ||
279 | goto out; | ||
280 | } else if (CPU_IS_060) { | ||
281 | if (!(fpstate[3] == 0x00 || | ||
282 | fpstate[3] == 0x60 || | ||
283 | fpstate[3] == 0xe0)) | ||
284 | goto out; | ||
285 | } else | ||
286 | goto out; | ||
287 | if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, | ||
288 | sizeof(fpregs))) | ||
289 | goto out; | ||
290 | __asm__ volatile (".chip 68k/68881\n\t" | ||
291 | "fmovemx %0,%%fp0-%%fp7\n\t" | ||
292 | "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" | ||
293 | ".chip 68k" | ||
294 | : /* no outputs */ | ||
295 | : "m" (*fpregs.f_fpregs), | ||
296 | "m" (*fpregs.f_fpcntl)); | ||
297 | } | ||
298 | if (context_size && | ||
299 | __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, | ||
300 | context_size)) | ||
301 | goto out; | ||
302 | __asm__ volatile (".chip 68k/68881\n\t" | ||
303 | "frestore %0\n\t" | ||
304 | ".chip 68k" : : "m" (*fpstate)); | ||
305 | err = 0; | ||
306 | |||
307 | out: | ||
308 | return err; | ||
309 | } | ||
310 | |||
311 | static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, | ||
312 | void __user *fp) | ||
313 | { | ||
314 | int fsize = frame_extra_sizes[formatvec >> 12]; | ||
315 | if (fsize < 0) { | ||
316 | /* | ||
317 | * user process trying to return with weird frame format | ||
318 | */ | ||
319 | #ifdef DEBUG | ||
320 | printk("user process returning with weird frame format\n"); | ||
321 | #endif | ||
322 | return 1; | ||
323 | } | ||
324 | if (!fsize) { | ||
325 | regs->format = formatvec >> 12; | ||
326 | regs->vector = formatvec & 0xfff; | ||
327 | } else { | ||
328 | struct switch_stack *sw = (struct switch_stack *)regs - 1; | ||
329 | unsigned long buf[fsize / 2]; /* yes, twice as much */ | ||
330 | |||
331 | /* that'll make sure that expansion won't crap over data */ | ||
332 | if (copy_from_user(buf + fsize / 4, fp, fsize)) | ||
333 | return 1; | ||
334 | |||
335 | /* point of no return */ | ||
336 | regs->format = formatvec >> 12; | ||
337 | regs->vector = formatvec & 0xfff; | ||
338 | #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) | ||
339 | __asm__ __volatile__ | ||
340 | (" movel %0,%/a0\n\t" | ||
341 | " subl %1,%/a0\n\t" /* make room on stack */ | ||
342 | " movel %/a0,%/sp\n\t" /* set stack pointer */ | ||
343 | /* move switch_stack and pt_regs */ | ||
344 | "1: movel %0@+,%/a0@+\n\t" | ||
345 | " dbra %2,1b\n\t" | ||
346 | " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ | ||
347 | " lsrl #2,%1\n\t" | ||
348 | " subql #1,%1\n\t" | ||
349 | /* copy to the gap we'd made */ | ||
350 | "2: movel %4@+,%/a0@+\n\t" | ||
351 | " dbra %1,2b\n\t" | ||
352 | " bral ret_from_signal\n" | ||
353 | : /* no outputs, it doesn't ever return */ | ||
354 | : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), | ||
355 | "n" (frame_offset), "a" (buf + fsize/4) | ||
356 | : "a0"); | ||
357 | #undef frame_offset | ||
358 | } | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static inline int | ||
363 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp) | ||
364 | { | ||
365 | int formatvec; | ||
366 | struct sigcontext context; | ||
367 | int err; | ||
368 | |||
369 | /* Always make any pending restarted system calls return -EINTR */ | ||
370 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
371 | |||
372 | /* get previous context */ | ||
373 | if (copy_from_user(&context, usc, sizeof(context))) | ||
374 | goto badframe; | ||
375 | |||
376 | /* restore passed registers */ | ||
377 | regs->d0 = context.sc_d0; | ||
378 | regs->d1 = context.sc_d1; | ||
379 | regs->a0 = context.sc_a0; | ||
380 | regs->a1 = context.sc_a1; | ||
381 | regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); | ||
382 | regs->pc = context.sc_pc; | ||
383 | regs->orig_d0 = -1; /* disable syscall checks */ | ||
384 | wrusp(context.sc_usp); | ||
385 | formatvec = context.sc_formatvec; | ||
386 | |||
387 | err = restore_fpu_state(&context); | ||
388 | |||
389 | if (err || mangle_kernel_stack(regs, formatvec, fp)) | ||
390 | goto badframe; | ||
391 | |||
392 | return 0; | ||
393 | |||
394 | badframe: | ||
395 | return 1; | ||
396 | } | ||
397 | |||
398 | static inline int | ||
399 | rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, | ||
400 | struct ucontext __user *uc) | ||
401 | { | ||
402 | int temp; | ||
403 | greg_t __user *gregs = uc->uc_mcontext.gregs; | ||
404 | unsigned long usp; | ||
405 | int err; | ||
406 | |||
407 | /* Always make any pending restarted system calls return -EINTR */ | ||
408 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
409 | |||
410 | err = __get_user(temp, &uc->uc_mcontext.version); | ||
411 | if (temp != MCONTEXT_VERSION) | ||
412 | goto badframe; | ||
413 | /* restore passed registers */ | ||
414 | err |= __get_user(regs->d0, &gregs[0]); | ||
415 | err |= __get_user(regs->d1, &gregs[1]); | ||
416 | err |= __get_user(regs->d2, &gregs[2]); | ||
417 | err |= __get_user(regs->d3, &gregs[3]); | ||
418 | err |= __get_user(regs->d4, &gregs[4]); | ||
419 | err |= __get_user(regs->d5, &gregs[5]); | ||
420 | err |= __get_user(sw->d6, &gregs[6]); | ||
421 | err |= __get_user(sw->d7, &gregs[7]); | ||
422 | err |= __get_user(regs->a0, &gregs[8]); | ||
423 | err |= __get_user(regs->a1, &gregs[9]); | ||
424 | err |= __get_user(regs->a2, &gregs[10]); | ||
425 | err |= __get_user(sw->a3, &gregs[11]); | ||
426 | err |= __get_user(sw->a4, &gregs[12]); | ||
427 | err |= __get_user(sw->a5, &gregs[13]); | ||
428 | err |= __get_user(sw->a6, &gregs[14]); | ||
429 | err |= __get_user(usp, &gregs[15]); | ||
430 | wrusp(usp); | ||
431 | err |= __get_user(regs->pc, &gregs[16]); | ||
432 | err |= __get_user(temp, &gregs[17]); | ||
433 | regs->sr = (regs->sr & 0xff00) | (temp & 0xff); | ||
434 | regs->orig_d0 = -1; /* disable syscall checks */ | ||
435 | err |= __get_user(temp, &uc->uc_formatvec); | ||
436 | |||
437 | err |= rt_restore_fpu_state(uc); | ||
438 | |||
439 | if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) | ||
440 | goto badframe; | ||
441 | |||
442 | if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) | ||
443 | goto badframe; | ||
444 | |||
445 | return 0; | ||
446 | |||
447 | badframe: | ||
448 | return 1; | ||
449 | } | ||
450 | |||
451 | asmlinkage int do_sigreturn(unsigned long __unused) | ||
452 | { | ||
453 | struct switch_stack *sw = (struct switch_stack *) &__unused; | ||
454 | struct pt_regs *regs = (struct pt_regs *) (sw + 1); | ||
455 | unsigned long usp = rdusp(); | ||
456 | struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); | ||
457 | sigset_t set; | ||
458 | |||
459 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
460 | goto badframe; | ||
461 | if (__get_user(set.sig[0], &frame->sc.sc_mask) || | ||
462 | (_NSIG_WORDS > 1 && | ||
463 | __copy_from_user(&set.sig[1], &frame->extramask, | ||
464 | sizeof(frame->extramask)))) | ||
465 | goto badframe; | ||
466 | |||
467 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
468 | current->blocked = set; | ||
469 | recalc_sigpending(); | ||
470 | |||
471 | if (restore_sigcontext(regs, &frame->sc, frame + 1)) | ||
472 | goto badframe; | ||
473 | return regs->d0; | ||
474 | |||
475 | badframe: | ||
476 | force_sig(SIGSEGV, current); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | asmlinkage int do_rt_sigreturn(unsigned long __unused) | ||
481 | { | ||
482 | struct switch_stack *sw = (struct switch_stack *) &__unused; | ||
483 | struct pt_regs *regs = (struct pt_regs *) (sw + 1); | ||
484 | unsigned long usp = rdusp(); | ||
485 | struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); | ||
486 | sigset_t set; | ||
487 | |||
488 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
489 | goto badframe; | ||
490 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | ||
491 | goto badframe; | ||
492 | |||
493 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
494 | current->blocked = set; | ||
495 | recalc_sigpending(); | ||
496 | |||
497 | if (rt_restore_ucontext(regs, sw, &frame->uc)) | ||
498 | goto badframe; | ||
499 | return regs->d0; | ||
500 | |||
501 | badframe: | ||
502 | force_sig(SIGSEGV, current); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * Set up a signal frame. | ||
508 | */ | ||
509 | |||
510 | static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) | ||
511 | { | ||
512 | if (FPU_IS_EMU) { | ||
513 | /* save registers */ | ||
514 | memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); | ||
515 | memcpy(sc->sc_fpregs, current->thread.fp, 24); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | __asm__ volatile (".chip 68k/68881\n\t" | ||
520 | "fsave %0\n\t" | ||
521 | ".chip 68k" | ||
522 | : : "m" (*sc->sc_fpstate) : "memory"); | ||
523 | |||
524 | if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { | ||
525 | fpu_version = sc->sc_fpstate[0]; | ||
526 | if (CPU_IS_020_OR_030 && | ||
527 | regs->vector >= (VEC_FPBRUC * 4) && | ||
528 | regs->vector <= (VEC_FPNAN * 4)) { | ||
529 | /* Clear pending exception in 68882 idle frame */ | ||
530 | if (*(unsigned short *) sc->sc_fpstate == 0x1f38) | ||
531 | sc->sc_fpstate[0x38] |= 1 << 3; | ||
532 | } | ||
533 | __asm__ volatile (".chip 68k/68881\n\t" | ||
534 | "fmovemx %%fp0-%%fp1,%0\n\t" | ||
535 | "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" | ||
536 | ".chip 68k" | ||
537 | : "=m" (*sc->sc_fpregs), | ||
538 | "=m" (*sc->sc_fpcntl) | ||
539 | : /* no inputs */ | ||
540 | : "memory"); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) | ||
545 | { | ||
546 | unsigned char fpstate[FPCONTEXT_SIZE]; | ||
547 | int context_size = CPU_IS_060 ? 8 : 0; | ||
548 | int err = 0; | ||
549 | |||
550 | if (FPU_IS_EMU) { | ||
551 | /* save fpu control register */ | ||
552 | err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, | ||
553 | current->thread.fpcntl, 12); | ||
554 | /* save all other fpu register */ | ||
555 | err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, | ||
556 | current->thread.fp, 96); | ||
557 | return err; | ||
558 | } | ||
559 | |||
560 | __asm__ volatile (".chip 68k/68881\n\t" | ||
561 | "fsave %0\n\t" | ||
562 | ".chip 68k" | ||
563 | : : "m" (*fpstate) : "memory"); | ||
564 | |||
565 | err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); | ||
566 | if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { | ||
567 | fpregset_t fpregs; | ||
568 | if (!CPU_IS_060) | ||
569 | context_size = fpstate[1]; | ||
570 | fpu_version = fpstate[0]; | ||
571 | if (CPU_IS_020_OR_030 && | ||
572 | regs->vector >= (VEC_FPBRUC * 4) && | ||
573 | regs->vector <= (VEC_FPNAN * 4)) { | ||
574 | /* Clear pending exception in 68882 idle frame */ | ||
575 | if (*(unsigned short *) fpstate == 0x1f38) | ||
576 | fpstate[0x38] |= 1 << 3; | ||
577 | } | ||
578 | __asm__ volatile (".chip 68k/68881\n\t" | ||
579 | "fmovemx %%fp0-%%fp7,%0\n\t" | ||
580 | "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" | ||
581 | ".chip 68k" | ||
582 | : "=m" (*fpregs.f_fpregs), | ||
583 | "=m" (*fpregs.f_fpcntl) | ||
584 | : /* no inputs */ | ||
585 | : "memory"); | ||
586 | err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, | ||
587 | sizeof(fpregs)); | ||
588 | } | ||
589 | if (context_size) | ||
590 | err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, | ||
591 | context_size); | ||
592 | return err; | ||
593 | } | ||
594 | |||
595 | static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, | ||
596 | unsigned long mask) | ||
597 | { | ||
598 | sc->sc_mask = mask; | ||
599 | sc->sc_usp = rdusp(); | ||
600 | sc->sc_d0 = regs->d0; | ||
601 | sc->sc_d1 = regs->d1; | ||
602 | sc->sc_a0 = regs->a0; | ||
603 | sc->sc_a1 = regs->a1; | ||
604 | sc->sc_sr = regs->sr; | ||
605 | sc->sc_pc = regs->pc; | ||
606 | sc->sc_formatvec = regs->format << 12 | regs->vector; | ||
607 | save_fpu_state(sc, regs); | ||
608 | } | ||
609 | |||
610 | static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) | ||
611 | { | ||
612 | struct switch_stack *sw = (struct switch_stack *)regs - 1; | ||
613 | greg_t __user *gregs = uc->uc_mcontext.gregs; | ||
614 | int err = 0; | ||
615 | |||
616 | err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); | ||
617 | err |= __put_user(regs->d0, &gregs[0]); | ||
618 | err |= __put_user(regs->d1, &gregs[1]); | ||
619 | err |= __put_user(regs->d2, &gregs[2]); | ||
620 | err |= __put_user(regs->d3, &gregs[3]); | ||
621 | err |= __put_user(regs->d4, &gregs[4]); | ||
622 | err |= __put_user(regs->d5, &gregs[5]); | ||
623 | err |= __put_user(sw->d6, &gregs[6]); | ||
624 | err |= __put_user(sw->d7, &gregs[7]); | ||
625 | err |= __put_user(regs->a0, &gregs[8]); | ||
626 | err |= __put_user(regs->a1, &gregs[9]); | ||
627 | err |= __put_user(regs->a2, &gregs[10]); | ||
628 | err |= __put_user(sw->a3, &gregs[11]); | ||
629 | err |= __put_user(sw->a4, &gregs[12]); | ||
630 | err |= __put_user(sw->a5, &gregs[13]); | ||
631 | err |= __put_user(sw->a6, &gregs[14]); | ||
632 | err |= __put_user(rdusp(), &gregs[15]); | ||
633 | err |= __put_user(regs->pc, &gregs[16]); | ||
634 | err |= __put_user(regs->sr, &gregs[17]); | ||
635 | err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); | ||
636 | err |= rt_save_fpu_state(uc, regs); | ||
637 | return err; | ||
638 | } | ||
639 | |||
640 | static inline void push_cache (unsigned long vaddr) | ||
641 | { | ||
642 | /* | ||
643 | * Using the old cache_push_v() was really a big waste. | ||
644 | * | ||
645 | * What we are trying to do is to flush 8 bytes to ram. | ||
646 | * Flushing 2 cache lines of 16 bytes is much cheaper than | ||
647 | * flushing 1 or 2 pages, as previously done in | ||
648 | * cache_push_v(). | ||
649 | * Jes | ||
650 | */ | ||
651 | if (CPU_IS_040) { | ||
652 | unsigned long temp; | ||
653 | |||
654 | __asm__ __volatile__ (".chip 68040\n\t" | ||
655 | "nop\n\t" | ||
656 | "ptestr (%1)\n\t" | ||
657 | "movec %%mmusr,%0\n\t" | ||
658 | ".chip 68k" | ||
659 | : "=r" (temp) | ||
660 | : "a" (vaddr)); | ||
661 | |||
662 | temp &= PAGE_MASK; | ||
663 | temp |= vaddr & ~PAGE_MASK; | ||
664 | |||
665 | __asm__ __volatile__ (".chip 68040\n\t" | ||
666 | "nop\n\t" | ||
667 | "cpushl %%bc,(%0)\n\t" | ||
668 | ".chip 68k" | ||
669 | : : "a" (temp)); | ||
670 | } | ||
671 | else if (CPU_IS_060) { | ||
672 | unsigned long temp; | ||
673 | __asm__ __volatile__ (".chip 68060\n\t" | ||
674 | "plpar (%0)\n\t" | ||
675 | ".chip 68k" | ||
676 | : "=a" (temp) | ||
677 | : "0" (vaddr)); | ||
678 | __asm__ __volatile__ (".chip 68060\n\t" | ||
679 | "cpushl %%bc,(%0)\n\t" | ||
680 | ".chip 68k" | ||
681 | : : "a" (temp)); | ||
682 | } | ||
683 | else { | ||
684 | /* | ||
685 | * 68030/68020 have no writeback cache; | ||
686 | * still need to clear icache. | ||
687 | * Note that vaddr is guaranteed to be long word aligned. | ||
688 | */ | ||
689 | unsigned long temp; | ||
690 | asm volatile ("movec %%cacr,%0" : "=r" (temp)); | ||
691 | temp += 4; | ||
692 | asm volatile ("movec %0,%%caar\n\t" | ||
693 | "movec %1,%%cacr" | ||
694 | : : "r" (vaddr), "r" (temp)); | ||
695 | asm volatile ("movec %0,%%caar\n\t" | ||
696 | "movec %1,%%cacr" | ||
697 | : : "r" (vaddr + 4), "r" (temp)); | ||
698 | } | ||
699 | } | ||
700 | |||
701 | static inline void __user * | ||
702 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | ||
703 | { | ||
704 | unsigned long usp; | ||
705 | |||
706 | /* Default to using normal stack. */ | ||
707 | usp = rdusp(); | ||
708 | |||
709 | /* This is the X/Open sanctioned signal stack switching. */ | ||
710 | if (ka->sa.sa_flags & SA_ONSTACK) { | ||
711 | if (!sas_ss_flags(usp)) | ||
712 | usp = current->sas_ss_sp + current->sas_ss_size; | ||
713 | } | ||
714 | return (void __user *)((usp - frame_size) & -8UL); | ||
715 | } | ||
716 | |||
717 | static int setup_frame (int sig, struct k_sigaction *ka, | ||
718 | sigset_t *set, struct pt_regs *regs) | ||
719 | { | ||
720 | struct sigframe __user *frame; | ||
721 | int fsize = frame_extra_sizes[regs->format]; | ||
722 | struct sigcontext context; | ||
723 | int err = 0; | ||
724 | |||
725 | if (fsize < 0) { | ||
726 | #ifdef DEBUG | ||
727 | printk ("setup_frame: Unknown frame format %#x\n", | ||
728 | regs->format); | ||
729 | #endif | ||
730 | goto give_sigsegv; | ||
731 | } | ||
732 | |||
733 | frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); | ||
734 | |||
735 | if (fsize) | ||
736 | err |= copy_to_user (frame + 1, regs + 1, fsize); | ||
737 | |||
738 | err |= __put_user((current_thread_info()->exec_domain | ||
739 | && current_thread_info()->exec_domain->signal_invmap | ||
740 | && sig < 32 | ||
741 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
742 | : sig), | ||
743 | &frame->sig); | ||
744 | |||
745 | err |= __put_user(regs->vector, &frame->code); | ||
746 | err |= __put_user(&frame->sc, &frame->psc); | ||
747 | |||
748 | if (_NSIG_WORDS > 1) | ||
749 | err |= copy_to_user(frame->extramask, &set->sig[1], | ||
750 | sizeof(frame->extramask)); | ||
751 | |||
752 | setup_sigcontext(&context, regs, set->sig[0]); | ||
753 | err |= copy_to_user (&frame->sc, &context, sizeof(context)); | ||
754 | |||
755 | /* Set up to return from userspace. */ | ||
756 | err |= __put_user(frame->retcode, &frame->pretcode); | ||
757 | /* moveq #,d0; trap #0 */ | ||
758 | err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), | ||
759 | (long __user *)(frame->retcode)); | ||
760 | |||
761 | if (err) | ||
762 | goto give_sigsegv; | ||
763 | |||
764 | push_cache ((unsigned long) &frame->retcode); | ||
765 | |||
766 | /* | ||
767 | * Set up registers for signal handler. All the state we are about | ||
768 | * to destroy is successfully copied to sigframe. | ||
769 | */ | ||
770 | wrusp ((unsigned long) frame); | ||
771 | regs->pc = (unsigned long) ka->sa.sa_handler; | ||
772 | |||
773 | /* | ||
774 | * This is subtle; if we build more than one sigframe, all but the | ||
775 | * first one will see frame format 0 and have fsize == 0, so we won't | ||
776 | * screw stkadj. | ||
777 | */ | ||
778 | if (fsize) | ||
779 | regs->stkadj = fsize; | ||
780 | |||
781 | /* Prepare to skip over the extra stuff in the exception frame. */ | ||
782 | if (regs->stkadj) { | ||
783 | struct pt_regs *tregs = | ||
784 | (struct pt_regs *)((ulong)regs + regs->stkadj); | ||
785 | #ifdef DEBUG | ||
786 | printk("Performing stackadjust=%04x\n", regs->stkadj); | ||
787 | #endif | ||
788 | /* This must be copied with decreasing addresses to | ||
789 | handle overlaps. */ | ||
790 | tregs->vector = 0; | ||
791 | tregs->format = 0; | ||
792 | tregs->pc = regs->pc; | ||
793 | tregs->sr = regs->sr; | ||
794 | } | ||
795 | return 0; | ||
796 | |||
797 | give_sigsegv: | ||
798 | force_sigsegv(sig, current); | ||
799 | return err; | ||
800 | } | ||
801 | |||
802 | static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, | ||
803 | sigset_t *set, struct pt_regs *regs) | ||
804 | { | ||
805 | struct rt_sigframe __user *frame; | ||
806 | int fsize = frame_extra_sizes[regs->format]; | ||
807 | int err = 0; | ||
808 | |||
809 | if (fsize < 0) { | ||
810 | #ifdef DEBUG | ||
811 | printk ("setup_frame: Unknown frame format %#x\n", | ||
812 | regs->format); | ||
813 | #endif | ||
814 | goto give_sigsegv; | ||
815 | } | ||
816 | |||
817 | frame = get_sigframe(ka, regs, sizeof(*frame)); | ||
818 | |||
819 | if (fsize) | ||
820 | err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); | ||
821 | |||
822 | err |= __put_user((current_thread_info()->exec_domain | ||
823 | && current_thread_info()->exec_domain->signal_invmap | ||
824 | && sig < 32 | ||
825 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
826 | : sig), | ||
827 | &frame->sig); | ||
828 | err |= __put_user(&frame->info, &frame->pinfo); | ||
829 | err |= __put_user(&frame->uc, &frame->puc); | ||
830 | err |= copy_siginfo_to_user(&frame->info, info); | ||
831 | |||
832 | /* Create the ucontext. */ | ||
833 | err |= __put_user(0, &frame->uc.uc_flags); | ||
834 | err |= __put_user(NULL, &frame->uc.uc_link); | ||
835 | err |= __put_user((void __user *)current->sas_ss_sp, | ||
836 | &frame->uc.uc_stack.ss_sp); | ||
837 | err |= __put_user(sas_ss_flags(rdusp()), | ||
838 | &frame->uc.uc_stack.ss_flags); | ||
839 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | ||
840 | err |= rt_setup_ucontext(&frame->uc, regs); | ||
841 | err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); | ||
842 | |||
843 | /* Set up to return from userspace. */ | ||
844 | err |= __put_user(frame->retcode, &frame->pretcode); | ||
845 | #ifdef __mcoldfire__ | ||
846 | /* movel #__NR_rt_sigreturn,d0; trap #0 */ | ||
847 | err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); | ||
848 | err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), | ||
849 | (long __user *)(frame->retcode + 4)); | ||
850 | #else | 3 | #else |
851 | /* moveq #,d0; notb d0; trap #0 */ | 4 | #include "signal_no.c" |
852 | err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), | ||
853 | (long __user *)(frame->retcode + 0)); | ||
854 | err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); | ||
855 | #endif | ||
856 | |||
857 | if (err) | ||
858 | goto give_sigsegv; | ||
859 | |||
860 | push_cache ((unsigned long) &frame->retcode); | ||
861 | |||
862 | /* | ||
863 | * Set up registers for signal handler. All the state we are about | ||
864 | * to destroy is successfully copied to sigframe. | ||
865 | */ | ||
866 | wrusp ((unsigned long) frame); | ||
867 | regs->pc = (unsigned long) ka->sa.sa_handler; | ||
868 | |||
869 | /* | ||
870 | * This is subtle; if we build more than one sigframe, all but the | ||
871 | * first one will see frame format 0 and have fsize == 0, so we won't | ||
872 | * screw stkadj. | ||
873 | */ | ||
874 | if (fsize) | ||
875 | regs->stkadj = fsize; | ||
876 | |||
877 | /* Prepare to skip over the extra stuff in the exception frame. */ | ||
878 | if (regs->stkadj) { | ||
879 | struct pt_regs *tregs = | ||
880 | (struct pt_regs *)((ulong)regs + regs->stkadj); | ||
881 | #ifdef DEBUG | ||
882 | printk("Performing stackadjust=%04x\n", regs->stkadj); | ||
883 | #endif | 5 | #endif |
884 | /* This must be copied with decreasing addresses to | ||
885 | handle overlaps. */ | ||
886 | tregs->vector = 0; | ||
887 | tregs->format = 0; | ||
888 | tregs->pc = regs->pc; | ||
889 | tregs->sr = regs->sr; | ||
890 | } | ||
891 | return 0; | ||
892 | |||
893 | give_sigsegv: | ||
894 | force_sigsegv(sig, current); | ||
895 | return err; | ||
896 | } | ||
897 | |||
898 | static inline void | ||
899 | handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) | ||
900 | { | ||
901 | switch (regs->d0) { | ||
902 | case -ERESTARTNOHAND: | ||
903 | if (!has_handler) | ||
904 | goto do_restart; | ||
905 | regs->d0 = -EINTR; | ||
906 | break; | ||
907 | |||
908 | case -ERESTART_RESTARTBLOCK: | ||
909 | if (!has_handler) { | ||
910 | regs->d0 = __NR_restart_syscall; | ||
911 | regs->pc -= 2; | ||
912 | break; | ||
913 | } | ||
914 | regs->d0 = -EINTR; | ||
915 | break; | ||
916 | |||
917 | case -ERESTARTSYS: | ||
918 | if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { | ||
919 | regs->d0 = -EINTR; | ||
920 | break; | ||
921 | } | ||
922 | /* fallthrough */ | ||
923 | case -ERESTARTNOINTR: | ||
924 | do_restart: | ||
925 | regs->d0 = regs->orig_d0; | ||
926 | regs->pc -= 2; | ||
927 | break; | ||
928 | } | ||
929 | } | ||
930 | |||
931 | void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) | ||
932 | { | ||
933 | if (regs->orig_d0 < 0) | ||
934 | return; | ||
935 | switch (regs->d0) { | ||
936 | case -ERESTARTNOHAND: | ||
937 | case -ERESTARTSYS: | ||
938 | case -ERESTARTNOINTR: | ||
939 | regs->d0 = regs->orig_d0; | ||
940 | regs->orig_d0 = -1; | ||
941 | regs->pc -= 2; | ||
942 | break; | ||
943 | } | ||
944 | } | ||
945 | |||
946 | /* | ||
947 | * OK, we're invoking a handler | ||
948 | */ | ||
949 | static void | ||
950 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | ||
951 | sigset_t *oldset, struct pt_regs *regs) | ||
952 | { | ||
953 | int err; | ||
954 | /* are we from a system call? */ | ||
955 | if (regs->orig_d0 >= 0) | ||
956 | /* If so, check system call restarting.. */ | ||
957 | handle_restart(regs, ka, 1); | ||
958 | |||
959 | /* set up the stack frame */ | ||
960 | if (ka->sa.sa_flags & SA_SIGINFO) | ||
961 | err = setup_rt_frame(sig, ka, info, oldset, regs); | ||
962 | else | ||
963 | err = setup_frame(sig, ka, oldset, regs); | ||
964 | |||
965 | if (err) | ||
966 | return; | ||
967 | |||
968 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
969 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
970 | sigaddset(¤t->blocked,sig); | ||
971 | recalc_sigpending(); | ||
972 | |||
973 | if (test_thread_flag(TIF_DELAYED_TRACE)) { | ||
974 | regs->sr &= ~0x8000; | ||
975 | send_sig(SIGTRAP, current, 1); | ||
976 | } | ||
977 | |||
978 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
979 | } | ||
980 | |||
981 | /* | ||
982 | * Note that 'init' is a special process: it doesn't get signals it doesn't | ||
983 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | ||
984 | * mistake. | ||
985 | */ | ||
986 | asmlinkage void do_signal(struct pt_regs *regs) | ||
987 | { | ||
988 | siginfo_t info; | ||
989 | struct k_sigaction ka; | ||
990 | int signr; | ||
991 | sigset_t *oldset; | ||
992 | |||
993 | current->thread.esp0 = (unsigned long) regs; | ||
994 | |||
995 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
996 | oldset = ¤t->saved_sigmask; | ||
997 | else | ||
998 | oldset = ¤t->blocked; | ||
999 | |||
1000 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | ||
1001 | if (signr > 0) { | ||
1002 | /* Whee! Actually deliver the signal. */ | ||
1003 | handle_signal(signr, &ka, &info, oldset, regs); | ||
1004 | return; | ||
1005 | } | ||
1006 | |||
1007 | /* Did we come from a system call? */ | ||
1008 | if (regs->orig_d0 >= 0) | ||
1009 | /* Restart the system call - no handlers present */ | ||
1010 | handle_restart(regs, NULL, 0); | ||
1011 | |||
1012 | /* If there's no signal to deliver, we just restore the saved mask. */ | ||
1013 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
1014 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
1015 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
1016 | } | ||
1017 | } | ||
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c new file mode 100644 index 000000000000..a0afc239304e --- /dev/null +++ b/arch/m68k/kernel/signal_mm.c | |||
@@ -0,0 +1,1017 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/kernel/signal.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
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 | |||
11 | /* | ||
12 | * Linux/m68k support by Hamish Macdonald | ||
13 | * | ||
14 | * 68060 fixes by Jesper Skov | ||
15 | * | ||
16 | * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab | ||
17 | * | ||
18 | * mathemu support by Roman Zippel | ||
19 | * (Note: fpstate in the signal context is completely ignored for the emulator | ||
20 | * and the internal floating point format is put on stack) | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * ++roman (07/09/96): implemented signal stacks (specially for tosemu on | ||
25 | * Atari :-) Current limitation: Only one sigstack can be active at one time. | ||
26 | * If a second signal with SA_ONSTACK set arrives while working on a sigstack, | ||
27 | * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested | ||
28 | * signal handlers! | ||
29 | */ | ||
30 | |||
31 | #include <linux/sched.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/signal.h> | ||
35 | #include <linux/syscalls.h> | ||
36 | #include <linux/errno.h> | ||
37 | #include <linux/wait.h> | ||
38 | #include <linux/ptrace.h> | ||
39 | #include <linux/unistd.h> | ||
40 | #include <linux/stddef.h> | ||
41 | #include <linux/highuid.h> | ||
42 | #include <linux/personality.h> | ||
43 | #include <linux/tty.h> | ||
44 | #include <linux/binfmts.h> | ||
45 | #include <linux/module.h> | ||
46 | |||
47 | #include <asm/setup.h> | ||
48 | #include <asm/uaccess.h> | ||
49 | #include <asm/pgtable.h> | ||
50 | #include <asm/traps.h> | ||
51 | #include <asm/ucontext.h> | ||
52 | |||
53 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
54 | |||
55 | static const int frame_extra_sizes[16] = { | ||
56 | [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ | ||
57 | [2] = sizeof(((struct frame *)0)->un.fmt2), | ||
58 | [3] = sizeof(((struct frame *)0)->un.fmt3), | ||
59 | [4] = sizeof(((struct frame *)0)->un.fmt4), | ||
60 | [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ | ||
61 | [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ | ||
62 | [7] = sizeof(((struct frame *)0)->un.fmt7), | ||
63 | [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */ | ||
64 | [9] = sizeof(((struct frame *)0)->un.fmt9), | ||
65 | [10] = sizeof(((struct frame *)0)->un.fmta), | ||
66 | [11] = sizeof(((struct frame *)0)->un.fmtb), | ||
67 | [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */ | ||
68 | [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */ | ||
69 | [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */ | ||
70 | [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ | ||
71 | }; | ||
72 | |||
73 | int handle_kernel_fault(struct pt_regs *regs) | ||
74 | { | ||
75 | const struct exception_table_entry *fixup; | ||
76 | struct pt_regs *tregs; | ||
77 | |||
78 | /* Are we prepared to handle this kernel fault? */ | ||
79 | fixup = search_exception_tables(regs->pc); | ||
80 | if (!fixup) | ||
81 | return 0; | ||
82 | |||
83 | /* Create a new four word stack frame, discarding the old one. */ | ||
84 | regs->stkadj = frame_extra_sizes[regs->format]; | ||
85 | tregs = (struct pt_regs *)((long)regs + regs->stkadj); | ||
86 | tregs->vector = regs->vector; | ||
87 | tregs->format = 0; | ||
88 | tregs->pc = fixup->fixup; | ||
89 | tregs->sr = regs->sr; | ||
90 | |||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Atomically swap in the new signal mask, and wait for a signal. | ||
96 | */ | ||
97 | asmlinkage int | ||
98 | sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) | ||
99 | { | ||
100 | mask &= _BLOCKABLE; | ||
101 | spin_lock_irq(¤t->sighand->siglock); | ||
102 | current->saved_sigmask = current->blocked; | ||
103 | siginitset(¤t->blocked, mask); | ||
104 | recalc_sigpending(); | ||
105 | spin_unlock_irq(¤t->sighand->siglock); | ||
106 | |||
107 | current->state = TASK_INTERRUPTIBLE; | ||
108 | schedule(); | ||
109 | set_restore_sigmask(); | ||
110 | |||
111 | return -ERESTARTNOHAND; | ||
112 | } | ||
113 | |||
114 | asmlinkage int | ||
115 | sys_sigaction(int sig, const struct old_sigaction __user *act, | ||
116 | struct old_sigaction __user *oact) | ||
117 | { | ||
118 | struct k_sigaction new_ka, old_ka; | ||
119 | int ret; | ||
120 | |||
121 | if (act) { | ||
122 | old_sigset_t mask; | ||
123 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
124 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
125 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || | ||
126 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
127 | __get_user(mask, &act->sa_mask)) | ||
128 | return -EFAULT; | ||
129 | siginitset(&new_ka.sa.sa_mask, mask); | ||
130 | } | ||
131 | |||
132 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
133 | |||
134 | if (!ret && oact) { | ||
135 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
136 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
137 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || | ||
138 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
139 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
140 | return -EFAULT; | ||
141 | } | ||
142 | |||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | asmlinkage int | ||
147 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) | ||
148 | { | ||
149 | return do_sigaltstack(uss, uoss, rdusp()); | ||
150 | } | ||
151 | |||
152 | |||
153 | /* | ||
154 | * Do a signal return; undo the signal stack. | ||
155 | * | ||
156 | * Keep the return code on the stack quadword aligned! | ||
157 | * That makes the cache flush below easier. | ||
158 | */ | ||
159 | |||
160 | struct sigframe | ||
161 | { | ||
162 | char __user *pretcode; | ||
163 | int sig; | ||
164 | int code; | ||
165 | struct sigcontext __user *psc; | ||
166 | char retcode[8]; | ||
167 | unsigned long extramask[_NSIG_WORDS-1]; | ||
168 | struct sigcontext sc; | ||
169 | }; | ||
170 | |||
171 | struct rt_sigframe | ||
172 | { | ||
173 | char __user *pretcode; | ||
174 | int sig; | ||
175 | struct siginfo __user *pinfo; | ||
176 | void __user *puc; | ||
177 | char retcode[8]; | ||
178 | struct siginfo info; | ||
179 | struct ucontext uc; | ||
180 | }; | ||
181 | |||
182 | |||
183 | static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ | ||
184 | |||
185 | static inline int restore_fpu_state(struct sigcontext *sc) | ||
186 | { | ||
187 | int err = 1; | ||
188 | |||
189 | if (FPU_IS_EMU) { | ||
190 | /* restore registers */ | ||
191 | memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); | ||
192 | memcpy(current->thread.fp, sc->sc_fpregs, 24); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { | ||
197 | /* Verify the frame format. */ | ||
198 | if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) | ||
199 | goto out; | ||
200 | if (CPU_IS_020_OR_030) { | ||
201 | if (m68k_fputype & FPU_68881 && | ||
202 | !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4)) | ||
203 | goto out; | ||
204 | if (m68k_fputype & FPU_68882 && | ||
205 | !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4)) | ||
206 | goto out; | ||
207 | } else if (CPU_IS_040) { | ||
208 | if (!(sc->sc_fpstate[1] == 0x00 || | ||
209 | sc->sc_fpstate[1] == 0x28 || | ||
210 | sc->sc_fpstate[1] == 0x60)) | ||
211 | goto out; | ||
212 | } else if (CPU_IS_060) { | ||
213 | if (!(sc->sc_fpstate[3] == 0x00 || | ||
214 | sc->sc_fpstate[3] == 0x60 || | ||
215 | sc->sc_fpstate[3] == 0xe0)) | ||
216 | goto out; | ||
217 | } else | ||
218 | goto out; | ||
219 | |||
220 | __asm__ volatile (".chip 68k/68881\n\t" | ||
221 | "fmovemx %0,%%fp0-%%fp1\n\t" | ||
222 | "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" | ||
223 | ".chip 68k" | ||
224 | : /* no outputs */ | ||
225 | : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); | ||
226 | } | ||
227 | __asm__ volatile (".chip 68k/68881\n\t" | ||
228 | "frestore %0\n\t" | ||
229 | ".chip 68k" : : "m" (*sc->sc_fpstate)); | ||
230 | err = 0; | ||
231 | |||
232 | out: | ||
233 | return err; | ||
234 | } | ||
235 | |||
236 | #define FPCONTEXT_SIZE 216 | ||
237 | #define uc_fpstate uc_filler[0] | ||
238 | #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] | ||
239 | #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] | ||
240 | |||
241 | static inline int rt_restore_fpu_state(struct ucontext __user *uc) | ||
242 | { | ||
243 | unsigned char fpstate[FPCONTEXT_SIZE]; | ||
244 | int context_size = CPU_IS_060 ? 8 : 0; | ||
245 | fpregset_t fpregs; | ||
246 | int err = 1; | ||
247 | |||
248 | if (FPU_IS_EMU) { | ||
249 | /* restore fpu control register */ | ||
250 | if (__copy_from_user(current->thread.fpcntl, | ||
251 | uc->uc_mcontext.fpregs.f_fpcntl, 12)) | ||
252 | goto out; | ||
253 | /* restore all other fpu register */ | ||
254 | if (__copy_from_user(current->thread.fp, | ||
255 | uc->uc_mcontext.fpregs.f_fpregs, 96)) | ||
256 | goto out; | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) | ||
261 | goto out; | ||
262 | if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { | ||
263 | if (!CPU_IS_060) | ||
264 | context_size = fpstate[1]; | ||
265 | /* Verify the frame format. */ | ||
266 | if (!CPU_IS_060 && (fpstate[0] != fpu_version)) | ||
267 | goto out; | ||
268 | if (CPU_IS_020_OR_030) { | ||
269 | if (m68k_fputype & FPU_68881 && | ||
270 | !(context_size == 0x18 || context_size == 0xb4)) | ||
271 | goto out; | ||
272 | if (m68k_fputype & FPU_68882 && | ||
273 | !(context_size == 0x38 || context_size == 0xd4)) | ||
274 | goto out; | ||
275 | } else if (CPU_IS_040) { | ||
276 | if (!(context_size == 0x00 || | ||
277 | context_size == 0x28 || | ||
278 | context_size == 0x60)) | ||
279 | goto out; | ||
280 | } else if (CPU_IS_060) { | ||
281 | if (!(fpstate[3] == 0x00 || | ||
282 | fpstate[3] == 0x60 || | ||
283 | fpstate[3] == 0xe0)) | ||
284 | goto out; | ||
285 | } else | ||
286 | goto out; | ||
287 | if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, | ||
288 | sizeof(fpregs))) | ||
289 | goto out; | ||
290 | __asm__ volatile (".chip 68k/68881\n\t" | ||
291 | "fmovemx %0,%%fp0-%%fp7\n\t" | ||
292 | "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" | ||
293 | ".chip 68k" | ||
294 | : /* no outputs */ | ||
295 | : "m" (*fpregs.f_fpregs), | ||
296 | "m" (*fpregs.f_fpcntl)); | ||
297 | } | ||
298 | if (context_size && | ||
299 | __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, | ||
300 | context_size)) | ||
301 | goto out; | ||
302 | __asm__ volatile (".chip 68k/68881\n\t" | ||
303 | "frestore %0\n\t" | ||
304 | ".chip 68k" : : "m" (*fpstate)); | ||
305 | err = 0; | ||
306 | |||
307 | out: | ||
308 | return err; | ||
309 | } | ||
310 | |||
311 | static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, | ||
312 | void __user *fp) | ||
313 | { | ||
314 | int fsize = frame_extra_sizes[formatvec >> 12]; | ||
315 | if (fsize < 0) { | ||
316 | /* | ||
317 | * user process trying to return with weird frame format | ||
318 | */ | ||
319 | #ifdef DEBUG | ||
320 | printk("user process returning with weird frame format\n"); | ||
321 | #endif | ||
322 | return 1; | ||
323 | } | ||
324 | if (!fsize) { | ||
325 | regs->format = formatvec >> 12; | ||
326 | regs->vector = formatvec & 0xfff; | ||
327 | } else { | ||
328 | struct switch_stack *sw = (struct switch_stack *)regs - 1; | ||
329 | unsigned long buf[fsize / 2]; /* yes, twice as much */ | ||
330 | |||
331 | /* that'll make sure that expansion won't crap over data */ | ||
332 | if (copy_from_user(buf + fsize / 4, fp, fsize)) | ||
333 | return 1; | ||
334 | |||
335 | /* point of no return */ | ||
336 | regs->format = formatvec >> 12; | ||
337 | regs->vector = formatvec & 0xfff; | ||
338 | #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) | ||
339 | __asm__ __volatile__ | ||
340 | (" movel %0,%/a0\n\t" | ||
341 | " subl %1,%/a0\n\t" /* make room on stack */ | ||
342 | " movel %/a0,%/sp\n\t" /* set stack pointer */ | ||
343 | /* move switch_stack and pt_regs */ | ||
344 | "1: movel %0@+,%/a0@+\n\t" | ||
345 | " dbra %2,1b\n\t" | ||
346 | " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ | ||
347 | " lsrl #2,%1\n\t" | ||
348 | " subql #1,%1\n\t" | ||
349 | /* copy to the gap we'd made */ | ||
350 | "2: movel %4@+,%/a0@+\n\t" | ||
351 | " dbra %1,2b\n\t" | ||
352 | " bral ret_from_signal\n" | ||
353 | : /* no outputs, it doesn't ever return */ | ||
354 | : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), | ||
355 | "n" (frame_offset), "a" (buf + fsize/4) | ||
356 | : "a0"); | ||
357 | #undef frame_offset | ||
358 | } | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static inline int | ||
363 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp) | ||
364 | { | ||
365 | int formatvec; | ||
366 | struct sigcontext context; | ||
367 | int err; | ||
368 | |||
369 | /* Always make any pending restarted system calls return -EINTR */ | ||
370 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
371 | |||
372 | /* get previous context */ | ||
373 | if (copy_from_user(&context, usc, sizeof(context))) | ||
374 | goto badframe; | ||
375 | |||
376 | /* restore passed registers */ | ||
377 | regs->d0 = context.sc_d0; | ||
378 | regs->d1 = context.sc_d1; | ||
379 | regs->a0 = context.sc_a0; | ||
380 | regs->a1 = context.sc_a1; | ||
381 | regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); | ||
382 | regs->pc = context.sc_pc; | ||
383 | regs->orig_d0 = -1; /* disable syscall checks */ | ||
384 | wrusp(context.sc_usp); | ||
385 | formatvec = context.sc_formatvec; | ||
386 | |||
387 | err = restore_fpu_state(&context); | ||
388 | |||
389 | if (err || mangle_kernel_stack(regs, formatvec, fp)) | ||
390 | goto badframe; | ||
391 | |||
392 | return 0; | ||
393 | |||
394 | badframe: | ||
395 | return 1; | ||
396 | } | ||
397 | |||
398 | static inline int | ||
399 | rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, | ||
400 | struct ucontext __user *uc) | ||
401 | { | ||
402 | int temp; | ||
403 | greg_t __user *gregs = uc->uc_mcontext.gregs; | ||
404 | unsigned long usp; | ||
405 | int err; | ||
406 | |||
407 | /* Always make any pending restarted system calls return -EINTR */ | ||
408 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
409 | |||
410 | err = __get_user(temp, &uc->uc_mcontext.version); | ||
411 | if (temp != MCONTEXT_VERSION) | ||
412 | goto badframe; | ||
413 | /* restore passed registers */ | ||
414 | err |= __get_user(regs->d0, &gregs[0]); | ||
415 | err |= __get_user(regs->d1, &gregs[1]); | ||
416 | err |= __get_user(regs->d2, &gregs[2]); | ||
417 | err |= __get_user(regs->d3, &gregs[3]); | ||
418 | err |= __get_user(regs->d4, &gregs[4]); | ||
419 | err |= __get_user(regs->d5, &gregs[5]); | ||
420 | err |= __get_user(sw->d6, &gregs[6]); | ||
421 | err |= __get_user(sw->d7, &gregs[7]); | ||
422 | err |= __get_user(regs->a0, &gregs[8]); | ||
423 | err |= __get_user(regs->a1, &gregs[9]); | ||
424 | err |= __get_user(regs->a2, &gregs[10]); | ||
425 | err |= __get_user(sw->a3, &gregs[11]); | ||
426 | err |= __get_user(sw->a4, &gregs[12]); | ||
427 | err |= __get_user(sw->a5, &gregs[13]); | ||
428 | err |= __get_user(sw->a6, &gregs[14]); | ||
429 | err |= __get_user(usp, &gregs[15]); | ||
430 | wrusp(usp); | ||
431 | err |= __get_user(regs->pc, &gregs[16]); | ||
432 | err |= __get_user(temp, &gregs[17]); | ||
433 | regs->sr = (regs->sr & 0xff00) | (temp & 0xff); | ||
434 | regs->orig_d0 = -1; /* disable syscall checks */ | ||
435 | err |= __get_user(temp, &uc->uc_formatvec); | ||
436 | |||
437 | err |= rt_restore_fpu_state(uc); | ||
438 | |||
439 | if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) | ||
440 | goto badframe; | ||
441 | |||
442 | if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) | ||
443 | goto badframe; | ||
444 | |||
445 | return 0; | ||
446 | |||
447 | badframe: | ||
448 | return 1; | ||
449 | } | ||
450 | |||
451 | asmlinkage int do_sigreturn(unsigned long __unused) | ||
452 | { | ||
453 | struct switch_stack *sw = (struct switch_stack *) &__unused; | ||
454 | struct pt_regs *regs = (struct pt_regs *) (sw + 1); | ||
455 | unsigned long usp = rdusp(); | ||
456 | struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); | ||
457 | sigset_t set; | ||
458 | |||
459 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
460 | goto badframe; | ||
461 | if (__get_user(set.sig[0], &frame->sc.sc_mask) || | ||
462 | (_NSIG_WORDS > 1 && | ||
463 | __copy_from_user(&set.sig[1], &frame->extramask, | ||
464 | sizeof(frame->extramask)))) | ||
465 | goto badframe; | ||
466 | |||
467 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
468 | current->blocked = set; | ||
469 | recalc_sigpending(); | ||
470 | |||
471 | if (restore_sigcontext(regs, &frame->sc, frame + 1)) | ||
472 | goto badframe; | ||
473 | return regs->d0; | ||
474 | |||
475 | badframe: | ||
476 | force_sig(SIGSEGV, current); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | asmlinkage int do_rt_sigreturn(unsigned long __unused) | ||
481 | { | ||
482 | struct switch_stack *sw = (struct switch_stack *) &__unused; | ||
483 | struct pt_regs *regs = (struct pt_regs *) (sw + 1); | ||
484 | unsigned long usp = rdusp(); | ||
485 | struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); | ||
486 | sigset_t set; | ||
487 | |||
488 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
489 | goto badframe; | ||
490 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | ||
491 | goto badframe; | ||
492 | |||
493 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
494 | current->blocked = set; | ||
495 | recalc_sigpending(); | ||
496 | |||
497 | if (rt_restore_ucontext(regs, sw, &frame->uc)) | ||
498 | goto badframe; | ||
499 | return regs->d0; | ||
500 | |||
501 | badframe: | ||
502 | force_sig(SIGSEGV, current); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * Set up a signal frame. | ||
508 | */ | ||
509 | |||
510 | static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) | ||
511 | { | ||
512 | if (FPU_IS_EMU) { | ||
513 | /* save registers */ | ||
514 | memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); | ||
515 | memcpy(sc->sc_fpregs, current->thread.fp, 24); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | __asm__ volatile (".chip 68k/68881\n\t" | ||
520 | "fsave %0\n\t" | ||
521 | ".chip 68k" | ||
522 | : : "m" (*sc->sc_fpstate) : "memory"); | ||
523 | |||
524 | if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { | ||
525 | fpu_version = sc->sc_fpstate[0]; | ||
526 | if (CPU_IS_020_OR_030 && | ||
527 | regs->vector >= (VEC_FPBRUC * 4) && | ||
528 | regs->vector <= (VEC_FPNAN * 4)) { | ||
529 | /* Clear pending exception in 68882 idle frame */ | ||
530 | if (*(unsigned short *) sc->sc_fpstate == 0x1f38) | ||
531 | sc->sc_fpstate[0x38] |= 1 << 3; | ||
532 | } | ||
533 | __asm__ volatile (".chip 68k/68881\n\t" | ||
534 | "fmovemx %%fp0-%%fp1,%0\n\t" | ||
535 | "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" | ||
536 | ".chip 68k" | ||
537 | : "=m" (*sc->sc_fpregs), | ||
538 | "=m" (*sc->sc_fpcntl) | ||
539 | : /* no inputs */ | ||
540 | : "memory"); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) | ||
545 | { | ||
546 | unsigned char fpstate[FPCONTEXT_SIZE]; | ||
547 | int context_size = CPU_IS_060 ? 8 : 0; | ||
548 | int err = 0; | ||
549 | |||
550 | if (FPU_IS_EMU) { | ||
551 | /* save fpu control register */ | ||
552 | err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, | ||
553 | current->thread.fpcntl, 12); | ||
554 | /* save all other fpu register */ | ||
555 | err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, | ||
556 | current->thread.fp, 96); | ||
557 | return err; | ||
558 | } | ||
559 | |||
560 | __asm__ volatile (".chip 68k/68881\n\t" | ||
561 | "fsave %0\n\t" | ||
562 | ".chip 68k" | ||
563 | : : "m" (*fpstate) : "memory"); | ||
564 | |||
565 | err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); | ||
566 | if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { | ||
567 | fpregset_t fpregs; | ||
568 | if (!CPU_IS_060) | ||
569 | context_size = fpstate[1]; | ||
570 | fpu_version = fpstate[0]; | ||
571 | if (CPU_IS_020_OR_030 && | ||
572 | regs->vector >= (VEC_FPBRUC * 4) && | ||
573 | regs->vector <= (VEC_FPNAN * 4)) { | ||
574 | /* Clear pending exception in 68882 idle frame */ | ||
575 | if (*(unsigned short *) fpstate == 0x1f38) | ||
576 | fpstate[0x38] |= 1 << 3; | ||
577 | } | ||
578 | __asm__ volatile (".chip 68k/68881\n\t" | ||
579 | "fmovemx %%fp0-%%fp7,%0\n\t" | ||
580 | "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" | ||
581 | ".chip 68k" | ||
582 | : "=m" (*fpregs.f_fpregs), | ||
583 | "=m" (*fpregs.f_fpcntl) | ||
584 | : /* no inputs */ | ||
585 | : "memory"); | ||
586 | err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, | ||
587 | sizeof(fpregs)); | ||
588 | } | ||
589 | if (context_size) | ||
590 | err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, | ||
591 | context_size); | ||
592 | return err; | ||
593 | } | ||
594 | |||
595 | static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, | ||
596 | unsigned long mask) | ||
597 | { | ||
598 | sc->sc_mask = mask; | ||
599 | sc->sc_usp = rdusp(); | ||
600 | sc->sc_d0 = regs->d0; | ||
601 | sc->sc_d1 = regs->d1; | ||
602 | sc->sc_a0 = regs->a0; | ||
603 | sc->sc_a1 = regs->a1; | ||
604 | sc->sc_sr = regs->sr; | ||
605 | sc->sc_pc = regs->pc; | ||
606 | sc->sc_formatvec = regs->format << 12 | regs->vector; | ||
607 | save_fpu_state(sc, regs); | ||
608 | } | ||
609 | |||
610 | static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) | ||
611 | { | ||
612 | struct switch_stack *sw = (struct switch_stack *)regs - 1; | ||
613 | greg_t __user *gregs = uc->uc_mcontext.gregs; | ||
614 | int err = 0; | ||
615 | |||
616 | err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); | ||
617 | err |= __put_user(regs->d0, &gregs[0]); | ||
618 | err |= __put_user(regs->d1, &gregs[1]); | ||
619 | err |= __put_user(regs->d2, &gregs[2]); | ||
620 | err |= __put_user(regs->d3, &gregs[3]); | ||
621 | err |= __put_user(regs->d4, &gregs[4]); | ||
622 | err |= __put_user(regs->d5, &gregs[5]); | ||
623 | err |= __put_user(sw->d6, &gregs[6]); | ||
624 | err |= __put_user(sw->d7, &gregs[7]); | ||
625 | err |= __put_user(regs->a0, &gregs[8]); | ||
626 | err |= __put_user(regs->a1, &gregs[9]); | ||
627 | err |= __put_user(regs->a2, &gregs[10]); | ||
628 | err |= __put_user(sw->a3, &gregs[11]); | ||
629 | err |= __put_user(sw->a4, &gregs[12]); | ||
630 | err |= __put_user(sw->a5, &gregs[13]); | ||
631 | err |= __put_user(sw->a6, &gregs[14]); | ||
632 | err |= __put_user(rdusp(), &gregs[15]); | ||
633 | err |= __put_user(regs->pc, &gregs[16]); | ||
634 | err |= __put_user(regs->sr, &gregs[17]); | ||
635 | err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); | ||
636 | err |= rt_save_fpu_state(uc, regs); | ||
637 | return err; | ||
638 | } | ||
639 | |||
640 | static inline void push_cache (unsigned long vaddr) | ||
641 | { | ||
642 | /* | ||
643 | * Using the old cache_push_v() was really a big waste. | ||
644 | * | ||
645 | * What we are trying to do is to flush 8 bytes to ram. | ||
646 | * Flushing 2 cache lines of 16 bytes is much cheaper than | ||
647 | * flushing 1 or 2 pages, as previously done in | ||
648 | * cache_push_v(). | ||
649 | * Jes | ||
650 | */ | ||
651 | if (CPU_IS_040) { | ||
652 | unsigned long temp; | ||
653 | |||
654 | __asm__ __volatile__ (".chip 68040\n\t" | ||
655 | "nop\n\t" | ||
656 | "ptestr (%1)\n\t" | ||
657 | "movec %%mmusr,%0\n\t" | ||
658 | ".chip 68k" | ||
659 | : "=r" (temp) | ||
660 | : "a" (vaddr)); | ||
661 | |||
662 | temp &= PAGE_MASK; | ||
663 | temp |= vaddr & ~PAGE_MASK; | ||
664 | |||
665 | __asm__ __volatile__ (".chip 68040\n\t" | ||
666 | "nop\n\t" | ||
667 | "cpushl %%bc,(%0)\n\t" | ||
668 | ".chip 68k" | ||
669 | : : "a" (temp)); | ||
670 | } | ||
671 | else if (CPU_IS_060) { | ||
672 | unsigned long temp; | ||
673 | __asm__ __volatile__ (".chip 68060\n\t" | ||
674 | "plpar (%0)\n\t" | ||
675 | ".chip 68k" | ||
676 | : "=a" (temp) | ||
677 | : "0" (vaddr)); | ||
678 | __asm__ __volatile__ (".chip 68060\n\t" | ||
679 | "cpushl %%bc,(%0)\n\t" | ||
680 | ".chip 68k" | ||
681 | : : "a" (temp)); | ||
682 | } | ||
683 | else { | ||
684 | /* | ||
685 | * 68030/68020 have no writeback cache; | ||
686 | * still need to clear icache. | ||
687 | * Note that vaddr is guaranteed to be long word aligned. | ||
688 | */ | ||
689 | unsigned long temp; | ||
690 | asm volatile ("movec %%cacr,%0" : "=r" (temp)); | ||
691 | temp += 4; | ||
692 | asm volatile ("movec %0,%%caar\n\t" | ||
693 | "movec %1,%%cacr" | ||
694 | : : "r" (vaddr), "r" (temp)); | ||
695 | asm volatile ("movec %0,%%caar\n\t" | ||
696 | "movec %1,%%cacr" | ||
697 | : : "r" (vaddr + 4), "r" (temp)); | ||
698 | } | ||
699 | } | ||
700 | |||
701 | static inline void __user * | ||
702 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | ||
703 | { | ||
704 | unsigned long usp; | ||
705 | |||
706 | /* Default to using normal stack. */ | ||
707 | usp = rdusp(); | ||
708 | |||
709 | /* This is the X/Open sanctioned signal stack switching. */ | ||
710 | if (ka->sa.sa_flags & SA_ONSTACK) { | ||
711 | if (!sas_ss_flags(usp)) | ||
712 | usp = current->sas_ss_sp + current->sas_ss_size; | ||
713 | } | ||
714 | return (void __user *)((usp - frame_size) & -8UL); | ||
715 | } | ||
716 | |||
717 | static int setup_frame (int sig, struct k_sigaction *ka, | ||
718 | sigset_t *set, struct pt_regs *regs) | ||
719 | { | ||
720 | struct sigframe __user *frame; | ||
721 | int fsize = frame_extra_sizes[regs->format]; | ||
722 | struct sigcontext context; | ||
723 | int err = 0; | ||
724 | |||
725 | if (fsize < 0) { | ||
726 | #ifdef DEBUG | ||
727 | printk ("setup_frame: Unknown frame format %#x\n", | ||
728 | regs->format); | ||
729 | #endif | ||
730 | goto give_sigsegv; | ||
731 | } | ||
732 | |||
733 | frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); | ||
734 | |||
735 | if (fsize) | ||
736 | err |= copy_to_user (frame + 1, regs + 1, fsize); | ||
737 | |||
738 | err |= __put_user((current_thread_info()->exec_domain | ||
739 | && current_thread_info()->exec_domain->signal_invmap | ||
740 | && sig < 32 | ||
741 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
742 | : sig), | ||
743 | &frame->sig); | ||
744 | |||
745 | err |= __put_user(regs->vector, &frame->code); | ||
746 | err |= __put_user(&frame->sc, &frame->psc); | ||
747 | |||
748 | if (_NSIG_WORDS > 1) | ||
749 | err |= copy_to_user(frame->extramask, &set->sig[1], | ||
750 | sizeof(frame->extramask)); | ||
751 | |||
752 | setup_sigcontext(&context, regs, set->sig[0]); | ||
753 | err |= copy_to_user (&frame->sc, &context, sizeof(context)); | ||
754 | |||
755 | /* Set up to return from userspace. */ | ||
756 | err |= __put_user(frame->retcode, &frame->pretcode); | ||
757 | /* moveq #,d0; trap #0 */ | ||
758 | err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), | ||
759 | (long __user *)(frame->retcode)); | ||
760 | |||
761 | if (err) | ||
762 | goto give_sigsegv; | ||
763 | |||
764 | push_cache ((unsigned long) &frame->retcode); | ||
765 | |||
766 | /* | ||
767 | * Set up registers for signal handler. All the state we are about | ||
768 | * to destroy is successfully copied to sigframe. | ||
769 | */ | ||
770 | wrusp ((unsigned long) frame); | ||
771 | regs->pc = (unsigned long) ka->sa.sa_handler; | ||
772 | |||
773 | /* | ||
774 | * This is subtle; if we build more than one sigframe, all but the | ||
775 | * first one will see frame format 0 and have fsize == 0, so we won't | ||
776 | * screw stkadj. | ||
777 | */ | ||
778 | if (fsize) | ||
779 | regs->stkadj = fsize; | ||
780 | |||
781 | /* Prepare to skip over the extra stuff in the exception frame. */ | ||
782 | if (regs->stkadj) { | ||
783 | struct pt_regs *tregs = | ||
784 | (struct pt_regs *)((ulong)regs + regs->stkadj); | ||
785 | #ifdef DEBUG | ||
786 | printk("Performing stackadjust=%04x\n", regs->stkadj); | ||
787 | #endif | ||
788 | /* This must be copied with decreasing addresses to | ||
789 | handle overlaps. */ | ||
790 | tregs->vector = 0; | ||
791 | tregs->format = 0; | ||
792 | tregs->pc = regs->pc; | ||
793 | tregs->sr = regs->sr; | ||
794 | } | ||
795 | return 0; | ||
796 | |||
797 | give_sigsegv: | ||
798 | force_sigsegv(sig, current); | ||
799 | return err; | ||
800 | } | ||
801 | |||
802 | static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, | ||
803 | sigset_t *set, struct pt_regs *regs) | ||
804 | { | ||
805 | struct rt_sigframe __user *frame; | ||
806 | int fsize = frame_extra_sizes[regs->format]; | ||
807 | int err = 0; | ||
808 | |||
809 | if (fsize < 0) { | ||
810 | #ifdef DEBUG | ||
811 | printk ("setup_frame: Unknown frame format %#x\n", | ||
812 | regs->format); | ||
813 | #endif | ||
814 | goto give_sigsegv; | ||
815 | } | ||
816 | |||
817 | frame = get_sigframe(ka, regs, sizeof(*frame)); | ||
818 | |||
819 | if (fsize) | ||
820 | err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); | ||
821 | |||
822 | err |= __put_user((current_thread_info()->exec_domain | ||
823 | && current_thread_info()->exec_domain->signal_invmap | ||
824 | && sig < 32 | ||
825 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
826 | : sig), | ||
827 | &frame->sig); | ||
828 | err |= __put_user(&frame->info, &frame->pinfo); | ||
829 | err |= __put_user(&frame->uc, &frame->puc); | ||
830 | err |= copy_siginfo_to_user(&frame->info, info); | ||
831 | |||
832 | /* Create the ucontext. */ | ||
833 | err |= __put_user(0, &frame->uc.uc_flags); | ||
834 | err |= __put_user(NULL, &frame->uc.uc_link); | ||
835 | err |= __put_user((void __user *)current->sas_ss_sp, | ||
836 | &frame->uc.uc_stack.ss_sp); | ||
837 | err |= __put_user(sas_ss_flags(rdusp()), | ||
838 | &frame->uc.uc_stack.ss_flags); | ||
839 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | ||
840 | err |= rt_setup_ucontext(&frame->uc, regs); | ||
841 | err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); | ||
842 | |||
843 | /* Set up to return from userspace. */ | ||
844 | err |= __put_user(frame->retcode, &frame->pretcode); | ||
845 | #ifdef __mcoldfire__ | ||
846 | /* movel #__NR_rt_sigreturn,d0; trap #0 */ | ||
847 | err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); | ||
848 | err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), | ||
849 | (long __user *)(frame->retcode + 4)); | ||
850 | #else | ||
851 | /* moveq #,d0; notb d0; trap #0 */ | ||
852 | err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), | ||
853 | (long __user *)(frame->retcode + 0)); | ||
854 | err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); | ||
855 | #endif | ||
856 | |||
857 | if (err) | ||
858 | goto give_sigsegv; | ||
859 | |||
860 | push_cache ((unsigned long) &frame->retcode); | ||
861 | |||
862 | /* | ||
863 | * Set up registers for signal handler. All the state we are about | ||
864 | * to destroy is successfully copied to sigframe. | ||
865 | */ | ||
866 | wrusp ((unsigned long) frame); | ||
867 | regs->pc = (unsigned long) ka->sa.sa_handler; | ||
868 | |||
869 | /* | ||
870 | * This is subtle; if we build more than one sigframe, all but the | ||
871 | * first one will see frame format 0 and have fsize == 0, so we won't | ||
872 | * screw stkadj. | ||
873 | */ | ||
874 | if (fsize) | ||
875 | regs->stkadj = fsize; | ||
876 | |||
877 | /* Prepare to skip over the extra stuff in the exception frame. */ | ||
878 | if (regs->stkadj) { | ||
879 | struct pt_regs *tregs = | ||
880 | (struct pt_regs *)((ulong)regs + regs->stkadj); | ||
881 | #ifdef DEBUG | ||
882 | printk("Performing stackadjust=%04x\n", regs->stkadj); | ||
883 | #endif | ||
884 | /* This must be copied with decreasing addresses to | ||
885 | handle overlaps. */ | ||
886 | tregs->vector = 0; | ||
887 | tregs->format = 0; | ||
888 | tregs->pc = regs->pc; | ||
889 | tregs->sr = regs->sr; | ||
890 | } | ||
891 | return 0; | ||
892 | |||
893 | give_sigsegv: | ||
894 | force_sigsegv(sig, current); | ||
895 | return err; | ||
896 | } | ||
897 | |||
898 | static inline void | ||
899 | handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) | ||
900 | { | ||
901 | switch (regs->d0) { | ||
902 | case -ERESTARTNOHAND: | ||
903 | if (!has_handler) | ||
904 | goto do_restart; | ||
905 | regs->d0 = -EINTR; | ||
906 | break; | ||
907 | |||
908 | case -ERESTART_RESTARTBLOCK: | ||
909 | if (!has_handler) { | ||
910 | regs->d0 = __NR_restart_syscall; | ||
911 | regs->pc -= 2; | ||
912 | break; | ||
913 | } | ||
914 | regs->d0 = -EINTR; | ||
915 | break; | ||
916 | |||
917 | case -ERESTARTSYS: | ||
918 | if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { | ||
919 | regs->d0 = -EINTR; | ||
920 | break; | ||
921 | } | ||
922 | /* fallthrough */ | ||
923 | case -ERESTARTNOINTR: | ||
924 | do_restart: | ||
925 | regs->d0 = regs->orig_d0; | ||
926 | regs->pc -= 2; | ||
927 | break; | ||
928 | } | ||
929 | } | ||
930 | |||
931 | void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) | ||
932 | { | ||
933 | if (regs->orig_d0 < 0) | ||
934 | return; | ||
935 | switch (regs->d0) { | ||
936 | case -ERESTARTNOHAND: | ||
937 | case -ERESTARTSYS: | ||
938 | case -ERESTARTNOINTR: | ||
939 | regs->d0 = regs->orig_d0; | ||
940 | regs->orig_d0 = -1; | ||
941 | regs->pc -= 2; | ||
942 | break; | ||
943 | } | ||
944 | } | ||
945 | |||
946 | /* | ||
947 | * OK, we're invoking a handler | ||
948 | */ | ||
949 | static void | ||
950 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | ||
951 | sigset_t *oldset, struct pt_regs *regs) | ||
952 | { | ||
953 | int err; | ||
954 | /* are we from a system call? */ | ||
955 | if (regs->orig_d0 >= 0) | ||
956 | /* If so, check system call restarting.. */ | ||
957 | handle_restart(regs, ka, 1); | ||
958 | |||
959 | /* set up the stack frame */ | ||
960 | if (ka->sa.sa_flags & SA_SIGINFO) | ||
961 | err = setup_rt_frame(sig, ka, info, oldset, regs); | ||
962 | else | ||
963 | err = setup_frame(sig, ka, oldset, regs); | ||
964 | |||
965 | if (err) | ||
966 | return; | ||
967 | |||
968 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
969 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
970 | sigaddset(¤t->blocked,sig); | ||
971 | recalc_sigpending(); | ||
972 | |||
973 | if (test_thread_flag(TIF_DELAYED_TRACE)) { | ||
974 | regs->sr &= ~0x8000; | ||
975 | send_sig(SIGTRAP, current, 1); | ||
976 | } | ||
977 | |||
978 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
979 | } | ||
980 | |||
981 | /* | ||
982 | * Note that 'init' is a special process: it doesn't get signals it doesn't | ||
983 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | ||
984 | * mistake. | ||
985 | */ | ||
986 | asmlinkage void do_signal(struct pt_regs *regs) | ||
987 | { | ||
988 | siginfo_t info; | ||
989 | struct k_sigaction ka; | ||
990 | int signr; | ||
991 | sigset_t *oldset; | ||
992 | |||
993 | current->thread.esp0 = (unsigned long) regs; | ||
994 | |||
995 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
996 | oldset = ¤t->saved_sigmask; | ||
997 | else | ||
998 | oldset = ¤t->blocked; | ||
999 | |||
1000 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | ||
1001 | if (signr > 0) { | ||
1002 | /* Whee! Actually deliver the signal. */ | ||
1003 | handle_signal(signr, &ka, &info, oldset, regs); | ||
1004 | return; | ||
1005 | } | ||
1006 | |||
1007 | /* Did we come from a system call? */ | ||
1008 | if (regs->orig_d0 >= 0) | ||
1009 | /* Restart the system call - no handlers present */ | ||
1010 | handle_restart(regs, NULL, 0); | ||
1011 | |||
1012 | /* If there's no signal to deliver, we just restore the saved mask. */ | ||
1013 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
1014 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
1015 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
1016 | } | ||
1017 | } | ||
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68k/kernel/signal_no.c index 36a81bb6835a..36a81bb6835a 100644 --- a/arch/m68knommu/kernel/signal.c +++ b/arch/m68k/kernel/signal_no.c | |||
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 3db2e7f902aa..63013df33584 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c | |||
@@ -1,546 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/kernel/sys_m68k.c | 2 | #include "sys_m68k_mm.c" |
3 | * | 3 | #else |
4 | * This file contains various random system calls that | 4 | #include "sys_m68k_no.c" |
5 | * have a non-standard calling sequence on the Linux/m68k | 5 | #endif |
6 | * platform. | ||
7 | */ | ||
8 | |||
9 | #include <linux/capability.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/smp.h> | ||
15 | #include <linux/sem.h> | ||
16 | #include <linux/msg.h> | ||
17 | #include <linux/shm.h> | ||
18 | #include <linux/stat.h> | ||
19 | #include <linux/syscalls.h> | ||
20 | #include <linux/mman.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/ipc.h> | ||
23 | |||
24 | #include <asm/setup.h> | ||
25 | #include <asm/uaccess.h> | ||
26 | #include <asm/cachectl.h> | ||
27 | #include <asm/traps.h> | ||
28 | #include <asm/page.h> | ||
29 | #include <asm/unistd.h> | ||
30 | #include <linux/elf.h> | ||
31 | #include <asm/tlb.h> | ||
32 | |||
33 | asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, | ||
34 | unsigned long error_code); | ||
35 | |||
36 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
37 | unsigned long prot, unsigned long flags, | ||
38 | unsigned long fd, unsigned long pgoff) | ||
39 | { | ||
40 | /* | ||
41 | * This is wrong for sun3 - there PAGE_SIZE is 8Kb, | ||
42 | * so we need to shift the argument down by 1; m68k mmap64(3) | ||
43 | * (in libc) expects the last argument of mmap2 in 4Kb units. | ||
44 | */ | ||
45 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); | ||
46 | } | ||
47 | |||
48 | /* Convert virtual (user) address VADDR to physical address PADDR */ | ||
49 | #define virt_to_phys_040(vaddr) \ | ||
50 | ({ \ | ||
51 | unsigned long _mmusr, _paddr; \ | ||
52 | \ | ||
53 | __asm__ __volatile__ (".chip 68040\n\t" \ | ||
54 | "ptestr (%1)\n\t" \ | ||
55 | "movec %%mmusr,%0\n\t" \ | ||
56 | ".chip 68k" \ | ||
57 | : "=r" (_mmusr) \ | ||
58 | : "a" (vaddr)); \ | ||
59 | _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \ | ||
60 | _paddr; \ | ||
61 | }) | ||
62 | |||
63 | static inline int | ||
64 | cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len) | ||
65 | { | ||
66 | unsigned long paddr, i; | ||
67 | |||
68 | switch (scope) | ||
69 | { | ||
70 | case FLUSH_SCOPE_ALL: | ||
71 | switch (cache) | ||
72 | { | ||
73 | case FLUSH_CACHE_DATA: | ||
74 | /* This nop is needed for some broken versions of the 68040. */ | ||
75 | __asm__ __volatile__ ("nop\n\t" | ||
76 | ".chip 68040\n\t" | ||
77 | "cpusha %dc\n\t" | ||
78 | ".chip 68k"); | ||
79 | break; | ||
80 | case FLUSH_CACHE_INSN: | ||
81 | __asm__ __volatile__ ("nop\n\t" | ||
82 | ".chip 68040\n\t" | ||
83 | "cpusha %ic\n\t" | ||
84 | ".chip 68k"); | ||
85 | break; | ||
86 | default: | ||
87 | case FLUSH_CACHE_BOTH: | ||
88 | __asm__ __volatile__ ("nop\n\t" | ||
89 | ".chip 68040\n\t" | ||
90 | "cpusha %bc\n\t" | ||
91 | ".chip 68k"); | ||
92 | break; | ||
93 | } | ||
94 | break; | ||
95 | |||
96 | case FLUSH_SCOPE_LINE: | ||
97 | /* Find the physical address of the first mapped page in the | ||
98 | address range. */ | ||
99 | if ((paddr = virt_to_phys_040(addr))) { | ||
100 | paddr += addr & ~(PAGE_MASK | 15); | ||
101 | len = (len + (addr & 15) + 15) >> 4; | ||
102 | } else { | ||
103 | unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); | ||
104 | |||
105 | if (len <= tmp) | ||
106 | return 0; | ||
107 | addr += tmp; | ||
108 | len -= tmp; | ||
109 | tmp = PAGE_SIZE; | ||
110 | for (;;) | ||
111 | { | ||
112 | if ((paddr = virt_to_phys_040(addr))) | ||
113 | break; | ||
114 | if (len <= tmp) | ||
115 | return 0; | ||
116 | addr += tmp; | ||
117 | len -= tmp; | ||
118 | } | ||
119 | len = (len + 15) >> 4; | ||
120 | } | ||
121 | i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; | ||
122 | while (len--) | ||
123 | { | ||
124 | switch (cache) | ||
125 | { | ||
126 | case FLUSH_CACHE_DATA: | ||
127 | __asm__ __volatile__ ("nop\n\t" | ||
128 | ".chip 68040\n\t" | ||
129 | "cpushl %%dc,(%0)\n\t" | ||
130 | ".chip 68k" | ||
131 | : : "a" (paddr)); | ||
132 | break; | ||
133 | case FLUSH_CACHE_INSN: | ||
134 | __asm__ __volatile__ ("nop\n\t" | ||
135 | ".chip 68040\n\t" | ||
136 | "cpushl %%ic,(%0)\n\t" | ||
137 | ".chip 68k" | ||
138 | : : "a" (paddr)); | ||
139 | break; | ||
140 | default: | ||
141 | case FLUSH_CACHE_BOTH: | ||
142 | __asm__ __volatile__ ("nop\n\t" | ||
143 | ".chip 68040\n\t" | ||
144 | "cpushl %%bc,(%0)\n\t" | ||
145 | ".chip 68k" | ||
146 | : : "a" (paddr)); | ||
147 | break; | ||
148 | } | ||
149 | if (!--i && len) | ||
150 | { | ||
151 | /* | ||
152 | * No need to page align here since it is done by | ||
153 | * virt_to_phys_040(). | ||
154 | */ | ||
155 | addr += PAGE_SIZE; | ||
156 | i = PAGE_SIZE / 16; | ||
157 | /* Recompute physical address when crossing a page | ||
158 | boundary. */ | ||
159 | for (;;) | ||
160 | { | ||
161 | if ((paddr = virt_to_phys_040(addr))) | ||
162 | break; | ||
163 | if (len <= i) | ||
164 | return 0; | ||
165 | len -= i; | ||
166 | addr += PAGE_SIZE; | ||
167 | } | ||
168 | } | ||
169 | else | ||
170 | paddr += 16; | ||
171 | } | ||
172 | break; | ||
173 | |||
174 | default: | ||
175 | case FLUSH_SCOPE_PAGE: | ||
176 | len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); | ||
177 | for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) | ||
178 | { | ||
179 | if (!(paddr = virt_to_phys_040(addr))) | ||
180 | continue; | ||
181 | switch (cache) | ||
182 | { | ||
183 | case FLUSH_CACHE_DATA: | ||
184 | __asm__ __volatile__ ("nop\n\t" | ||
185 | ".chip 68040\n\t" | ||
186 | "cpushp %%dc,(%0)\n\t" | ||
187 | ".chip 68k" | ||
188 | : : "a" (paddr)); | ||
189 | break; | ||
190 | case FLUSH_CACHE_INSN: | ||
191 | __asm__ __volatile__ ("nop\n\t" | ||
192 | ".chip 68040\n\t" | ||
193 | "cpushp %%ic,(%0)\n\t" | ||
194 | ".chip 68k" | ||
195 | : : "a" (paddr)); | ||
196 | break; | ||
197 | default: | ||
198 | case FLUSH_CACHE_BOTH: | ||
199 | __asm__ __volatile__ ("nop\n\t" | ||
200 | ".chip 68040\n\t" | ||
201 | "cpushp %%bc,(%0)\n\t" | ||
202 | ".chip 68k" | ||
203 | : : "a" (paddr)); | ||
204 | break; | ||
205 | } | ||
206 | } | ||
207 | break; | ||
208 | } | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | #define virt_to_phys_060(vaddr) \ | ||
213 | ({ \ | ||
214 | unsigned long paddr; \ | ||
215 | __asm__ __volatile__ (".chip 68060\n\t" \ | ||
216 | "plpar (%0)\n\t" \ | ||
217 | ".chip 68k" \ | ||
218 | : "=a" (paddr) \ | ||
219 | : "0" (vaddr)); \ | ||
220 | (paddr); /* XXX */ \ | ||
221 | }) | ||
222 | |||
223 | static inline int | ||
224 | cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len) | ||
225 | { | ||
226 | unsigned long paddr, i; | ||
227 | |||
228 | /* | ||
229 | * 68060 manual says: | ||
230 | * cpush %dc : flush DC, remains valid (with our %cacr setup) | ||
231 | * cpush %ic : invalidate IC | ||
232 | * cpush %bc : flush DC + invalidate IC | ||
233 | */ | ||
234 | switch (scope) | ||
235 | { | ||
236 | case FLUSH_SCOPE_ALL: | ||
237 | switch (cache) | ||
238 | { | ||
239 | case FLUSH_CACHE_DATA: | ||
240 | __asm__ __volatile__ (".chip 68060\n\t" | ||
241 | "cpusha %dc\n\t" | ||
242 | ".chip 68k"); | ||
243 | break; | ||
244 | case FLUSH_CACHE_INSN: | ||
245 | __asm__ __volatile__ (".chip 68060\n\t" | ||
246 | "cpusha %ic\n\t" | ||
247 | ".chip 68k"); | ||
248 | break; | ||
249 | default: | ||
250 | case FLUSH_CACHE_BOTH: | ||
251 | __asm__ __volatile__ (".chip 68060\n\t" | ||
252 | "cpusha %bc\n\t" | ||
253 | ".chip 68k"); | ||
254 | break; | ||
255 | } | ||
256 | break; | ||
257 | |||
258 | case FLUSH_SCOPE_LINE: | ||
259 | /* Find the physical address of the first mapped page in the | ||
260 | address range. */ | ||
261 | len += addr & 15; | ||
262 | addr &= -16; | ||
263 | if (!(paddr = virt_to_phys_060(addr))) { | ||
264 | unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); | ||
265 | |||
266 | if (len <= tmp) | ||
267 | return 0; | ||
268 | addr += tmp; | ||
269 | len -= tmp; | ||
270 | tmp = PAGE_SIZE; | ||
271 | for (;;) | ||
272 | { | ||
273 | if ((paddr = virt_to_phys_060(addr))) | ||
274 | break; | ||
275 | if (len <= tmp) | ||
276 | return 0; | ||
277 | addr += tmp; | ||
278 | len -= tmp; | ||
279 | } | ||
280 | } | ||
281 | len = (len + 15) >> 4; | ||
282 | i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; | ||
283 | while (len--) | ||
284 | { | ||
285 | switch (cache) | ||
286 | { | ||
287 | case FLUSH_CACHE_DATA: | ||
288 | __asm__ __volatile__ (".chip 68060\n\t" | ||
289 | "cpushl %%dc,(%0)\n\t" | ||
290 | ".chip 68k" | ||
291 | : : "a" (paddr)); | ||
292 | break; | ||
293 | case FLUSH_CACHE_INSN: | ||
294 | __asm__ __volatile__ (".chip 68060\n\t" | ||
295 | "cpushl %%ic,(%0)\n\t" | ||
296 | ".chip 68k" | ||
297 | : : "a" (paddr)); | ||
298 | break; | ||
299 | default: | ||
300 | case FLUSH_CACHE_BOTH: | ||
301 | __asm__ __volatile__ (".chip 68060\n\t" | ||
302 | "cpushl %%bc,(%0)\n\t" | ||
303 | ".chip 68k" | ||
304 | : : "a" (paddr)); | ||
305 | break; | ||
306 | } | ||
307 | if (!--i && len) | ||
308 | { | ||
309 | |||
310 | /* | ||
311 | * We just want to jump to the first cache line | ||
312 | * in the next page. | ||
313 | */ | ||
314 | addr += PAGE_SIZE; | ||
315 | addr &= PAGE_MASK; | ||
316 | |||
317 | i = PAGE_SIZE / 16; | ||
318 | /* Recompute physical address when crossing a page | ||
319 | boundary. */ | ||
320 | for (;;) | ||
321 | { | ||
322 | if ((paddr = virt_to_phys_060(addr))) | ||
323 | break; | ||
324 | if (len <= i) | ||
325 | return 0; | ||
326 | len -= i; | ||
327 | addr += PAGE_SIZE; | ||
328 | } | ||
329 | } | ||
330 | else | ||
331 | paddr += 16; | ||
332 | } | ||
333 | break; | ||
334 | |||
335 | default: | ||
336 | case FLUSH_SCOPE_PAGE: | ||
337 | len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); | ||
338 | addr &= PAGE_MASK; /* Workaround for bug in some | ||
339 | revisions of the 68060 */ | ||
340 | for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) | ||
341 | { | ||
342 | if (!(paddr = virt_to_phys_060(addr))) | ||
343 | continue; | ||
344 | switch (cache) | ||
345 | { | ||
346 | case FLUSH_CACHE_DATA: | ||
347 | __asm__ __volatile__ (".chip 68060\n\t" | ||
348 | "cpushp %%dc,(%0)\n\t" | ||
349 | ".chip 68k" | ||
350 | : : "a" (paddr)); | ||
351 | break; | ||
352 | case FLUSH_CACHE_INSN: | ||
353 | __asm__ __volatile__ (".chip 68060\n\t" | ||
354 | "cpushp %%ic,(%0)\n\t" | ||
355 | ".chip 68k" | ||
356 | : : "a" (paddr)); | ||
357 | break; | ||
358 | default: | ||
359 | case FLUSH_CACHE_BOTH: | ||
360 | __asm__ __volatile__ (".chip 68060\n\t" | ||
361 | "cpushp %%bc,(%0)\n\t" | ||
362 | ".chip 68k" | ||
363 | : : "a" (paddr)); | ||
364 | break; | ||
365 | } | ||
366 | } | ||
367 | break; | ||
368 | } | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /* sys_cacheflush -- flush (part of) the processor cache. */ | ||
373 | asmlinkage int | ||
374 | sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) | ||
375 | { | ||
376 | struct vm_area_struct *vma; | ||
377 | int ret = -EINVAL; | ||
378 | |||
379 | if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || | ||
380 | cache & ~FLUSH_CACHE_BOTH) | ||
381 | goto out; | ||
382 | |||
383 | if (scope == FLUSH_SCOPE_ALL) { | ||
384 | /* Only the superuser may explicitly flush the whole cache. */ | ||
385 | ret = -EPERM; | ||
386 | if (!capable(CAP_SYS_ADMIN)) | ||
387 | goto out; | ||
388 | } else { | ||
389 | /* | ||
390 | * Verify that the specified address region actually belongs | ||
391 | * to this process. | ||
392 | */ | ||
393 | vma = find_vma (current->mm, addr); | ||
394 | ret = -EINVAL; | ||
395 | /* Check for overflow. */ | ||
396 | if (addr + len < addr) | ||
397 | goto out; | ||
398 | if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) | ||
399 | goto out; | ||
400 | } | ||
401 | |||
402 | if (CPU_IS_020_OR_030) { | ||
403 | if (scope == FLUSH_SCOPE_LINE && len < 256) { | ||
404 | unsigned long cacr; | ||
405 | __asm__ ("movec %%cacr, %0" : "=r" (cacr)); | ||
406 | if (cache & FLUSH_CACHE_INSN) | ||
407 | cacr |= 4; | ||
408 | if (cache & FLUSH_CACHE_DATA) | ||
409 | cacr |= 0x400; | ||
410 | len >>= 2; | ||
411 | while (len--) { | ||
412 | __asm__ __volatile__ ("movec %1, %%caar\n\t" | ||
413 | "movec %0, %%cacr" | ||
414 | : /* no outputs */ | ||
415 | : "r" (cacr), "r" (addr)); | ||
416 | addr += 4; | ||
417 | } | ||
418 | } else { | ||
419 | /* Flush the whole cache, even if page granularity requested. */ | ||
420 | unsigned long cacr; | ||
421 | __asm__ ("movec %%cacr, %0" : "=r" (cacr)); | ||
422 | if (cache & FLUSH_CACHE_INSN) | ||
423 | cacr |= 8; | ||
424 | if (cache & FLUSH_CACHE_DATA) | ||
425 | cacr |= 0x800; | ||
426 | __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); | ||
427 | } | ||
428 | ret = 0; | ||
429 | goto out; | ||
430 | } else { | ||
431 | /* | ||
432 | * 040 or 060: don't blindly trust 'scope', someone could | ||
433 | * try to flush a few megs of memory. | ||
434 | */ | ||
435 | |||
436 | if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE) | ||
437 | scope=FLUSH_SCOPE_PAGE; | ||
438 | if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL) | ||
439 | scope=FLUSH_SCOPE_ALL; | ||
440 | if (CPU_IS_040) { | ||
441 | ret = cache_flush_040 (addr, scope, cache, len); | ||
442 | } else if (CPU_IS_060) { | ||
443 | ret = cache_flush_060 (addr, scope, cache, len); | ||
444 | } | ||
445 | } | ||
446 | out: | ||
447 | return ret; | ||
448 | } | ||
449 | |||
450 | asmlinkage int sys_getpagesize(void) | ||
451 | { | ||
452 | return PAGE_SIZE; | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * Do a system call from kernel instead of calling sys_execve so we | ||
457 | * end up with proper pt_regs. | ||
458 | */ | ||
459 | int kernel_execve(const char *filename, | ||
460 | const char *const argv[], | ||
461 | const char *const envp[]) | ||
462 | { | ||
463 | register long __res asm ("%d0") = __NR_execve; | ||
464 | register long __a asm ("%d1") = (long)(filename); | ||
465 | register long __b asm ("%d2") = (long)(argv); | ||
466 | register long __c asm ("%d3") = (long)(envp); | ||
467 | asm volatile ("trap #0" : "+d" (__res) | ||
468 | : "d" (__a), "d" (__b), "d" (__c)); | ||
469 | return __res; | ||
470 | } | ||
471 | |||
472 | asmlinkage unsigned long sys_get_thread_area(void) | ||
473 | { | ||
474 | return current_thread_info()->tp_value; | ||
475 | } | ||
476 | |||
477 | asmlinkage int sys_set_thread_area(unsigned long tp) | ||
478 | { | ||
479 | current_thread_info()->tp_value = tp; | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* This syscall gets its arguments in A0 (mem), D2 (oldval) and | ||
484 | D1 (newval). */ | ||
485 | asmlinkage int | ||
486 | sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, | ||
487 | unsigned long __user * mem) | ||
488 | { | ||
489 | /* This was borrowed from ARM's implementation. */ | ||
490 | for (;;) { | ||
491 | struct mm_struct *mm = current->mm; | ||
492 | pgd_t *pgd; | ||
493 | pmd_t *pmd; | ||
494 | pte_t *pte; | ||
495 | spinlock_t *ptl; | ||
496 | unsigned long mem_value; | ||
497 | |||
498 | down_read(&mm->mmap_sem); | ||
499 | pgd = pgd_offset(mm, (unsigned long)mem); | ||
500 | if (!pgd_present(*pgd)) | ||
501 | goto bad_access; | ||
502 | pmd = pmd_offset(pgd, (unsigned long)mem); | ||
503 | if (!pmd_present(*pmd)) | ||
504 | goto bad_access; | ||
505 | pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); | ||
506 | if (!pte_present(*pte) || !pte_dirty(*pte) | ||
507 | || !pte_write(*pte)) { | ||
508 | pte_unmap_unlock(pte, ptl); | ||
509 | goto bad_access; | ||
510 | } | ||
511 | |||
512 | mem_value = *mem; | ||
513 | if (mem_value == oldval) | ||
514 | *mem = newval; | ||
515 | |||
516 | pte_unmap_unlock(pte, ptl); | ||
517 | up_read(&mm->mmap_sem); | ||
518 | return mem_value; | ||
519 | |||
520 | bad_access: | ||
521 | up_read(&mm->mmap_sem); | ||
522 | /* This is not necessarily a bad access, we can get here if | ||
523 | a memory we're trying to write to should be copied-on-write. | ||
524 | Make the kernel do the necessary page stuff, then re-iterate. | ||
525 | Simulate a write access fault to do that. */ | ||
526 | { | ||
527 | /* The first argument of the function corresponds to | ||
528 | D1, which is the first field of struct pt_regs. */ | ||
529 | struct pt_regs *fp = (struct pt_regs *)&newval; | ||
530 | |||
531 | /* '3' is an RMW flag. */ | ||
532 | if (do_page_fault(fp, (unsigned long)mem, 3)) | ||
533 | /* If the do_page_fault() failed, we don't | ||
534 | have anything meaningful to return. | ||
535 | There should be a SIGSEGV pending for | ||
536 | the process. */ | ||
537 | return 0xdeadbeef; | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | |||
542 | asmlinkage int sys_atomic_barrier(void) | ||
543 | { | ||
544 | /* no code needed for uniprocs */ | ||
545 | return 0; | ||
546 | } | ||
diff --git a/arch/m68k/kernel/sys_m68k_mm.c b/arch/m68k/kernel/sys_m68k_mm.c new file mode 100644 index 000000000000..3db2e7f902aa --- /dev/null +++ b/arch/m68k/kernel/sys_m68k_mm.c | |||
@@ -0,0 +1,546 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/kernel/sys_m68k.c | ||
3 | * | ||
4 | * This file contains various random system calls that | ||
5 | * have a non-standard calling sequence on the Linux/m68k | ||
6 | * platform. | ||
7 | */ | ||
8 | |||
9 | #include <linux/capability.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/smp.h> | ||
15 | #include <linux/sem.h> | ||
16 | #include <linux/msg.h> | ||
17 | #include <linux/shm.h> | ||
18 | #include <linux/stat.h> | ||
19 | #include <linux/syscalls.h> | ||
20 | #include <linux/mman.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/ipc.h> | ||
23 | |||
24 | #include <asm/setup.h> | ||
25 | #include <asm/uaccess.h> | ||
26 | #include <asm/cachectl.h> | ||
27 | #include <asm/traps.h> | ||
28 | #include <asm/page.h> | ||
29 | #include <asm/unistd.h> | ||
30 | #include <linux/elf.h> | ||
31 | #include <asm/tlb.h> | ||
32 | |||
33 | asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, | ||
34 | unsigned long error_code); | ||
35 | |||
36 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | ||
37 | unsigned long prot, unsigned long flags, | ||
38 | unsigned long fd, unsigned long pgoff) | ||
39 | { | ||
40 | /* | ||
41 | * This is wrong for sun3 - there PAGE_SIZE is 8Kb, | ||
42 | * so we need to shift the argument down by 1; m68k mmap64(3) | ||
43 | * (in libc) expects the last argument of mmap2 in 4Kb units. | ||
44 | */ | ||
45 | return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); | ||
46 | } | ||
47 | |||
48 | /* Convert virtual (user) address VADDR to physical address PADDR */ | ||
49 | #define virt_to_phys_040(vaddr) \ | ||
50 | ({ \ | ||
51 | unsigned long _mmusr, _paddr; \ | ||
52 | \ | ||
53 | __asm__ __volatile__ (".chip 68040\n\t" \ | ||
54 | "ptestr (%1)\n\t" \ | ||
55 | "movec %%mmusr,%0\n\t" \ | ||
56 | ".chip 68k" \ | ||
57 | : "=r" (_mmusr) \ | ||
58 | : "a" (vaddr)); \ | ||
59 | _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \ | ||
60 | _paddr; \ | ||
61 | }) | ||
62 | |||
63 | static inline int | ||
64 | cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len) | ||
65 | { | ||
66 | unsigned long paddr, i; | ||
67 | |||
68 | switch (scope) | ||
69 | { | ||
70 | case FLUSH_SCOPE_ALL: | ||
71 | switch (cache) | ||
72 | { | ||
73 | case FLUSH_CACHE_DATA: | ||
74 | /* This nop is needed for some broken versions of the 68040. */ | ||
75 | __asm__ __volatile__ ("nop\n\t" | ||
76 | ".chip 68040\n\t" | ||
77 | "cpusha %dc\n\t" | ||
78 | ".chip 68k"); | ||
79 | break; | ||
80 | case FLUSH_CACHE_INSN: | ||
81 | __asm__ __volatile__ ("nop\n\t" | ||
82 | ".chip 68040\n\t" | ||
83 | "cpusha %ic\n\t" | ||
84 | ".chip 68k"); | ||
85 | break; | ||
86 | default: | ||
87 | case FLUSH_CACHE_BOTH: | ||
88 | __asm__ __volatile__ ("nop\n\t" | ||
89 | ".chip 68040\n\t" | ||
90 | "cpusha %bc\n\t" | ||
91 | ".chip 68k"); | ||
92 | break; | ||
93 | } | ||
94 | break; | ||
95 | |||
96 | case FLUSH_SCOPE_LINE: | ||
97 | /* Find the physical address of the first mapped page in the | ||
98 | address range. */ | ||
99 | if ((paddr = virt_to_phys_040(addr))) { | ||
100 | paddr += addr & ~(PAGE_MASK | 15); | ||
101 | len = (len + (addr & 15) + 15) >> 4; | ||
102 | } else { | ||
103 | unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); | ||
104 | |||
105 | if (len <= tmp) | ||
106 | return 0; | ||
107 | addr += tmp; | ||
108 | len -= tmp; | ||
109 | tmp = PAGE_SIZE; | ||
110 | for (;;) | ||
111 | { | ||
112 | if ((paddr = virt_to_phys_040(addr))) | ||
113 | break; | ||
114 | if (len <= tmp) | ||
115 | return 0; | ||
116 | addr += tmp; | ||
117 | len -= tmp; | ||
118 | } | ||
119 | len = (len + 15) >> 4; | ||
120 | } | ||
121 | i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; | ||
122 | while (len--) | ||
123 | { | ||
124 | switch (cache) | ||
125 | { | ||
126 | case FLUSH_CACHE_DATA: | ||
127 | __asm__ __volatile__ ("nop\n\t" | ||
128 | ".chip 68040\n\t" | ||
129 | "cpushl %%dc,(%0)\n\t" | ||
130 | ".chip 68k" | ||
131 | : : "a" (paddr)); | ||
132 | break; | ||
133 | case FLUSH_CACHE_INSN: | ||
134 | __asm__ __volatile__ ("nop\n\t" | ||
135 | ".chip 68040\n\t" | ||
136 | "cpushl %%ic,(%0)\n\t" | ||
137 | ".chip 68k" | ||
138 | : : "a" (paddr)); | ||
139 | break; | ||
140 | default: | ||
141 | case FLUSH_CACHE_BOTH: | ||
142 | __asm__ __volatile__ ("nop\n\t" | ||
143 | ".chip 68040\n\t" | ||
144 | "cpushl %%bc,(%0)\n\t" | ||
145 | ".chip 68k" | ||
146 | : : "a" (paddr)); | ||
147 | break; | ||
148 | } | ||
149 | if (!--i && len) | ||
150 | { | ||
151 | /* | ||
152 | * No need to page align here since it is done by | ||
153 | * virt_to_phys_040(). | ||
154 | */ | ||
155 | addr += PAGE_SIZE; | ||
156 | i = PAGE_SIZE / 16; | ||
157 | /* Recompute physical address when crossing a page | ||
158 | boundary. */ | ||
159 | for (;;) | ||
160 | { | ||
161 | if ((paddr = virt_to_phys_040(addr))) | ||
162 | break; | ||
163 | if (len <= i) | ||
164 | return 0; | ||
165 | len -= i; | ||
166 | addr += PAGE_SIZE; | ||
167 | } | ||
168 | } | ||
169 | else | ||
170 | paddr += 16; | ||
171 | } | ||
172 | break; | ||
173 | |||
174 | default: | ||
175 | case FLUSH_SCOPE_PAGE: | ||
176 | len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); | ||
177 | for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) | ||
178 | { | ||
179 | if (!(paddr = virt_to_phys_040(addr))) | ||
180 | continue; | ||
181 | switch (cache) | ||
182 | { | ||
183 | case FLUSH_CACHE_DATA: | ||
184 | __asm__ __volatile__ ("nop\n\t" | ||
185 | ".chip 68040\n\t" | ||
186 | "cpushp %%dc,(%0)\n\t" | ||
187 | ".chip 68k" | ||
188 | : : "a" (paddr)); | ||
189 | break; | ||
190 | case FLUSH_CACHE_INSN: | ||
191 | __asm__ __volatile__ ("nop\n\t" | ||
192 | ".chip 68040\n\t" | ||
193 | "cpushp %%ic,(%0)\n\t" | ||
194 | ".chip 68k" | ||
195 | : : "a" (paddr)); | ||
196 | break; | ||
197 | default: | ||
198 | case FLUSH_CACHE_BOTH: | ||
199 | __asm__ __volatile__ ("nop\n\t" | ||
200 | ".chip 68040\n\t" | ||
201 | "cpushp %%bc,(%0)\n\t" | ||
202 | ".chip 68k" | ||
203 | : : "a" (paddr)); | ||
204 | break; | ||
205 | } | ||
206 | } | ||
207 | break; | ||
208 | } | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | #define virt_to_phys_060(vaddr) \ | ||
213 | ({ \ | ||
214 | unsigned long paddr; \ | ||
215 | __asm__ __volatile__ (".chip 68060\n\t" \ | ||
216 | "plpar (%0)\n\t" \ | ||
217 | ".chip 68k" \ | ||
218 | : "=a" (paddr) \ | ||
219 | : "0" (vaddr)); \ | ||
220 | (paddr); /* XXX */ \ | ||
221 | }) | ||
222 | |||
223 | static inline int | ||
224 | cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len) | ||
225 | { | ||
226 | unsigned long paddr, i; | ||
227 | |||
228 | /* | ||
229 | * 68060 manual says: | ||
230 | * cpush %dc : flush DC, remains valid (with our %cacr setup) | ||
231 | * cpush %ic : invalidate IC | ||
232 | * cpush %bc : flush DC + invalidate IC | ||
233 | */ | ||
234 | switch (scope) | ||
235 | { | ||
236 | case FLUSH_SCOPE_ALL: | ||
237 | switch (cache) | ||
238 | { | ||
239 | case FLUSH_CACHE_DATA: | ||
240 | __asm__ __volatile__ (".chip 68060\n\t" | ||
241 | "cpusha %dc\n\t" | ||
242 | ".chip 68k"); | ||
243 | break; | ||
244 | case FLUSH_CACHE_INSN: | ||
245 | __asm__ __volatile__ (".chip 68060\n\t" | ||
246 | "cpusha %ic\n\t" | ||
247 | ".chip 68k"); | ||
248 | break; | ||
249 | default: | ||
250 | case FLUSH_CACHE_BOTH: | ||
251 | __asm__ __volatile__ (".chip 68060\n\t" | ||
252 | "cpusha %bc\n\t" | ||
253 | ".chip 68k"); | ||
254 | break; | ||
255 | } | ||
256 | break; | ||
257 | |||
258 | case FLUSH_SCOPE_LINE: | ||
259 | /* Find the physical address of the first mapped page in the | ||
260 | address range. */ | ||
261 | len += addr & 15; | ||
262 | addr &= -16; | ||
263 | if (!(paddr = virt_to_phys_060(addr))) { | ||
264 | unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); | ||
265 | |||
266 | if (len <= tmp) | ||
267 | return 0; | ||
268 | addr += tmp; | ||
269 | len -= tmp; | ||
270 | tmp = PAGE_SIZE; | ||
271 | for (;;) | ||
272 | { | ||
273 | if ((paddr = virt_to_phys_060(addr))) | ||
274 | break; | ||
275 | if (len <= tmp) | ||
276 | return 0; | ||
277 | addr += tmp; | ||
278 | len -= tmp; | ||
279 | } | ||
280 | } | ||
281 | len = (len + 15) >> 4; | ||
282 | i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; | ||
283 | while (len--) | ||
284 | { | ||
285 | switch (cache) | ||
286 | { | ||
287 | case FLUSH_CACHE_DATA: | ||
288 | __asm__ __volatile__ (".chip 68060\n\t" | ||
289 | "cpushl %%dc,(%0)\n\t" | ||
290 | ".chip 68k" | ||
291 | : : "a" (paddr)); | ||
292 | break; | ||
293 | case FLUSH_CACHE_INSN: | ||
294 | __asm__ __volatile__ (".chip 68060\n\t" | ||
295 | "cpushl %%ic,(%0)\n\t" | ||
296 | ".chip 68k" | ||
297 | : : "a" (paddr)); | ||
298 | break; | ||
299 | default: | ||
300 | case FLUSH_CACHE_BOTH: | ||
301 | __asm__ __volatile__ (".chip 68060\n\t" | ||
302 | "cpushl %%bc,(%0)\n\t" | ||
303 | ".chip 68k" | ||
304 | : : "a" (paddr)); | ||
305 | break; | ||
306 | } | ||
307 | if (!--i && len) | ||
308 | { | ||
309 | |||
310 | /* | ||
311 | * We just want to jump to the first cache line | ||
312 | * in the next page. | ||
313 | */ | ||
314 | addr += PAGE_SIZE; | ||
315 | addr &= PAGE_MASK; | ||
316 | |||
317 | i = PAGE_SIZE / 16; | ||
318 | /* Recompute physical address when crossing a page | ||
319 | boundary. */ | ||
320 | for (;;) | ||
321 | { | ||
322 | if ((paddr = virt_to_phys_060(addr))) | ||
323 | break; | ||
324 | if (len <= i) | ||
325 | return 0; | ||
326 | len -= i; | ||
327 | addr += PAGE_SIZE; | ||
328 | } | ||
329 | } | ||
330 | else | ||
331 | paddr += 16; | ||
332 | } | ||
333 | break; | ||
334 | |||
335 | default: | ||
336 | case FLUSH_SCOPE_PAGE: | ||
337 | len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); | ||
338 | addr &= PAGE_MASK; /* Workaround for bug in some | ||
339 | revisions of the 68060 */ | ||
340 | for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) | ||
341 | { | ||
342 | if (!(paddr = virt_to_phys_060(addr))) | ||
343 | continue; | ||
344 | switch (cache) | ||
345 | { | ||
346 | case FLUSH_CACHE_DATA: | ||
347 | __asm__ __volatile__ (".chip 68060\n\t" | ||
348 | "cpushp %%dc,(%0)\n\t" | ||
349 | ".chip 68k" | ||
350 | : : "a" (paddr)); | ||
351 | break; | ||
352 | case FLUSH_CACHE_INSN: | ||
353 | __asm__ __volatile__ (".chip 68060\n\t" | ||
354 | "cpushp %%ic,(%0)\n\t" | ||
355 | ".chip 68k" | ||
356 | : : "a" (paddr)); | ||
357 | break; | ||
358 | default: | ||
359 | case FLUSH_CACHE_BOTH: | ||
360 | __asm__ __volatile__ (".chip 68060\n\t" | ||
361 | "cpushp %%bc,(%0)\n\t" | ||
362 | ".chip 68k" | ||
363 | : : "a" (paddr)); | ||
364 | break; | ||
365 | } | ||
366 | } | ||
367 | break; | ||
368 | } | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /* sys_cacheflush -- flush (part of) the processor cache. */ | ||
373 | asmlinkage int | ||
374 | sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) | ||
375 | { | ||
376 | struct vm_area_struct *vma; | ||
377 | int ret = -EINVAL; | ||
378 | |||
379 | if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || | ||
380 | cache & ~FLUSH_CACHE_BOTH) | ||
381 | goto out; | ||
382 | |||
383 | if (scope == FLUSH_SCOPE_ALL) { | ||
384 | /* Only the superuser may explicitly flush the whole cache. */ | ||
385 | ret = -EPERM; | ||
386 | if (!capable(CAP_SYS_ADMIN)) | ||
387 | goto out; | ||
388 | } else { | ||
389 | /* | ||
390 | * Verify that the specified address region actually belongs | ||
391 | * to this process. | ||
392 | */ | ||
393 | vma = find_vma (current->mm, addr); | ||
394 | ret = -EINVAL; | ||
395 | /* Check for overflow. */ | ||
396 | if (addr + len < addr) | ||
397 | goto out; | ||
398 | if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) | ||
399 | goto out; | ||
400 | } | ||
401 | |||
402 | if (CPU_IS_020_OR_030) { | ||
403 | if (scope == FLUSH_SCOPE_LINE && len < 256) { | ||
404 | unsigned long cacr; | ||
405 | __asm__ ("movec %%cacr, %0" : "=r" (cacr)); | ||
406 | if (cache & FLUSH_CACHE_INSN) | ||
407 | cacr |= 4; | ||
408 | if (cache & FLUSH_CACHE_DATA) | ||
409 | cacr |= 0x400; | ||
410 | len >>= 2; | ||
411 | while (len--) { | ||
412 | __asm__ __volatile__ ("movec %1, %%caar\n\t" | ||
413 | "movec %0, %%cacr" | ||
414 | : /* no outputs */ | ||
415 | : "r" (cacr), "r" (addr)); | ||
416 | addr += 4; | ||
417 | } | ||
418 | } else { | ||
419 | /* Flush the whole cache, even if page granularity requested. */ | ||
420 | unsigned long cacr; | ||
421 | __asm__ ("movec %%cacr, %0" : "=r" (cacr)); | ||
422 | if (cache & FLUSH_CACHE_INSN) | ||
423 | cacr |= 8; | ||
424 | if (cache & FLUSH_CACHE_DATA) | ||
425 | cacr |= 0x800; | ||
426 | __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); | ||
427 | } | ||
428 | ret = 0; | ||
429 | goto out; | ||
430 | } else { | ||
431 | /* | ||
432 | * 040 or 060: don't blindly trust 'scope', someone could | ||
433 | * try to flush a few megs of memory. | ||
434 | */ | ||
435 | |||
436 | if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE) | ||
437 | scope=FLUSH_SCOPE_PAGE; | ||
438 | if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL) | ||
439 | scope=FLUSH_SCOPE_ALL; | ||
440 | if (CPU_IS_040) { | ||
441 | ret = cache_flush_040 (addr, scope, cache, len); | ||
442 | } else if (CPU_IS_060) { | ||
443 | ret = cache_flush_060 (addr, scope, cache, len); | ||
444 | } | ||
445 | } | ||
446 | out: | ||
447 | return ret; | ||
448 | } | ||
449 | |||
450 | asmlinkage int sys_getpagesize(void) | ||
451 | { | ||
452 | return PAGE_SIZE; | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * Do a system call from kernel instead of calling sys_execve so we | ||
457 | * end up with proper pt_regs. | ||
458 | */ | ||
459 | int kernel_execve(const char *filename, | ||
460 | const char *const argv[], | ||
461 | const char *const envp[]) | ||
462 | { | ||
463 | register long __res asm ("%d0") = __NR_execve; | ||
464 | register long __a asm ("%d1") = (long)(filename); | ||
465 | register long __b asm ("%d2") = (long)(argv); | ||
466 | register long __c asm ("%d3") = (long)(envp); | ||
467 | asm volatile ("trap #0" : "+d" (__res) | ||
468 | : "d" (__a), "d" (__b), "d" (__c)); | ||
469 | return __res; | ||
470 | } | ||
471 | |||
472 | asmlinkage unsigned long sys_get_thread_area(void) | ||
473 | { | ||
474 | return current_thread_info()->tp_value; | ||
475 | } | ||
476 | |||
477 | asmlinkage int sys_set_thread_area(unsigned long tp) | ||
478 | { | ||
479 | current_thread_info()->tp_value = tp; | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* This syscall gets its arguments in A0 (mem), D2 (oldval) and | ||
484 | D1 (newval). */ | ||
485 | asmlinkage int | ||
486 | sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, | ||
487 | unsigned long __user * mem) | ||
488 | { | ||
489 | /* This was borrowed from ARM's implementation. */ | ||
490 | for (;;) { | ||
491 | struct mm_struct *mm = current->mm; | ||
492 | pgd_t *pgd; | ||
493 | pmd_t *pmd; | ||
494 | pte_t *pte; | ||
495 | spinlock_t *ptl; | ||
496 | unsigned long mem_value; | ||
497 | |||
498 | down_read(&mm->mmap_sem); | ||
499 | pgd = pgd_offset(mm, (unsigned long)mem); | ||
500 | if (!pgd_present(*pgd)) | ||
501 | goto bad_access; | ||
502 | pmd = pmd_offset(pgd, (unsigned long)mem); | ||
503 | if (!pmd_present(*pmd)) | ||
504 | goto bad_access; | ||
505 | pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); | ||
506 | if (!pte_present(*pte) || !pte_dirty(*pte) | ||
507 | || !pte_write(*pte)) { | ||
508 | pte_unmap_unlock(pte, ptl); | ||
509 | goto bad_access; | ||
510 | } | ||
511 | |||
512 | mem_value = *mem; | ||
513 | if (mem_value == oldval) | ||
514 | *mem = newval; | ||
515 | |||
516 | pte_unmap_unlock(pte, ptl); | ||
517 | up_read(&mm->mmap_sem); | ||
518 | return mem_value; | ||
519 | |||
520 | bad_access: | ||
521 | up_read(&mm->mmap_sem); | ||
522 | /* This is not necessarily a bad access, we can get here if | ||
523 | a memory we're trying to write to should be copied-on-write. | ||
524 | Make the kernel do the necessary page stuff, then re-iterate. | ||
525 | Simulate a write access fault to do that. */ | ||
526 | { | ||
527 | /* The first argument of the function corresponds to | ||
528 | D1, which is the first field of struct pt_regs. */ | ||
529 | struct pt_regs *fp = (struct pt_regs *)&newval; | ||
530 | |||
531 | /* '3' is an RMW flag. */ | ||
532 | if (do_page_fault(fp, (unsigned long)mem, 3)) | ||
533 | /* If the do_page_fault() failed, we don't | ||
534 | have anything meaningful to return. | ||
535 | There should be a SIGSEGV pending for | ||
536 | the process. */ | ||
537 | return 0xdeadbeef; | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | |||
542 | asmlinkage int sys_atomic_barrier(void) | ||
543 | { | ||
544 | /* no code needed for uniprocs */ | ||
545 | return 0; | ||
546 | } | ||
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k_no.c index 68488ae47f0a..68488ae47f0a 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k_no.c | |||
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 79b1ed198c07..79b1ed198c07 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S | |||
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index 18b34ee5db3b..a5cf40c26de5 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c | |||
@@ -1,114 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/kernel/time.c | 2 | #include "time_mm.c" |
3 | * | 3 | #else |
4 | * Copyright (C) 1991, 1992, 1995 Linus Torvalds | 4 | #include "time_no.c" |
5 | * | 5 | #endif |
6 | * This file contains the m68k-specific time handling details. | ||
7 | * Most of the stuff is located in the machine specific files. | ||
8 | * | ||
9 | * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 | ||
10 | * "A Kernel Model for Precision Timekeeping" by Dave Mills | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/param.h> | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/mm.h> | ||
20 | #include <linux/rtc.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | |||
23 | #include <asm/machdep.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/irq_regs.h> | ||
26 | |||
27 | #include <linux/time.h> | ||
28 | #include <linux/timex.h> | ||
29 | #include <linux/profile.h> | ||
30 | |||
31 | static inline int set_rtc_mmss(unsigned long nowtime) | ||
32 | { | ||
33 | if (mach_set_clock_mmss) | ||
34 | return mach_set_clock_mmss (nowtime); | ||
35 | return -1; | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * timer_interrupt() needs to keep up the real-time clock, | ||
40 | * as well as call the "xtime_update()" routine every clocktick | ||
41 | */ | ||
42 | static irqreturn_t timer_interrupt(int irq, void *dummy) | ||
43 | { | ||
44 | xtime_update(1); | ||
45 | update_process_times(user_mode(get_irq_regs())); | ||
46 | profile_tick(CPU_PROFILING); | ||
47 | |||
48 | #ifdef CONFIG_HEARTBEAT | ||
49 | /* use power LED as a heartbeat instead -- much more useful | ||
50 | for debugging -- based on the version for PReP by Cort */ | ||
51 | /* acts like an actual heart beat -- ie thump-thump-pause... */ | ||
52 | if (mach_heartbeat) { | ||
53 | static unsigned cnt = 0, period = 0, dist = 0; | ||
54 | |||
55 | if (cnt == 0 || cnt == dist) | ||
56 | mach_heartbeat( 1 ); | ||
57 | else if (cnt == 7 || cnt == dist+7) | ||
58 | mach_heartbeat( 0 ); | ||
59 | |||
60 | if (++cnt > period) { | ||
61 | cnt = 0; | ||
62 | /* The hyperbolic function below modifies the heartbeat period | ||
63 | * length in dependency of the current (5min) load. It goes | ||
64 | * through the points f(0)=126, f(1)=86, f(5)=51, | ||
65 | * f(inf)->30. */ | ||
66 | period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; | ||
67 | dist = period / 4; | ||
68 | } | ||
69 | } | ||
70 | #endif /* CONFIG_HEARTBEAT */ | ||
71 | return IRQ_HANDLED; | ||
72 | } | ||
73 | |||
74 | void read_persistent_clock(struct timespec *ts) | ||
75 | { | ||
76 | struct rtc_time time; | ||
77 | ts->tv_sec = 0; | ||
78 | ts->tv_nsec = 0; | ||
79 | |||
80 | if (mach_hwclk) { | ||
81 | mach_hwclk(0, &time); | ||
82 | |||
83 | if ((time.tm_year += 1900) < 1970) | ||
84 | time.tm_year += 100; | ||
85 | ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday, | ||
86 | time.tm_hour, time.tm_min, time.tm_sec); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void __init time_init(void) | ||
91 | { | ||
92 | mach_sched_init(timer_interrupt); | ||
93 | } | ||
94 | |||
95 | u32 arch_gettimeoffset(void) | ||
96 | { | ||
97 | return mach_gettimeoffset() * 1000; | ||
98 | } | ||
99 | |||
100 | static int __init rtc_init(void) | ||
101 | { | ||
102 | struct platform_device *pdev; | ||
103 | |||
104 | if (!mach_hwclk) | ||
105 | return -ENODEV; | ||
106 | |||
107 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | ||
108 | if (IS_ERR(pdev)) | ||
109 | return PTR_ERR(pdev); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | module_init(rtc_init); | ||
diff --git a/arch/m68k/kernel/time_mm.c b/arch/m68k/kernel/time_mm.c new file mode 100644 index 000000000000..18b34ee5db3b --- /dev/null +++ b/arch/m68k/kernel/time_mm.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/kernel/time.c | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992, 1995 Linus Torvalds | ||
5 | * | ||
6 | * This file contains the m68k-specific time handling details. | ||
7 | * Most of the stuff is located in the machine specific files. | ||
8 | * | ||
9 | * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 | ||
10 | * "A Kernel Model for Precision Timekeeping" by Dave Mills | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/param.h> | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/mm.h> | ||
20 | #include <linux/rtc.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | |||
23 | #include <asm/machdep.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/irq_regs.h> | ||
26 | |||
27 | #include <linux/time.h> | ||
28 | #include <linux/timex.h> | ||
29 | #include <linux/profile.h> | ||
30 | |||
31 | static inline int set_rtc_mmss(unsigned long nowtime) | ||
32 | { | ||
33 | if (mach_set_clock_mmss) | ||
34 | return mach_set_clock_mmss (nowtime); | ||
35 | return -1; | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * timer_interrupt() needs to keep up the real-time clock, | ||
40 | * as well as call the "xtime_update()" routine every clocktick | ||
41 | */ | ||
42 | static irqreturn_t timer_interrupt(int irq, void *dummy) | ||
43 | { | ||
44 | xtime_update(1); | ||
45 | update_process_times(user_mode(get_irq_regs())); | ||
46 | profile_tick(CPU_PROFILING); | ||
47 | |||
48 | #ifdef CONFIG_HEARTBEAT | ||
49 | /* use power LED as a heartbeat instead -- much more useful | ||
50 | for debugging -- based on the version for PReP by Cort */ | ||
51 | /* acts like an actual heart beat -- ie thump-thump-pause... */ | ||
52 | if (mach_heartbeat) { | ||
53 | static unsigned cnt = 0, period = 0, dist = 0; | ||
54 | |||
55 | if (cnt == 0 || cnt == dist) | ||
56 | mach_heartbeat( 1 ); | ||
57 | else if (cnt == 7 || cnt == dist+7) | ||
58 | mach_heartbeat( 0 ); | ||
59 | |||
60 | if (++cnt > period) { | ||
61 | cnt = 0; | ||
62 | /* The hyperbolic function below modifies the heartbeat period | ||
63 | * length in dependency of the current (5min) load. It goes | ||
64 | * through the points f(0)=126, f(1)=86, f(5)=51, | ||
65 | * f(inf)->30. */ | ||
66 | period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; | ||
67 | dist = period / 4; | ||
68 | } | ||
69 | } | ||
70 | #endif /* CONFIG_HEARTBEAT */ | ||
71 | return IRQ_HANDLED; | ||
72 | } | ||
73 | |||
74 | void read_persistent_clock(struct timespec *ts) | ||
75 | { | ||
76 | struct rtc_time time; | ||
77 | ts->tv_sec = 0; | ||
78 | ts->tv_nsec = 0; | ||
79 | |||
80 | if (mach_hwclk) { | ||
81 | mach_hwclk(0, &time); | ||
82 | |||
83 | if ((time.tm_year += 1900) < 1970) | ||
84 | time.tm_year += 100; | ||
85 | ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday, | ||
86 | time.tm_hour, time.tm_min, time.tm_sec); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void __init time_init(void) | ||
91 | { | ||
92 | mach_sched_init(timer_interrupt); | ||
93 | } | ||
94 | |||
95 | u32 arch_gettimeoffset(void) | ||
96 | { | ||
97 | return mach_gettimeoffset() * 1000; | ||
98 | } | ||
99 | |||
100 | static int __init rtc_init(void) | ||
101 | { | ||
102 | struct platform_device *pdev; | ||
103 | |||
104 | if (!mach_hwclk) | ||
105 | return -ENODEV; | ||
106 | |||
107 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | ||
108 | if (IS_ERR(pdev)) | ||
109 | return PTR_ERR(pdev); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | module_init(rtc_init); | ||
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68k/kernel/time_no.c index 6623909f70e6..6623909f70e6 100644 --- a/arch/m68knommu/kernel/time.c +++ b/arch/m68k/kernel/time_no.c | |||
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index 4022bbc28878..c98add3f5f0f 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c | |||
@@ -1,1207 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/kernel/traps.c | 2 | #include "traps_mm.c" |
3 | * | ||
4 | * Copyright (C) 1993, 1994 by Hamish Macdonald | ||
5 | * | ||
6 | * 68040 fixes by Michael Rausch | ||
7 | * 68040 fixes by Martin Apel | ||
8 | * 68040 fixes and writeback by Richard Zidlicky | ||
9 | * 68060 fixes by Roman Hodek | ||
10 | * 68060 fixes by Jesper Skov | ||
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 | |||
17 | /* | ||
18 | * Sets up all exception vectors | ||
19 | */ | ||
20 | |||
21 | #include <linux/sched.h> | ||
22 | #include <linux/signal.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/user.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/linkage.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/ptrace.h> | ||
31 | #include <linux/kallsyms.h> | ||
32 | |||
33 | #include <asm/setup.h> | ||
34 | #include <asm/fpu.h> | ||
35 | #include <asm/system.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | #include <asm/traps.h> | ||
38 | #include <asm/pgalloc.h> | ||
39 | #include <asm/machdep.h> | ||
40 | #include <asm/siginfo.h> | ||
41 | |||
42 | /* assembler routines */ | ||
43 | asmlinkage void system_call(void); | ||
44 | asmlinkage void buserr(void); | ||
45 | asmlinkage void trap(void); | ||
46 | asmlinkage void nmihandler(void); | ||
47 | #ifdef CONFIG_M68KFPU_EMU | ||
48 | asmlinkage void fpu_emu(void); | ||
49 | #endif | ||
50 | |||
51 | e_vector vectors[256]; | ||
52 | |||
53 | /* nmi handler for the Amiga */ | ||
54 | asm(".text\n" | ||
55 | __ALIGN_STR "\n" | ||
56 | "nmihandler: rte"); | ||
57 | |||
58 | /* | ||
59 | * this must be called very early as the kernel might | ||
60 | * use some instruction that are emulated on the 060 | ||
61 | * and so we're prepared for early probe attempts (e.g. nf_init). | ||
62 | */ | ||
63 | void __init base_trap_init(void) | ||
64 | { | ||
65 | if (MACH_IS_SUN3X) { | ||
66 | extern e_vector *sun3x_prom_vbr; | ||
67 | |||
68 | __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); | ||
69 | } | ||
70 | |||
71 | /* setup the exception vector table */ | ||
72 | __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); | ||
73 | |||
74 | if (CPU_IS_060) { | ||
75 | /* set up ISP entry points */ | ||
76 | asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); | ||
77 | |||
78 | vectors[VEC_UNIMPII] = unimp_vec; | ||
79 | } | ||
80 | |||
81 | vectors[VEC_BUSERR] = buserr; | ||
82 | vectors[VEC_ILLEGAL] = trap; | ||
83 | vectors[VEC_SYS] = system_call; | ||
84 | } | ||
85 | |||
86 | void __init trap_init (void) | ||
87 | { | ||
88 | int i; | ||
89 | |||
90 | for (i = VEC_SPUR; i <= VEC_INT7; i++) | ||
91 | vectors[i] = bad_inthandler; | ||
92 | |||
93 | for (i = 0; i < VEC_USER; i++) | ||
94 | if (!vectors[i]) | ||
95 | vectors[i] = trap; | ||
96 | |||
97 | for (i = VEC_USER; i < 256; i++) | ||
98 | vectors[i] = bad_inthandler; | ||
99 | |||
100 | #ifdef CONFIG_M68KFPU_EMU | ||
101 | if (FPU_IS_EMU) | ||
102 | vectors[VEC_LINE11] = fpu_emu; | ||
103 | #endif | ||
104 | |||
105 | if (CPU_IS_040 && !FPU_IS_EMU) { | ||
106 | /* set up FPSP entry points */ | ||
107 | asmlinkage void dz_vec(void) asm ("dz"); | ||
108 | asmlinkage void inex_vec(void) asm ("inex"); | ||
109 | asmlinkage void ovfl_vec(void) asm ("ovfl"); | ||
110 | asmlinkage void unfl_vec(void) asm ("unfl"); | ||
111 | asmlinkage void snan_vec(void) asm ("snan"); | ||
112 | asmlinkage void operr_vec(void) asm ("operr"); | ||
113 | asmlinkage void bsun_vec(void) asm ("bsun"); | ||
114 | asmlinkage void fline_vec(void) asm ("fline"); | ||
115 | asmlinkage void unsupp_vec(void) asm ("unsupp"); | ||
116 | |||
117 | vectors[VEC_FPDIVZ] = dz_vec; | ||
118 | vectors[VEC_FPIR] = inex_vec; | ||
119 | vectors[VEC_FPOVER] = ovfl_vec; | ||
120 | vectors[VEC_FPUNDER] = unfl_vec; | ||
121 | vectors[VEC_FPNAN] = snan_vec; | ||
122 | vectors[VEC_FPOE] = operr_vec; | ||
123 | vectors[VEC_FPBRUC] = bsun_vec; | ||
124 | vectors[VEC_LINE11] = fline_vec; | ||
125 | vectors[VEC_FPUNSUP] = unsupp_vec; | ||
126 | } | ||
127 | |||
128 | if (CPU_IS_060 && !FPU_IS_EMU) { | ||
129 | /* set up IFPSP entry points */ | ||
130 | asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan"); | ||
131 | asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr"); | ||
132 | asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl"); | ||
133 | asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl"); | ||
134 | asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz"); | ||
135 | asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex"); | ||
136 | asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline"); | ||
137 | asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp"); | ||
138 | asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd"); | ||
139 | |||
140 | vectors[VEC_FPNAN] = snan_vec6; | ||
141 | vectors[VEC_FPOE] = operr_vec6; | ||
142 | vectors[VEC_FPOVER] = ovfl_vec6; | ||
143 | vectors[VEC_FPUNDER] = unfl_vec6; | ||
144 | vectors[VEC_FPDIVZ] = dz_vec6; | ||
145 | vectors[VEC_FPIR] = inex_vec6; | ||
146 | vectors[VEC_LINE11] = fline_vec6; | ||
147 | vectors[VEC_FPUNSUP] = unsupp_vec6; | ||
148 | vectors[VEC_UNIMPEA] = effadd_vec6; | ||
149 | } | ||
150 | |||
151 | /* if running on an amiga, make the NMI interrupt do nothing */ | ||
152 | if (MACH_IS_AMIGA) { | ||
153 | vectors[VEC_INT7] = nmihandler; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | static const char *vec_names[] = { | ||
159 | [VEC_RESETSP] = "RESET SP", | ||
160 | [VEC_RESETPC] = "RESET PC", | ||
161 | [VEC_BUSERR] = "BUS ERROR", | ||
162 | [VEC_ADDRERR] = "ADDRESS ERROR", | ||
163 | [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION", | ||
164 | [VEC_ZERODIV] = "ZERO DIVIDE", | ||
165 | [VEC_CHK] = "CHK", | ||
166 | [VEC_TRAP] = "TRAPcc", | ||
167 | [VEC_PRIV] = "PRIVILEGE VIOLATION", | ||
168 | [VEC_TRACE] = "TRACE", | ||
169 | [VEC_LINE10] = "LINE 1010", | ||
170 | [VEC_LINE11] = "LINE 1111", | ||
171 | [VEC_RESV12] = "UNASSIGNED RESERVED 12", | ||
172 | [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION", | ||
173 | [VEC_FORMAT] = "FORMAT ERROR", | ||
174 | [VEC_UNINT] = "UNINITIALIZED INTERRUPT", | ||
175 | [VEC_RESV16] = "UNASSIGNED RESERVED 16", | ||
176 | [VEC_RESV17] = "UNASSIGNED RESERVED 17", | ||
177 | [VEC_RESV18] = "UNASSIGNED RESERVED 18", | ||
178 | [VEC_RESV19] = "UNASSIGNED RESERVED 19", | ||
179 | [VEC_RESV20] = "UNASSIGNED RESERVED 20", | ||
180 | [VEC_RESV21] = "UNASSIGNED RESERVED 21", | ||
181 | [VEC_RESV22] = "UNASSIGNED RESERVED 22", | ||
182 | [VEC_RESV23] = "UNASSIGNED RESERVED 23", | ||
183 | [VEC_SPUR] = "SPURIOUS INTERRUPT", | ||
184 | [VEC_INT1] = "LEVEL 1 INT", | ||
185 | [VEC_INT2] = "LEVEL 2 INT", | ||
186 | [VEC_INT3] = "LEVEL 3 INT", | ||
187 | [VEC_INT4] = "LEVEL 4 INT", | ||
188 | [VEC_INT5] = "LEVEL 5 INT", | ||
189 | [VEC_INT6] = "LEVEL 6 INT", | ||
190 | [VEC_INT7] = "LEVEL 7 INT", | ||
191 | [VEC_SYS] = "SYSCALL", | ||
192 | [VEC_TRAP1] = "TRAP #1", | ||
193 | [VEC_TRAP2] = "TRAP #2", | ||
194 | [VEC_TRAP3] = "TRAP #3", | ||
195 | [VEC_TRAP4] = "TRAP #4", | ||
196 | [VEC_TRAP5] = "TRAP #5", | ||
197 | [VEC_TRAP6] = "TRAP #6", | ||
198 | [VEC_TRAP7] = "TRAP #7", | ||
199 | [VEC_TRAP8] = "TRAP #8", | ||
200 | [VEC_TRAP9] = "TRAP #9", | ||
201 | [VEC_TRAP10] = "TRAP #10", | ||
202 | [VEC_TRAP11] = "TRAP #11", | ||
203 | [VEC_TRAP12] = "TRAP #12", | ||
204 | [VEC_TRAP13] = "TRAP #13", | ||
205 | [VEC_TRAP14] = "TRAP #14", | ||
206 | [VEC_TRAP15] = "TRAP #15", | ||
207 | [VEC_FPBRUC] = "FPCP BSUN", | ||
208 | [VEC_FPIR] = "FPCP INEXACT", | ||
209 | [VEC_FPDIVZ] = "FPCP DIV BY 0", | ||
210 | [VEC_FPUNDER] = "FPCP UNDERFLOW", | ||
211 | [VEC_FPOE] = "FPCP OPERAND ERROR", | ||
212 | [VEC_FPOVER] = "FPCP OVERFLOW", | ||
213 | [VEC_FPNAN] = "FPCP SNAN", | ||
214 | [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION", | ||
215 | [VEC_MMUCFG] = "MMU CONFIGURATION ERROR", | ||
216 | [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR", | ||
217 | [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR", | ||
218 | [VEC_RESV59] = "UNASSIGNED RESERVED 59", | ||
219 | [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60", | ||
220 | [VEC_UNIMPII] = "UNASSIGNED RESERVED 61", | ||
221 | [VEC_RESV62] = "UNASSIGNED RESERVED 62", | ||
222 | [VEC_RESV63] = "UNASSIGNED RESERVED 63", | ||
223 | }; | ||
224 | |||
225 | static const char *space_names[] = { | ||
226 | [0] = "Space 0", | ||
227 | [USER_DATA] = "User Data", | ||
228 | [USER_PROGRAM] = "User Program", | ||
229 | #ifndef CONFIG_SUN3 | ||
230 | [3] = "Space 3", | ||
231 | #else | 3 | #else |
232 | [FC_CONTROL] = "Control", | 4 | #include "traps_no.c" |
233 | #endif | ||
234 | [4] = "Space 4", | ||
235 | [SUPER_DATA] = "Super Data", | ||
236 | [SUPER_PROGRAM] = "Super Program", | ||
237 | [CPU_SPACE] = "CPU" | ||
238 | }; | ||
239 | |||
240 | void die_if_kernel(char *,struct pt_regs *,int); | ||
241 | asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, | ||
242 | unsigned long error_code); | ||
243 | int send_fault_sig(struct pt_regs *regs); | ||
244 | |||
245 | asmlinkage void trap_c(struct frame *fp); | ||
246 | |||
247 | #if defined (CONFIG_M68060) | ||
248 | static inline void access_error060 (struct frame *fp) | ||
249 | { | ||
250 | unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */ | ||
251 | |||
252 | #ifdef DEBUG | ||
253 | printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr); | ||
254 | #endif | ||
255 | |||
256 | if (fslw & MMU060_BPE) { | ||
257 | /* branch prediction error -> clear branch cache */ | ||
258 | __asm__ __volatile__ ("movec %/cacr,%/d0\n\t" | ||
259 | "orl #0x00400000,%/d0\n\t" | ||
260 | "movec %/d0,%/cacr" | ||
261 | : : : "d0" ); | ||
262 | /* return if there's no other error */ | ||
263 | if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE)) | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) { | ||
268 | unsigned long errorcode; | ||
269 | unsigned long addr = fp->un.fmt4.effaddr; | ||
270 | |||
271 | if (fslw & MMU060_MA) | ||
272 | addr = (addr + PAGE_SIZE - 1) & PAGE_MASK; | ||
273 | |||
274 | errorcode = 1; | ||
275 | if (fslw & MMU060_DESC_ERR) { | ||
276 | __flush_tlb040_one(addr); | ||
277 | errorcode = 0; | ||
278 | } | ||
279 | if (fslw & MMU060_W) | ||
280 | errorcode |= 2; | ||
281 | #ifdef DEBUG | ||
282 | printk("errorcode = %d\n", errorcode ); | ||
283 | #endif | ||
284 | do_page_fault(&fp->ptregs, addr, errorcode); | ||
285 | } else if (fslw & (MMU060_SEE)){ | ||
286 | /* Software Emulation Error. | ||
287 | * fault during mem_read/mem_write in ifpsp060/os.S | ||
288 | */ | ||
289 | send_fault_sig(&fp->ptregs); | ||
290 | } else if (!(fslw & (MMU060_RE|MMU060_WE)) || | ||
291 | send_fault_sig(&fp->ptregs) > 0) { | ||
292 | printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr); | ||
293 | printk( "68060 access error, fslw=%lx\n", fslw ); | ||
294 | trap_c( fp ); | ||
295 | } | ||
296 | } | ||
297 | #endif /* CONFIG_M68060 */ | ||
298 | |||
299 | #if defined (CONFIG_M68040) | ||
300 | static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs) | ||
301 | { | ||
302 | unsigned long mmusr; | ||
303 | mm_segment_t old_fs = get_fs(); | ||
304 | |||
305 | set_fs(MAKE_MM_SEG(wbs)); | ||
306 | |||
307 | if (iswrite) | ||
308 | asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr)); | ||
309 | else | ||
310 | asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr)); | ||
311 | |||
312 | asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr)); | ||
313 | |||
314 | set_fs(old_fs); | ||
315 | |||
316 | return mmusr; | ||
317 | } | ||
318 | |||
319 | static inline int do_040writeback1(unsigned short wbs, unsigned long wba, | ||
320 | unsigned long wbd) | ||
321 | { | ||
322 | int res = 0; | ||
323 | mm_segment_t old_fs = get_fs(); | ||
324 | |||
325 | /* set_fs can not be moved, otherwise put_user() may oops */ | ||
326 | set_fs(MAKE_MM_SEG(wbs)); | ||
327 | |||
328 | switch (wbs & WBSIZ_040) { | ||
329 | case BA_SIZE_BYTE: | ||
330 | res = put_user(wbd & 0xff, (char __user *)wba); | ||
331 | break; | ||
332 | case BA_SIZE_WORD: | ||
333 | res = put_user(wbd & 0xffff, (short __user *)wba); | ||
334 | break; | ||
335 | case BA_SIZE_LONG: | ||
336 | res = put_user(wbd, (int __user *)wba); | ||
337 | break; | ||
338 | } | ||
339 | |||
340 | /* set_fs can not be moved, otherwise put_user() may oops */ | ||
341 | set_fs(old_fs); | ||
342 | |||
343 | |||
344 | #ifdef DEBUG | ||
345 | printk("do_040writeback1, res=%d\n",res); | ||
346 | #endif | ||
347 | |||
348 | return res; | ||
349 | } | ||
350 | |||
351 | /* after an exception in a writeback the stack frame corresponding | ||
352 | * to that exception is discarded, set a few bits in the old frame | ||
353 | * to simulate what it should look like | ||
354 | */ | ||
355 | static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs) | ||
356 | { | ||
357 | fp->un.fmt7.faddr = wba; | ||
358 | fp->un.fmt7.ssw = wbs & 0xff; | ||
359 | if (wba != current->thread.faddr) | ||
360 | fp->un.fmt7.ssw |= MA_040; | ||
361 | } | ||
362 | |||
363 | static inline void do_040writebacks(struct frame *fp) | ||
364 | { | ||
365 | int res = 0; | ||
366 | #if 0 | ||
367 | if (fp->un.fmt7.wb1s & WBV_040) | ||
368 | printk("access_error040: cannot handle 1st writeback. oops.\n"); | ||
369 | #endif | ||
370 | |||
371 | if ((fp->un.fmt7.wb2s & WBV_040) && | ||
372 | !(fp->un.fmt7.wb2s & WBTT_040)) { | ||
373 | res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, | ||
374 | fp->un.fmt7.wb2d); | ||
375 | if (res) | ||
376 | fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s); | ||
377 | else | ||
378 | fp->un.fmt7.wb2s = 0; | ||
379 | } | ||
380 | |||
381 | /* do the 2nd wb only if the first one was successful (except for a kernel wb) */ | ||
382 | if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) { | ||
383 | res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, | ||
384 | fp->un.fmt7.wb3d); | ||
385 | if (res) | ||
386 | { | ||
387 | fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s); | ||
388 | |||
389 | fp->un.fmt7.wb2s = fp->un.fmt7.wb3s; | ||
390 | fp->un.fmt7.wb3s &= (~WBV_040); | ||
391 | fp->un.fmt7.wb2a = fp->un.fmt7.wb3a; | ||
392 | fp->un.fmt7.wb2d = fp->un.fmt7.wb3d; | ||
393 | } | ||
394 | else | ||
395 | fp->un.fmt7.wb3s = 0; | ||
396 | } | ||
397 | |||
398 | if (res) | ||
399 | send_fault_sig(&fp->ptregs); | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * called from sigreturn(), must ensure userspace code didn't | ||
404 | * manipulate exception frame to circumvent protection, then complete | ||
405 | * pending writebacks | ||
406 | * we just clear TM2 to turn it into a userspace access | ||
407 | */ | ||
408 | asmlinkage void berr_040cleanup(struct frame *fp) | ||
409 | { | ||
410 | fp->un.fmt7.wb2s &= ~4; | ||
411 | fp->un.fmt7.wb3s &= ~4; | ||
412 | |||
413 | do_040writebacks(fp); | ||
414 | } | ||
415 | |||
416 | static inline void access_error040(struct frame *fp) | ||
417 | { | ||
418 | unsigned short ssw = fp->un.fmt7.ssw; | ||
419 | unsigned long mmusr; | ||
420 | |||
421 | #ifdef DEBUG | ||
422 | printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr); | ||
423 | printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s, | ||
424 | fp->un.fmt7.wb2s, fp->un.fmt7.wb3s); | ||
425 | printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n", | ||
426 | fp->un.fmt7.wb2a, fp->un.fmt7.wb3a, | ||
427 | fp->un.fmt7.wb2d, fp->un.fmt7.wb3d); | ||
428 | #endif | ||
429 | |||
430 | if (ssw & ATC_040) { | ||
431 | unsigned long addr = fp->un.fmt7.faddr; | ||
432 | unsigned long errorcode; | ||
433 | |||
434 | /* | ||
435 | * The MMU status has to be determined AFTER the address | ||
436 | * has been corrected if there was a misaligned access (MA). | ||
437 | */ | ||
438 | if (ssw & MA_040) | ||
439 | addr = (addr + 7) & -8; | ||
440 | |||
441 | /* MMU error, get the MMUSR info for this access */ | ||
442 | mmusr = probe040(!(ssw & RW_040), addr, ssw); | ||
443 | #ifdef DEBUG | ||
444 | printk("mmusr = %lx\n", mmusr); | ||
445 | #endif | ||
446 | errorcode = 1; | ||
447 | if (!(mmusr & MMU_R_040)) { | ||
448 | /* clear the invalid atc entry */ | ||
449 | __flush_tlb040_one(addr); | ||
450 | errorcode = 0; | ||
451 | } | ||
452 | |||
453 | /* despite what documentation seems to say, RMW | ||
454 | * accesses have always both the LK and RW bits set */ | ||
455 | if (!(ssw & RW_040) || (ssw & LK_040)) | ||
456 | errorcode |= 2; | ||
457 | |||
458 | if (do_page_fault(&fp->ptregs, addr, errorcode)) { | ||
459 | #ifdef DEBUG | ||
460 | printk("do_page_fault() !=0\n"); | ||
461 | #endif | ||
462 | if (user_mode(&fp->ptregs)){ | ||
463 | /* delay writebacks after signal delivery */ | ||
464 | #ifdef DEBUG | ||
465 | printk(".. was usermode - return\n"); | ||
466 | #endif | ||
467 | return; | ||
468 | } | ||
469 | /* disable writeback into user space from kernel | ||
470 | * (if do_page_fault didn't fix the mapping, | ||
471 | * the writeback won't do good) | ||
472 | */ | ||
473 | disable_wb: | ||
474 | #ifdef DEBUG | ||
475 | printk(".. disabling wb2\n"); | ||
476 | #endif | ||
477 | if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr) | ||
478 | fp->un.fmt7.wb2s &= ~WBV_040; | ||
479 | if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr) | ||
480 | fp->un.fmt7.wb3s &= ~WBV_040; | ||
481 | } | ||
482 | } else { | ||
483 | /* In case of a bus error we either kill the process or expect | ||
484 | * the kernel to catch the fault, which then is also responsible | ||
485 | * for cleaning up the mess. | ||
486 | */ | ||
487 | current->thread.signo = SIGBUS; | ||
488 | current->thread.faddr = fp->un.fmt7.faddr; | ||
489 | if (send_fault_sig(&fp->ptregs) >= 0) | ||
490 | printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw, | ||
491 | fp->un.fmt7.faddr); | ||
492 | goto disable_wb; | ||
493 | } | ||
494 | |||
495 | do_040writebacks(fp); | ||
496 | } | ||
497 | #endif /* CONFIG_M68040 */ | ||
498 | |||
499 | #if defined(CONFIG_SUN3) | ||
500 | #include <asm/sun3mmu.h> | ||
501 | |||
502 | extern int mmu_emu_handle_fault (unsigned long, int, int); | ||
503 | |||
504 | /* sun3 version of bus_error030 */ | ||
505 | |||
506 | static inline void bus_error030 (struct frame *fp) | ||
507 | { | ||
508 | unsigned char buserr_type = sun3_get_buserr (); | ||
509 | unsigned long addr, errorcode; | ||
510 | unsigned short ssw = fp->un.fmtb.ssw; | ||
511 | extern unsigned long _sun3_map_test_start, _sun3_map_test_end; | ||
512 | |||
513 | #ifdef DEBUG | ||
514 | if (ssw & (FC | FB)) | ||
515 | printk ("Instruction fault at %#010lx\n", | ||
516 | ssw & FC ? | ||
517 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 | ||
518 | : | ||
519 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); | ||
520 | if (ssw & DF) | ||
521 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
522 | ssw & RW ? "read" : "write", | ||
523 | fp->un.fmtb.daddr, | ||
524 | space_names[ssw & DFC], fp->ptregs.pc); | ||
525 | #endif | ||
526 | |||
527 | /* | ||
528 | * Check if this page should be demand-mapped. This needs to go before | ||
529 | * the testing for a bad kernel-space access (demand-mapping applies | ||
530 | * to kernel accesses too). | ||
531 | */ | ||
532 | |||
533 | if ((ssw & DF) | ||
534 | && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) { | ||
535 | if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0)) | ||
536 | return; | ||
537 | } | ||
538 | |||
539 | /* Check for kernel-space pagefault (BAD). */ | ||
540 | if (fp->ptregs.sr & PS_S) { | ||
541 | /* kernel fault must be a data fault to user space */ | ||
542 | if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) { | ||
543 | // try checking the kernel mappings before surrender | ||
544 | if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1)) | ||
545 | return; | ||
546 | /* instruction fault or kernel data fault! */ | ||
547 | if (ssw & (FC | FB)) | ||
548 | printk ("Instruction fault at %#010lx\n", | ||
549 | fp->ptregs.pc); | ||
550 | if (ssw & DF) { | ||
551 | /* was this fault incurred testing bus mappings? */ | ||
552 | if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) && | ||
553 | (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) { | ||
554 | send_fault_sig(&fp->ptregs); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
559 | ssw & RW ? "read" : "write", | ||
560 | fp->un.fmtb.daddr, | ||
561 | space_names[ssw & DFC], fp->ptregs.pc); | ||
562 | } | ||
563 | printk ("BAD KERNEL BUSERR\n"); | ||
564 | |||
565 | die_if_kernel("Oops", &fp->ptregs,0); | ||
566 | force_sig(SIGKILL, current); | ||
567 | return; | ||
568 | } | ||
569 | } else { | ||
570 | /* user fault */ | ||
571 | if (!(ssw & (FC | FB)) && !(ssw & DF)) | ||
572 | /* not an instruction fault or data fault! BAD */ | ||
573 | panic ("USER BUSERR w/o instruction or data fault"); | ||
574 | } | ||
575 | |||
576 | |||
577 | /* First handle the data fault, if any. */ | ||
578 | if (ssw & DF) { | ||
579 | addr = fp->un.fmtb.daddr; | ||
580 | |||
581 | // errorcode bit 0: 0 -> no page 1 -> protection fault | ||
582 | // errorcode bit 1: 0 -> read fault 1 -> write fault | ||
583 | |||
584 | // (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault | ||
585 | // (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault | ||
586 | |||
587 | if (buserr_type & SUN3_BUSERR_PROTERR) | ||
588 | errorcode = 0x01; | ||
589 | else if (buserr_type & SUN3_BUSERR_INVALID) | ||
590 | errorcode = 0x00; | ||
591 | else { | ||
592 | #ifdef DEBUG | ||
593 | printk ("*** unexpected busfault type=%#04x\n", buserr_type); | ||
594 | printk ("invalid %s access at %#lx from pc %#lx\n", | ||
595 | !(ssw & RW) ? "write" : "read", addr, | ||
596 | fp->ptregs.pc); | ||
597 | #endif | ||
598 | die_if_kernel ("Oops", &fp->ptregs, buserr_type); | ||
599 | force_sig (SIGBUS, current); | ||
600 | return; | ||
601 | } | ||
602 | |||
603 | //todo: wtf is RM bit? --m | ||
604 | if (!(ssw & RW) || ssw & RM) | ||
605 | errorcode |= 0x02; | ||
606 | |||
607 | /* Handle page fault. */ | ||
608 | do_page_fault (&fp->ptregs, addr, errorcode); | ||
609 | |||
610 | /* Retry the data fault now. */ | ||
611 | return; | ||
612 | } | ||
613 | |||
614 | /* Now handle the instruction fault. */ | ||
615 | |||
616 | /* Get the fault address. */ | ||
617 | if (fp->ptregs.format == 0xA) | ||
618 | addr = fp->ptregs.pc + 4; | ||
619 | else | ||
620 | addr = fp->un.fmtb.baddr; | ||
621 | if (ssw & FC) | ||
622 | addr -= 2; | ||
623 | |||
624 | if (buserr_type & SUN3_BUSERR_INVALID) { | ||
625 | if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0)) | ||
626 | do_page_fault (&fp->ptregs, addr, 0); | ||
627 | } else { | ||
628 | #ifdef DEBUG | ||
629 | printk ("protection fault on insn access (segv).\n"); | ||
630 | #endif | ||
631 | force_sig (SIGSEGV, current); | ||
632 | } | ||
633 | } | ||
634 | #else | ||
635 | #if defined(CPU_M68020_OR_M68030) | ||
636 | static inline void bus_error030 (struct frame *fp) | ||
637 | { | ||
638 | volatile unsigned short temp; | ||
639 | unsigned short mmusr; | ||
640 | unsigned long addr, errorcode; | ||
641 | unsigned short ssw = fp->un.fmtb.ssw; | ||
642 | #ifdef DEBUG | ||
643 | unsigned long desc; | ||
644 | |||
645 | printk ("pid = %x ", current->pid); | ||
646 | printk ("SSW=%#06x ", ssw); | ||
647 | |||
648 | if (ssw & (FC | FB)) | ||
649 | printk ("Instruction fault at %#010lx\n", | ||
650 | ssw & FC ? | ||
651 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 | ||
652 | : | ||
653 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); | ||
654 | if (ssw & DF) | ||
655 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
656 | ssw & RW ? "read" : "write", | ||
657 | fp->un.fmtb.daddr, | ||
658 | space_names[ssw & DFC], fp->ptregs.pc); | ||
659 | #endif | ||
660 | |||
661 | /* ++andreas: If a data fault and an instruction fault happen | ||
662 | at the same time map in both pages. */ | ||
663 | |||
664 | /* First handle the data fault, if any. */ | ||
665 | if (ssw & DF) { | ||
666 | addr = fp->un.fmtb.daddr; | ||
667 | |||
668 | #ifdef DEBUG | ||
669 | asm volatile ("ptestr %3,%2@,#7,%0\n\t" | ||
670 | "pmove %%psr,%1@" | ||
671 | : "=a&" (desc) | ||
672 | : "a" (&temp), "a" (addr), "d" (ssw)); | ||
673 | #else | ||
674 | asm volatile ("ptestr %2,%1@,#7\n\t" | ||
675 | "pmove %%psr,%0@" | ||
676 | : : "a" (&temp), "a" (addr), "d" (ssw)); | ||
677 | #endif | ||
678 | mmusr = temp; | ||
679 | |||
680 | #ifdef DEBUG | ||
681 | printk("mmusr is %#x for addr %#lx in task %p\n", | ||
682 | mmusr, addr, current); | ||
683 | printk("descriptor address is %#lx, contents %#lx\n", | ||
684 | __va(desc), *(unsigned long *)__va(desc)); | ||
685 | #endif | ||
686 | |||
687 | errorcode = (mmusr & MMU_I) ? 0 : 1; | ||
688 | if (!(ssw & RW) || (ssw & RM)) | ||
689 | errorcode |= 2; | ||
690 | |||
691 | if (mmusr & (MMU_I | MMU_WP)) { | ||
692 | if (ssw & 4) { | ||
693 | printk("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
694 | ssw & RW ? "read" : "write", | ||
695 | fp->un.fmtb.daddr, | ||
696 | space_names[ssw & DFC], fp->ptregs.pc); | ||
697 | goto buserr; | ||
698 | } | ||
699 | /* Don't try to do anything further if an exception was | ||
700 | handled. */ | ||
701 | if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) | ||
702 | return; | ||
703 | } else if (!(mmusr & MMU_I)) { | ||
704 | /* probably a 020 cas fault */ | ||
705 | if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0) | ||
706 | printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr); | ||
707 | } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { | ||
708 | printk("invalid %s access at %#lx from pc %#lx\n", | ||
709 | !(ssw & RW) ? "write" : "read", addr, | ||
710 | fp->ptregs.pc); | ||
711 | die_if_kernel("Oops",&fp->ptregs,mmusr); | ||
712 | force_sig(SIGSEGV, current); | ||
713 | return; | ||
714 | } else { | ||
715 | #if 0 | ||
716 | static volatile long tlong; | ||
717 | #endif | ||
718 | |||
719 | printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", | ||
720 | !(ssw & RW) ? "write" : "read", addr, | ||
721 | fp->ptregs.pc, ssw); | ||
722 | asm volatile ("ptestr #1,%1@,#0\n\t" | ||
723 | "pmove %%psr,%0@" | ||
724 | : /* no outputs */ | ||
725 | : "a" (&temp), "a" (addr)); | ||
726 | mmusr = temp; | ||
727 | |||
728 | printk ("level 0 mmusr is %#x\n", mmusr); | ||
729 | #if 0 | ||
730 | asm volatile ("pmove %%tt0,%0@" | ||
731 | : /* no outputs */ | ||
732 | : "a" (&tlong)); | ||
733 | printk("tt0 is %#lx, ", tlong); | ||
734 | asm volatile ("pmove %%tt1,%0@" | ||
735 | : /* no outputs */ | ||
736 | : "a" (&tlong)); | ||
737 | printk("tt1 is %#lx\n", tlong); | ||
738 | #endif | ||
739 | #ifdef DEBUG | ||
740 | printk("Unknown SIGSEGV - 1\n"); | ||
741 | #endif | ||
742 | die_if_kernel("Oops",&fp->ptregs,mmusr); | ||
743 | force_sig(SIGSEGV, current); | ||
744 | return; | ||
745 | } | ||
746 | |||
747 | /* setup an ATC entry for the access about to be retried */ | ||
748 | if (!(ssw & RW) || (ssw & RM)) | ||
749 | asm volatile ("ploadw %1,%0@" : /* no outputs */ | ||
750 | : "a" (addr), "d" (ssw)); | ||
751 | else | ||
752 | asm volatile ("ploadr %1,%0@" : /* no outputs */ | ||
753 | : "a" (addr), "d" (ssw)); | ||
754 | } | ||
755 | |||
756 | /* Now handle the instruction fault. */ | ||
757 | |||
758 | if (!(ssw & (FC|FB))) | ||
759 | return; | ||
760 | |||
761 | if (fp->ptregs.sr & PS_S) { | ||
762 | printk("Instruction fault at %#010lx\n", | ||
763 | fp->ptregs.pc); | ||
764 | buserr: | ||
765 | printk ("BAD KERNEL BUSERR\n"); | ||
766 | die_if_kernel("Oops",&fp->ptregs,0); | ||
767 | force_sig(SIGKILL, current); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | /* get the fault address */ | ||
772 | if (fp->ptregs.format == 10) | ||
773 | addr = fp->ptregs.pc + 4; | ||
774 | else | ||
775 | addr = fp->un.fmtb.baddr; | ||
776 | if (ssw & FC) | ||
777 | addr -= 2; | ||
778 | |||
779 | if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0) | ||
780 | /* Insn fault on same page as data fault. But we | ||
781 | should still create the ATC entry. */ | ||
782 | goto create_atc_entry; | ||
783 | |||
784 | #ifdef DEBUG | ||
785 | asm volatile ("ptestr #1,%2@,#7,%0\n\t" | ||
786 | "pmove %%psr,%1@" | ||
787 | : "=a&" (desc) | ||
788 | : "a" (&temp), "a" (addr)); | ||
789 | #else | ||
790 | asm volatile ("ptestr #1,%1@,#7\n\t" | ||
791 | "pmove %%psr,%0@" | ||
792 | : : "a" (&temp), "a" (addr)); | ||
793 | #endif | ||
794 | mmusr = temp; | ||
795 | |||
796 | #ifdef DEBUG | ||
797 | printk ("mmusr is %#x for addr %#lx in task %p\n", | ||
798 | mmusr, addr, current); | ||
799 | printk ("descriptor address is %#lx, contents %#lx\n", | ||
800 | __va(desc), *(unsigned long *)__va(desc)); | ||
801 | #endif | ||
802 | |||
803 | if (mmusr & MMU_I) | ||
804 | do_page_fault (&fp->ptregs, addr, 0); | ||
805 | else if (mmusr & (MMU_B|MMU_L|MMU_S)) { | ||
806 | printk ("invalid insn access at %#lx from pc %#lx\n", | ||
807 | addr, fp->ptregs.pc); | ||
808 | #ifdef DEBUG | ||
809 | printk("Unknown SIGSEGV - 2\n"); | ||
810 | #endif | ||
811 | die_if_kernel("Oops",&fp->ptregs,mmusr); | ||
812 | force_sig(SIGSEGV, current); | ||
813 | return; | ||
814 | } | ||
815 | |||
816 | create_atc_entry: | ||
817 | /* setup an ATC entry for the access about to be retried */ | ||
818 | asm volatile ("ploadr #2,%0@" : /* no outputs */ | ||
819 | : "a" (addr)); | ||
820 | } | ||
821 | #endif /* CPU_M68020_OR_M68030 */ | ||
822 | #endif /* !CONFIG_SUN3 */ | ||
823 | |||
824 | asmlinkage void buserr_c(struct frame *fp) | ||
825 | { | ||
826 | /* Only set esp0 if coming from user mode */ | ||
827 | if (user_mode(&fp->ptregs)) | ||
828 | current->thread.esp0 = (unsigned long) fp; | ||
829 | |||
830 | #ifdef DEBUG | ||
831 | printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format); | ||
832 | #endif | ||
833 | |||
834 | switch (fp->ptregs.format) { | ||
835 | #if defined (CONFIG_M68060) | ||
836 | case 4: /* 68060 access error */ | ||
837 | access_error060 (fp); | ||
838 | break; | ||
839 | #endif | ||
840 | #if defined (CONFIG_M68040) | ||
841 | case 0x7: /* 68040 access error */ | ||
842 | access_error040 (fp); | ||
843 | break; | ||
844 | #endif | ||
845 | #if defined (CPU_M68020_OR_M68030) | ||
846 | case 0xa: | ||
847 | case 0xb: | ||
848 | bus_error030 (fp); | ||
849 | break; | ||
850 | #endif | ||
851 | default: | ||
852 | die_if_kernel("bad frame format",&fp->ptregs,0); | ||
853 | #ifdef DEBUG | ||
854 | printk("Unknown SIGSEGV - 4\n"); | ||
855 | #endif | ||
856 | force_sig(SIGSEGV, current); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | |||
861 | static int kstack_depth_to_print = 48; | ||
862 | |||
863 | void show_trace(unsigned long *stack) | ||
864 | { | ||
865 | unsigned long *endstack; | ||
866 | unsigned long addr; | ||
867 | int i; | ||
868 | |||
869 | printk("Call Trace:"); | ||
870 | addr = (unsigned long)stack + THREAD_SIZE - 1; | ||
871 | endstack = (unsigned long *)(addr & -THREAD_SIZE); | ||
872 | i = 0; | ||
873 | while (stack + 1 <= endstack) { | ||
874 | addr = *stack++; | ||
875 | /* | ||
876 | * If the address is either in the text segment of the | ||
877 | * kernel, or in the region which contains vmalloc'ed | ||
878 | * memory, it *may* be the address of a calling | ||
879 | * routine; if so, print it so that someone tracing | ||
880 | * down the cause of the crash will be able to figure | ||
881 | * out the call path that was taken. | ||
882 | */ | ||
883 | if (__kernel_text_address(addr)) { | ||
884 | #ifndef CONFIG_KALLSYMS | ||
885 | if (i % 5 == 0) | ||
886 | printk("\n "); | ||
887 | #endif | ||
888 | printk(" [<%08lx>] %pS\n", addr, (void *)addr); | ||
889 | i++; | ||
890 | } | ||
891 | } | ||
892 | printk("\n"); | ||
893 | } | ||
894 | |||
895 | void show_registers(struct pt_regs *regs) | ||
896 | { | ||
897 | struct frame *fp = (struct frame *)regs; | ||
898 | mm_segment_t old_fs = get_fs(); | ||
899 | u16 c, *cp; | ||
900 | unsigned long addr; | ||
901 | int i; | ||
902 | |||
903 | print_modules(); | ||
904 | printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc); | ||
905 | printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2); | ||
906 | printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", | ||
907 | regs->d0, regs->d1, regs->d2, regs->d3); | ||
908 | printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", | ||
909 | regs->d4, regs->d5, regs->a0, regs->a1); | ||
910 | |||
911 | printk("Process %s (pid: %d, task=%p)\n", | ||
912 | current->comm, task_pid_nr(current), current); | ||
913 | addr = (unsigned long)&fp->un; | ||
914 | printk("Frame format=%X ", regs->format); | ||
915 | switch (regs->format) { | ||
916 | case 0x2: | ||
917 | printk("instr addr=%08lx\n", fp->un.fmt2.iaddr); | ||
918 | addr += sizeof(fp->un.fmt2); | ||
919 | break; | ||
920 | case 0x3: | ||
921 | printk("eff addr=%08lx\n", fp->un.fmt3.effaddr); | ||
922 | addr += sizeof(fp->un.fmt3); | ||
923 | break; | ||
924 | case 0x4: | ||
925 | printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n" | ||
926 | : "eff addr=%08lx pc=%08lx\n"), | ||
927 | fp->un.fmt4.effaddr, fp->un.fmt4.pc); | ||
928 | addr += sizeof(fp->un.fmt4); | ||
929 | break; | ||
930 | case 0x7: | ||
931 | printk("eff addr=%08lx ssw=%04x faddr=%08lx\n", | ||
932 | fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr); | ||
933 | printk("wb 1 stat/addr/data: %04x %08lx %08lx\n", | ||
934 | fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0); | ||
935 | printk("wb 2 stat/addr/data: %04x %08lx %08lx\n", | ||
936 | fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); | ||
937 | printk("wb 3 stat/addr/data: %04x %08lx %08lx\n", | ||
938 | fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); | ||
939 | printk("push data: %08lx %08lx %08lx %08lx\n", | ||
940 | fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2, | ||
941 | fp->un.fmt7.pd3); | ||
942 | addr += sizeof(fp->un.fmt7); | ||
943 | break; | ||
944 | case 0x9: | ||
945 | printk("instr addr=%08lx\n", fp->un.fmt9.iaddr); | ||
946 | addr += sizeof(fp->un.fmt9); | ||
947 | break; | ||
948 | case 0xa: | ||
949 | printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", | ||
950 | fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb, | ||
951 | fp->un.fmta.daddr, fp->un.fmta.dobuf); | ||
952 | addr += sizeof(fp->un.fmta); | ||
953 | break; | ||
954 | case 0xb: | ||
955 | printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", | ||
956 | fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb, | ||
957 | fp->un.fmtb.daddr, fp->un.fmtb.dobuf); | ||
958 | printk("baddr=%08lx dibuf=%08lx ver=%x\n", | ||
959 | fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver); | ||
960 | addr += sizeof(fp->un.fmtb); | ||
961 | break; | ||
962 | default: | ||
963 | printk("\n"); | ||
964 | } | ||
965 | show_stack(NULL, (unsigned long *)addr); | ||
966 | |||
967 | printk("Code:"); | ||
968 | set_fs(KERNEL_DS); | ||
969 | cp = (u16 *)regs->pc; | ||
970 | for (i = -8; i < 16; i++) { | ||
971 | if (get_user(c, cp + i) && i >= 0) { | ||
972 | printk(" Bad PC value."); | ||
973 | break; | ||
974 | } | ||
975 | printk(i ? " %04x" : " <%04x>", c); | ||
976 | } | ||
977 | set_fs(old_fs); | ||
978 | printk ("\n"); | ||
979 | } | ||
980 | |||
981 | void show_stack(struct task_struct *task, unsigned long *stack) | ||
982 | { | ||
983 | unsigned long *p; | ||
984 | unsigned long *endstack; | ||
985 | int i; | ||
986 | |||
987 | if (!stack) { | ||
988 | if (task) | ||
989 | stack = (unsigned long *)task->thread.esp0; | ||
990 | else | ||
991 | stack = (unsigned long *)&stack; | ||
992 | } | ||
993 | endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); | ||
994 | |||
995 | printk("Stack from %08lx:", (unsigned long)stack); | ||
996 | p = stack; | ||
997 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
998 | if (p + 1 > endstack) | ||
999 | break; | ||
1000 | if (i % 8 == 0) | ||
1001 | printk("\n "); | ||
1002 | printk(" %08lx", *p++); | ||
1003 | } | ||
1004 | printk("\n"); | ||
1005 | show_trace(stack); | ||
1006 | } | ||
1007 | |||
1008 | /* | ||
1009 | * The architecture-independent backtrace generator | ||
1010 | */ | ||
1011 | void dump_stack(void) | ||
1012 | { | ||
1013 | unsigned long stack; | ||
1014 | |||
1015 | show_trace(&stack); | ||
1016 | } | ||
1017 | |||
1018 | EXPORT_SYMBOL(dump_stack); | ||
1019 | |||
1020 | void bad_super_trap (struct frame *fp) | ||
1021 | { | ||
1022 | console_verbose(); | ||
1023 | if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names)) | ||
1024 | printk ("*** %s *** FORMAT=%X\n", | ||
1025 | vec_names[(fp->ptregs.vector) >> 2], | ||
1026 | fp->ptregs.format); | ||
1027 | else | ||
1028 | printk ("*** Exception %d *** FORMAT=%X\n", | ||
1029 | (fp->ptregs.vector) >> 2, | ||
1030 | fp->ptregs.format); | ||
1031 | if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) { | ||
1032 | unsigned short ssw = fp->un.fmtb.ssw; | ||
1033 | |||
1034 | printk ("SSW=%#06x ", ssw); | ||
1035 | |||
1036 | if (ssw & RC) | ||
1037 | printk ("Pipe stage C instruction fault at %#010lx\n", | ||
1038 | (fp->ptregs.format) == 0xA ? | ||
1039 | fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2); | ||
1040 | if (ssw & RB) | ||
1041 | printk ("Pipe stage B instruction fault at %#010lx\n", | ||
1042 | (fp->ptregs.format) == 0xA ? | ||
1043 | fp->ptregs.pc + 4 : fp->un.fmtb.baddr); | ||
1044 | if (ssw & DF) | ||
1045 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
1046 | ssw & RW ? "read" : "write", | ||
1047 | fp->un.fmtb.daddr, space_names[ssw & DFC], | ||
1048 | fp->ptregs.pc); | ||
1049 | } | ||
1050 | printk ("Current process id is %d\n", task_pid_nr(current)); | ||
1051 | die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); | ||
1052 | } | ||
1053 | |||
1054 | asmlinkage void trap_c(struct frame *fp) | ||
1055 | { | ||
1056 | int sig; | ||
1057 | siginfo_t info; | ||
1058 | |||
1059 | if (fp->ptregs.sr & PS_S) { | ||
1060 | if (fp->ptregs.vector == VEC_TRACE << 2) { | ||
1061 | /* traced a trapping instruction on a 68020/30, | ||
1062 | * real exception will be executed afterwards. | ||
1063 | */ | ||
1064 | } else if (!handle_kernel_fault(&fp->ptregs)) | ||
1065 | bad_super_trap(fp); | ||
1066 | return; | ||
1067 | } | ||
1068 | |||
1069 | /* send the appropriate signal to the user program */ | ||
1070 | switch ((fp->ptregs.vector) >> 2) { | ||
1071 | case VEC_ADDRERR: | ||
1072 | info.si_code = BUS_ADRALN; | ||
1073 | sig = SIGBUS; | ||
1074 | break; | ||
1075 | case VEC_ILLEGAL: | ||
1076 | case VEC_LINE10: | ||
1077 | case VEC_LINE11: | ||
1078 | info.si_code = ILL_ILLOPC; | ||
1079 | sig = SIGILL; | ||
1080 | break; | ||
1081 | case VEC_PRIV: | ||
1082 | info.si_code = ILL_PRVOPC; | ||
1083 | sig = SIGILL; | ||
1084 | break; | ||
1085 | case VEC_COPROC: | ||
1086 | info.si_code = ILL_COPROC; | ||
1087 | sig = SIGILL; | ||
1088 | break; | ||
1089 | case VEC_TRAP1: | ||
1090 | case VEC_TRAP2: | ||
1091 | case VEC_TRAP3: | ||
1092 | case VEC_TRAP4: | ||
1093 | case VEC_TRAP5: | ||
1094 | case VEC_TRAP6: | ||
1095 | case VEC_TRAP7: | ||
1096 | case VEC_TRAP8: | ||
1097 | case VEC_TRAP9: | ||
1098 | case VEC_TRAP10: | ||
1099 | case VEC_TRAP11: | ||
1100 | case VEC_TRAP12: | ||
1101 | case VEC_TRAP13: | ||
1102 | case VEC_TRAP14: | ||
1103 | info.si_code = ILL_ILLTRP; | ||
1104 | sig = SIGILL; | ||
1105 | break; | ||
1106 | case VEC_FPBRUC: | ||
1107 | case VEC_FPOE: | ||
1108 | case VEC_FPNAN: | ||
1109 | info.si_code = FPE_FLTINV; | ||
1110 | sig = SIGFPE; | ||
1111 | break; | ||
1112 | case VEC_FPIR: | ||
1113 | info.si_code = FPE_FLTRES; | ||
1114 | sig = SIGFPE; | ||
1115 | break; | ||
1116 | case VEC_FPDIVZ: | ||
1117 | info.si_code = FPE_FLTDIV; | ||
1118 | sig = SIGFPE; | ||
1119 | break; | ||
1120 | case VEC_FPUNDER: | ||
1121 | info.si_code = FPE_FLTUND; | ||
1122 | sig = SIGFPE; | ||
1123 | break; | ||
1124 | case VEC_FPOVER: | ||
1125 | info.si_code = FPE_FLTOVF; | ||
1126 | sig = SIGFPE; | ||
1127 | break; | ||
1128 | case VEC_ZERODIV: | ||
1129 | info.si_code = FPE_INTDIV; | ||
1130 | sig = SIGFPE; | ||
1131 | break; | ||
1132 | case VEC_CHK: | ||
1133 | case VEC_TRAP: | ||
1134 | info.si_code = FPE_INTOVF; | ||
1135 | sig = SIGFPE; | ||
1136 | break; | ||
1137 | case VEC_TRACE: /* ptrace single step */ | ||
1138 | info.si_code = TRAP_TRACE; | ||
1139 | sig = SIGTRAP; | ||
1140 | break; | ||
1141 | case VEC_TRAP15: /* breakpoint */ | ||
1142 | info.si_code = TRAP_BRKPT; | ||
1143 | sig = SIGTRAP; | ||
1144 | break; | ||
1145 | default: | ||
1146 | info.si_code = ILL_ILLOPC; | ||
1147 | sig = SIGILL; | ||
1148 | break; | ||
1149 | } | ||
1150 | info.si_signo = sig; | ||
1151 | info.si_errno = 0; | ||
1152 | switch (fp->ptregs.format) { | ||
1153 | default: | ||
1154 | info.si_addr = (void *) fp->ptregs.pc; | ||
1155 | break; | ||
1156 | case 2: | ||
1157 | info.si_addr = (void *) fp->un.fmt2.iaddr; | ||
1158 | break; | ||
1159 | case 7: | ||
1160 | info.si_addr = (void *) fp->un.fmt7.effaddr; | ||
1161 | break; | ||
1162 | case 9: | ||
1163 | info.si_addr = (void *) fp->un.fmt9.iaddr; | ||
1164 | break; | ||
1165 | case 10: | ||
1166 | info.si_addr = (void *) fp->un.fmta.daddr; | ||
1167 | break; | ||
1168 | case 11: | ||
1169 | info.si_addr = (void *) fp->un.fmtb.daddr; | ||
1170 | break; | ||
1171 | } | ||
1172 | force_sig_info (sig, &info, current); | ||
1173 | } | ||
1174 | |||
1175 | void die_if_kernel (char *str, struct pt_regs *fp, int nr) | ||
1176 | { | ||
1177 | if (!(fp->sr & PS_S)) | ||
1178 | return; | ||
1179 | |||
1180 | console_verbose(); | ||
1181 | printk("%s: %08x\n",str,nr); | ||
1182 | show_registers(fp); | ||
1183 | add_taint(TAINT_DIE); | ||
1184 | do_exit(SIGSEGV); | ||
1185 | } | ||
1186 | |||
1187 | /* | ||
1188 | * This function is called if an error occur while accessing | ||
1189 | * user-space from the fpsp040 code. | ||
1190 | */ | ||
1191 | asmlinkage void fpsp040_die(void) | ||
1192 | { | ||
1193 | do_exit(SIGSEGV); | ||
1194 | } | ||
1195 | |||
1196 | #ifdef CONFIG_M68KFPU_EMU | ||
1197 | asmlinkage void fpemu_signal(int signal, int code, void *addr) | ||
1198 | { | ||
1199 | siginfo_t info; | ||
1200 | |||
1201 | info.si_signo = signal; | ||
1202 | info.si_errno = 0; | ||
1203 | info.si_code = code; | ||
1204 | info.si_addr = addr; | ||
1205 | force_sig_info(signal, &info, current); | ||
1206 | } | ||
1207 | #endif | 5 | #endif |
diff --git a/arch/m68k/kernel/traps_mm.c b/arch/m68k/kernel/traps_mm.c new file mode 100644 index 000000000000..4022bbc28878 --- /dev/null +++ b/arch/m68k/kernel/traps_mm.c | |||
@@ -0,0 +1,1207 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/kernel/traps.c | ||
3 | * | ||
4 | * Copyright (C) 1993, 1994 by Hamish Macdonald | ||
5 | * | ||
6 | * 68040 fixes by Michael Rausch | ||
7 | * 68040 fixes by Martin Apel | ||
8 | * 68040 fixes and writeback by Richard Zidlicky | ||
9 | * 68060 fixes by Roman Hodek | ||
10 | * 68060 fixes by Jesper Skov | ||
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 | |||
17 | /* | ||
18 | * Sets up all exception vectors | ||
19 | */ | ||
20 | |||
21 | #include <linux/sched.h> | ||
22 | #include <linux/signal.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/user.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/linkage.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/ptrace.h> | ||
31 | #include <linux/kallsyms.h> | ||
32 | |||
33 | #include <asm/setup.h> | ||
34 | #include <asm/fpu.h> | ||
35 | #include <asm/system.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | #include <asm/traps.h> | ||
38 | #include <asm/pgalloc.h> | ||
39 | #include <asm/machdep.h> | ||
40 | #include <asm/siginfo.h> | ||
41 | |||
42 | /* assembler routines */ | ||
43 | asmlinkage void system_call(void); | ||
44 | asmlinkage void buserr(void); | ||
45 | asmlinkage void trap(void); | ||
46 | asmlinkage void nmihandler(void); | ||
47 | #ifdef CONFIG_M68KFPU_EMU | ||
48 | asmlinkage void fpu_emu(void); | ||
49 | #endif | ||
50 | |||
51 | e_vector vectors[256]; | ||
52 | |||
53 | /* nmi handler for the Amiga */ | ||
54 | asm(".text\n" | ||
55 | __ALIGN_STR "\n" | ||
56 | "nmihandler: rte"); | ||
57 | |||
58 | /* | ||
59 | * this must be called very early as the kernel might | ||
60 | * use some instruction that are emulated on the 060 | ||
61 | * and so we're prepared for early probe attempts (e.g. nf_init). | ||
62 | */ | ||
63 | void __init base_trap_init(void) | ||
64 | { | ||
65 | if (MACH_IS_SUN3X) { | ||
66 | extern e_vector *sun3x_prom_vbr; | ||
67 | |||
68 | __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); | ||
69 | } | ||
70 | |||
71 | /* setup the exception vector table */ | ||
72 | __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); | ||
73 | |||
74 | if (CPU_IS_060) { | ||
75 | /* set up ISP entry points */ | ||
76 | asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); | ||
77 | |||
78 | vectors[VEC_UNIMPII] = unimp_vec; | ||
79 | } | ||
80 | |||
81 | vectors[VEC_BUSERR] = buserr; | ||
82 | vectors[VEC_ILLEGAL] = trap; | ||
83 | vectors[VEC_SYS] = system_call; | ||
84 | } | ||
85 | |||
86 | void __init trap_init (void) | ||
87 | { | ||
88 | int i; | ||
89 | |||
90 | for (i = VEC_SPUR; i <= VEC_INT7; i++) | ||
91 | vectors[i] = bad_inthandler; | ||
92 | |||
93 | for (i = 0; i < VEC_USER; i++) | ||
94 | if (!vectors[i]) | ||
95 | vectors[i] = trap; | ||
96 | |||
97 | for (i = VEC_USER; i < 256; i++) | ||
98 | vectors[i] = bad_inthandler; | ||
99 | |||
100 | #ifdef CONFIG_M68KFPU_EMU | ||
101 | if (FPU_IS_EMU) | ||
102 | vectors[VEC_LINE11] = fpu_emu; | ||
103 | #endif | ||
104 | |||
105 | if (CPU_IS_040 && !FPU_IS_EMU) { | ||
106 | /* set up FPSP entry points */ | ||
107 | asmlinkage void dz_vec(void) asm ("dz"); | ||
108 | asmlinkage void inex_vec(void) asm ("inex"); | ||
109 | asmlinkage void ovfl_vec(void) asm ("ovfl"); | ||
110 | asmlinkage void unfl_vec(void) asm ("unfl"); | ||
111 | asmlinkage void snan_vec(void) asm ("snan"); | ||
112 | asmlinkage void operr_vec(void) asm ("operr"); | ||
113 | asmlinkage void bsun_vec(void) asm ("bsun"); | ||
114 | asmlinkage void fline_vec(void) asm ("fline"); | ||
115 | asmlinkage void unsupp_vec(void) asm ("unsupp"); | ||
116 | |||
117 | vectors[VEC_FPDIVZ] = dz_vec; | ||
118 | vectors[VEC_FPIR] = inex_vec; | ||
119 | vectors[VEC_FPOVER] = ovfl_vec; | ||
120 | vectors[VEC_FPUNDER] = unfl_vec; | ||
121 | vectors[VEC_FPNAN] = snan_vec; | ||
122 | vectors[VEC_FPOE] = operr_vec; | ||
123 | vectors[VEC_FPBRUC] = bsun_vec; | ||
124 | vectors[VEC_LINE11] = fline_vec; | ||
125 | vectors[VEC_FPUNSUP] = unsupp_vec; | ||
126 | } | ||
127 | |||
128 | if (CPU_IS_060 && !FPU_IS_EMU) { | ||
129 | /* set up IFPSP entry points */ | ||
130 | asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan"); | ||
131 | asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr"); | ||
132 | asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl"); | ||
133 | asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl"); | ||
134 | asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz"); | ||
135 | asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex"); | ||
136 | asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline"); | ||
137 | asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp"); | ||
138 | asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd"); | ||
139 | |||
140 | vectors[VEC_FPNAN] = snan_vec6; | ||
141 | vectors[VEC_FPOE] = operr_vec6; | ||
142 | vectors[VEC_FPOVER] = ovfl_vec6; | ||
143 | vectors[VEC_FPUNDER] = unfl_vec6; | ||
144 | vectors[VEC_FPDIVZ] = dz_vec6; | ||
145 | vectors[VEC_FPIR] = inex_vec6; | ||
146 | vectors[VEC_LINE11] = fline_vec6; | ||
147 | vectors[VEC_FPUNSUP] = unsupp_vec6; | ||
148 | vectors[VEC_UNIMPEA] = effadd_vec6; | ||
149 | } | ||
150 | |||
151 | /* if running on an amiga, make the NMI interrupt do nothing */ | ||
152 | if (MACH_IS_AMIGA) { | ||
153 | vectors[VEC_INT7] = nmihandler; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | static const char *vec_names[] = { | ||
159 | [VEC_RESETSP] = "RESET SP", | ||
160 | [VEC_RESETPC] = "RESET PC", | ||
161 | [VEC_BUSERR] = "BUS ERROR", | ||
162 | [VEC_ADDRERR] = "ADDRESS ERROR", | ||
163 | [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION", | ||
164 | [VEC_ZERODIV] = "ZERO DIVIDE", | ||
165 | [VEC_CHK] = "CHK", | ||
166 | [VEC_TRAP] = "TRAPcc", | ||
167 | [VEC_PRIV] = "PRIVILEGE VIOLATION", | ||
168 | [VEC_TRACE] = "TRACE", | ||
169 | [VEC_LINE10] = "LINE 1010", | ||
170 | [VEC_LINE11] = "LINE 1111", | ||
171 | [VEC_RESV12] = "UNASSIGNED RESERVED 12", | ||
172 | [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION", | ||
173 | [VEC_FORMAT] = "FORMAT ERROR", | ||
174 | [VEC_UNINT] = "UNINITIALIZED INTERRUPT", | ||
175 | [VEC_RESV16] = "UNASSIGNED RESERVED 16", | ||
176 | [VEC_RESV17] = "UNASSIGNED RESERVED 17", | ||
177 | [VEC_RESV18] = "UNASSIGNED RESERVED 18", | ||
178 | [VEC_RESV19] = "UNASSIGNED RESERVED 19", | ||
179 | [VEC_RESV20] = "UNASSIGNED RESERVED 20", | ||
180 | [VEC_RESV21] = "UNASSIGNED RESERVED 21", | ||
181 | [VEC_RESV22] = "UNASSIGNED RESERVED 22", | ||
182 | [VEC_RESV23] = "UNASSIGNED RESERVED 23", | ||
183 | [VEC_SPUR] = "SPURIOUS INTERRUPT", | ||
184 | [VEC_INT1] = "LEVEL 1 INT", | ||
185 | [VEC_INT2] = "LEVEL 2 INT", | ||
186 | [VEC_INT3] = "LEVEL 3 INT", | ||
187 | [VEC_INT4] = "LEVEL 4 INT", | ||
188 | [VEC_INT5] = "LEVEL 5 INT", | ||
189 | [VEC_INT6] = "LEVEL 6 INT", | ||
190 | [VEC_INT7] = "LEVEL 7 INT", | ||
191 | [VEC_SYS] = "SYSCALL", | ||
192 | [VEC_TRAP1] = "TRAP #1", | ||
193 | [VEC_TRAP2] = "TRAP #2", | ||
194 | [VEC_TRAP3] = "TRAP #3", | ||
195 | [VEC_TRAP4] = "TRAP #4", | ||
196 | [VEC_TRAP5] = "TRAP #5", | ||
197 | [VEC_TRAP6] = "TRAP #6", | ||
198 | [VEC_TRAP7] = "TRAP #7", | ||
199 | [VEC_TRAP8] = "TRAP #8", | ||
200 | [VEC_TRAP9] = "TRAP #9", | ||
201 | [VEC_TRAP10] = "TRAP #10", | ||
202 | [VEC_TRAP11] = "TRAP #11", | ||
203 | [VEC_TRAP12] = "TRAP #12", | ||
204 | [VEC_TRAP13] = "TRAP #13", | ||
205 | [VEC_TRAP14] = "TRAP #14", | ||
206 | [VEC_TRAP15] = "TRAP #15", | ||
207 | [VEC_FPBRUC] = "FPCP BSUN", | ||
208 | [VEC_FPIR] = "FPCP INEXACT", | ||
209 | [VEC_FPDIVZ] = "FPCP DIV BY 0", | ||
210 | [VEC_FPUNDER] = "FPCP UNDERFLOW", | ||
211 | [VEC_FPOE] = "FPCP OPERAND ERROR", | ||
212 | [VEC_FPOVER] = "FPCP OVERFLOW", | ||
213 | [VEC_FPNAN] = "FPCP SNAN", | ||
214 | [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION", | ||
215 | [VEC_MMUCFG] = "MMU CONFIGURATION ERROR", | ||
216 | [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR", | ||
217 | [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR", | ||
218 | [VEC_RESV59] = "UNASSIGNED RESERVED 59", | ||
219 | [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60", | ||
220 | [VEC_UNIMPII] = "UNASSIGNED RESERVED 61", | ||
221 | [VEC_RESV62] = "UNASSIGNED RESERVED 62", | ||
222 | [VEC_RESV63] = "UNASSIGNED RESERVED 63", | ||
223 | }; | ||
224 | |||
225 | static const char *space_names[] = { | ||
226 | [0] = "Space 0", | ||
227 | [USER_DATA] = "User Data", | ||
228 | [USER_PROGRAM] = "User Program", | ||
229 | #ifndef CONFIG_SUN3 | ||
230 | [3] = "Space 3", | ||
231 | #else | ||
232 | [FC_CONTROL] = "Control", | ||
233 | #endif | ||
234 | [4] = "Space 4", | ||
235 | [SUPER_DATA] = "Super Data", | ||
236 | [SUPER_PROGRAM] = "Super Program", | ||
237 | [CPU_SPACE] = "CPU" | ||
238 | }; | ||
239 | |||
240 | void die_if_kernel(char *,struct pt_regs *,int); | ||
241 | asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, | ||
242 | unsigned long error_code); | ||
243 | int send_fault_sig(struct pt_regs *regs); | ||
244 | |||
245 | asmlinkage void trap_c(struct frame *fp); | ||
246 | |||
247 | #if defined (CONFIG_M68060) | ||
248 | static inline void access_error060 (struct frame *fp) | ||
249 | { | ||
250 | unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */ | ||
251 | |||
252 | #ifdef DEBUG | ||
253 | printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr); | ||
254 | #endif | ||
255 | |||
256 | if (fslw & MMU060_BPE) { | ||
257 | /* branch prediction error -> clear branch cache */ | ||
258 | __asm__ __volatile__ ("movec %/cacr,%/d0\n\t" | ||
259 | "orl #0x00400000,%/d0\n\t" | ||
260 | "movec %/d0,%/cacr" | ||
261 | : : : "d0" ); | ||
262 | /* return if there's no other error */ | ||
263 | if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE)) | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) { | ||
268 | unsigned long errorcode; | ||
269 | unsigned long addr = fp->un.fmt4.effaddr; | ||
270 | |||
271 | if (fslw & MMU060_MA) | ||
272 | addr = (addr + PAGE_SIZE - 1) & PAGE_MASK; | ||
273 | |||
274 | errorcode = 1; | ||
275 | if (fslw & MMU060_DESC_ERR) { | ||
276 | __flush_tlb040_one(addr); | ||
277 | errorcode = 0; | ||
278 | } | ||
279 | if (fslw & MMU060_W) | ||
280 | errorcode |= 2; | ||
281 | #ifdef DEBUG | ||
282 | printk("errorcode = %d\n", errorcode ); | ||
283 | #endif | ||
284 | do_page_fault(&fp->ptregs, addr, errorcode); | ||
285 | } else if (fslw & (MMU060_SEE)){ | ||
286 | /* Software Emulation Error. | ||
287 | * fault during mem_read/mem_write in ifpsp060/os.S | ||
288 | */ | ||
289 | send_fault_sig(&fp->ptregs); | ||
290 | } else if (!(fslw & (MMU060_RE|MMU060_WE)) || | ||
291 | send_fault_sig(&fp->ptregs) > 0) { | ||
292 | printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr); | ||
293 | printk( "68060 access error, fslw=%lx\n", fslw ); | ||
294 | trap_c( fp ); | ||
295 | } | ||
296 | } | ||
297 | #endif /* CONFIG_M68060 */ | ||
298 | |||
299 | #if defined (CONFIG_M68040) | ||
300 | static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs) | ||
301 | { | ||
302 | unsigned long mmusr; | ||
303 | mm_segment_t old_fs = get_fs(); | ||
304 | |||
305 | set_fs(MAKE_MM_SEG(wbs)); | ||
306 | |||
307 | if (iswrite) | ||
308 | asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr)); | ||
309 | else | ||
310 | asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr)); | ||
311 | |||
312 | asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr)); | ||
313 | |||
314 | set_fs(old_fs); | ||
315 | |||
316 | return mmusr; | ||
317 | } | ||
318 | |||
319 | static inline int do_040writeback1(unsigned short wbs, unsigned long wba, | ||
320 | unsigned long wbd) | ||
321 | { | ||
322 | int res = 0; | ||
323 | mm_segment_t old_fs = get_fs(); | ||
324 | |||
325 | /* set_fs can not be moved, otherwise put_user() may oops */ | ||
326 | set_fs(MAKE_MM_SEG(wbs)); | ||
327 | |||
328 | switch (wbs & WBSIZ_040) { | ||
329 | case BA_SIZE_BYTE: | ||
330 | res = put_user(wbd & 0xff, (char __user *)wba); | ||
331 | break; | ||
332 | case BA_SIZE_WORD: | ||
333 | res = put_user(wbd & 0xffff, (short __user *)wba); | ||
334 | break; | ||
335 | case BA_SIZE_LONG: | ||
336 | res = put_user(wbd, (int __user *)wba); | ||
337 | break; | ||
338 | } | ||
339 | |||
340 | /* set_fs can not be moved, otherwise put_user() may oops */ | ||
341 | set_fs(old_fs); | ||
342 | |||
343 | |||
344 | #ifdef DEBUG | ||
345 | printk("do_040writeback1, res=%d\n",res); | ||
346 | #endif | ||
347 | |||
348 | return res; | ||
349 | } | ||
350 | |||
351 | /* after an exception in a writeback the stack frame corresponding | ||
352 | * to that exception is discarded, set a few bits in the old frame | ||
353 | * to simulate what it should look like | ||
354 | */ | ||
355 | static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs) | ||
356 | { | ||
357 | fp->un.fmt7.faddr = wba; | ||
358 | fp->un.fmt7.ssw = wbs & 0xff; | ||
359 | if (wba != current->thread.faddr) | ||
360 | fp->un.fmt7.ssw |= MA_040; | ||
361 | } | ||
362 | |||
363 | static inline void do_040writebacks(struct frame *fp) | ||
364 | { | ||
365 | int res = 0; | ||
366 | #if 0 | ||
367 | if (fp->un.fmt7.wb1s & WBV_040) | ||
368 | printk("access_error040: cannot handle 1st writeback. oops.\n"); | ||
369 | #endif | ||
370 | |||
371 | if ((fp->un.fmt7.wb2s & WBV_040) && | ||
372 | !(fp->un.fmt7.wb2s & WBTT_040)) { | ||
373 | res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, | ||
374 | fp->un.fmt7.wb2d); | ||
375 | if (res) | ||
376 | fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s); | ||
377 | else | ||
378 | fp->un.fmt7.wb2s = 0; | ||
379 | } | ||
380 | |||
381 | /* do the 2nd wb only if the first one was successful (except for a kernel wb) */ | ||
382 | if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) { | ||
383 | res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, | ||
384 | fp->un.fmt7.wb3d); | ||
385 | if (res) | ||
386 | { | ||
387 | fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s); | ||
388 | |||
389 | fp->un.fmt7.wb2s = fp->un.fmt7.wb3s; | ||
390 | fp->un.fmt7.wb3s &= (~WBV_040); | ||
391 | fp->un.fmt7.wb2a = fp->un.fmt7.wb3a; | ||
392 | fp->un.fmt7.wb2d = fp->un.fmt7.wb3d; | ||
393 | } | ||
394 | else | ||
395 | fp->un.fmt7.wb3s = 0; | ||
396 | } | ||
397 | |||
398 | if (res) | ||
399 | send_fault_sig(&fp->ptregs); | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * called from sigreturn(), must ensure userspace code didn't | ||
404 | * manipulate exception frame to circumvent protection, then complete | ||
405 | * pending writebacks | ||
406 | * we just clear TM2 to turn it into a userspace access | ||
407 | */ | ||
408 | asmlinkage void berr_040cleanup(struct frame *fp) | ||
409 | { | ||
410 | fp->un.fmt7.wb2s &= ~4; | ||
411 | fp->un.fmt7.wb3s &= ~4; | ||
412 | |||
413 | do_040writebacks(fp); | ||
414 | } | ||
415 | |||
416 | static inline void access_error040(struct frame *fp) | ||
417 | { | ||
418 | unsigned short ssw = fp->un.fmt7.ssw; | ||
419 | unsigned long mmusr; | ||
420 | |||
421 | #ifdef DEBUG | ||
422 | printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr); | ||
423 | printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s, | ||
424 | fp->un.fmt7.wb2s, fp->un.fmt7.wb3s); | ||
425 | printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n", | ||
426 | fp->un.fmt7.wb2a, fp->un.fmt7.wb3a, | ||
427 | fp->un.fmt7.wb2d, fp->un.fmt7.wb3d); | ||
428 | #endif | ||
429 | |||
430 | if (ssw & ATC_040) { | ||
431 | unsigned long addr = fp->un.fmt7.faddr; | ||
432 | unsigned long errorcode; | ||
433 | |||
434 | /* | ||
435 | * The MMU status has to be determined AFTER the address | ||
436 | * has been corrected if there was a misaligned access (MA). | ||
437 | */ | ||
438 | if (ssw & MA_040) | ||
439 | addr = (addr + 7) & -8; | ||
440 | |||
441 | /* MMU error, get the MMUSR info for this access */ | ||
442 | mmusr = probe040(!(ssw & RW_040), addr, ssw); | ||
443 | #ifdef DEBUG | ||
444 | printk("mmusr = %lx\n", mmusr); | ||
445 | #endif | ||
446 | errorcode = 1; | ||
447 | if (!(mmusr & MMU_R_040)) { | ||
448 | /* clear the invalid atc entry */ | ||
449 | __flush_tlb040_one(addr); | ||
450 | errorcode = 0; | ||
451 | } | ||
452 | |||
453 | /* despite what documentation seems to say, RMW | ||
454 | * accesses have always both the LK and RW bits set */ | ||
455 | if (!(ssw & RW_040) || (ssw & LK_040)) | ||
456 | errorcode |= 2; | ||
457 | |||
458 | if (do_page_fault(&fp->ptregs, addr, errorcode)) { | ||
459 | #ifdef DEBUG | ||
460 | printk("do_page_fault() !=0\n"); | ||
461 | #endif | ||
462 | if (user_mode(&fp->ptregs)){ | ||
463 | /* delay writebacks after signal delivery */ | ||
464 | #ifdef DEBUG | ||
465 | printk(".. was usermode - return\n"); | ||
466 | #endif | ||
467 | return; | ||
468 | } | ||
469 | /* disable writeback into user space from kernel | ||
470 | * (if do_page_fault didn't fix the mapping, | ||
471 | * the writeback won't do good) | ||
472 | */ | ||
473 | disable_wb: | ||
474 | #ifdef DEBUG | ||
475 | printk(".. disabling wb2\n"); | ||
476 | #endif | ||
477 | if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr) | ||
478 | fp->un.fmt7.wb2s &= ~WBV_040; | ||
479 | if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr) | ||
480 | fp->un.fmt7.wb3s &= ~WBV_040; | ||
481 | } | ||
482 | } else { | ||
483 | /* In case of a bus error we either kill the process or expect | ||
484 | * the kernel to catch the fault, which then is also responsible | ||
485 | * for cleaning up the mess. | ||
486 | */ | ||
487 | current->thread.signo = SIGBUS; | ||
488 | current->thread.faddr = fp->un.fmt7.faddr; | ||
489 | if (send_fault_sig(&fp->ptregs) >= 0) | ||
490 | printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw, | ||
491 | fp->un.fmt7.faddr); | ||
492 | goto disable_wb; | ||
493 | } | ||
494 | |||
495 | do_040writebacks(fp); | ||
496 | } | ||
497 | #endif /* CONFIG_M68040 */ | ||
498 | |||
499 | #if defined(CONFIG_SUN3) | ||
500 | #include <asm/sun3mmu.h> | ||
501 | |||
502 | extern int mmu_emu_handle_fault (unsigned long, int, int); | ||
503 | |||
504 | /* sun3 version of bus_error030 */ | ||
505 | |||
506 | static inline void bus_error030 (struct frame *fp) | ||
507 | { | ||
508 | unsigned char buserr_type = sun3_get_buserr (); | ||
509 | unsigned long addr, errorcode; | ||
510 | unsigned short ssw = fp->un.fmtb.ssw; | ||
511 | extern unsigned long _sun3_map_test_start, _sun3_map_test_end; | ||
512 | |||
513 | #ifdef DEBUG | ||
514 | if (ssw & (FC | FB)) | ||
515 | printk ("Instruction fault at %#010lx\n", | ||
516 | ssw & FC ? | ||
517 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 | ||
518 | : | ||
519 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); | ||
520 | if (ssw & DF) | ||
521 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
522 | ssw & RW ? "read" : "write", | ||
523 | fp->un.fmtb.daddr, | ||
524 | space_names[ssw & DFC], fp->ptregs.pc); | ||
525 | #endif | ||
526 | |||
527 | /* | ||
528 | * Check if this page should be demand-mapped. This needs to go before | ||
529 | * the testing for a bad kernel-space access (demand-mapping applies | ||
530 | * to kernel accesses too). | ||
531 | */ | ||
532 | |||
533 | if ((ssw & DF) | ||
534 | && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) { | ||
535 | if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0)) | ||
536 | return; | ||
537 | } | ||
538 | |||
539 | /* Check for kernel-space pagefault (BAD). */ | ||
540 | if (fp->ptregs.sr & PS_S) { | ||
541 | /* kernel fault must be a data fault to user space */ | ||
542 | if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) { | ||
543 | // try checking the kernel mappings before surrender | ||
544 | if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1)) | ||
545 | return; | ||
546 | /* instruction fault or kernel data fault! */ | ||
547 | if (ssw & (FC | FB)) | ||
548 | printk ("Instruction fault at %#010lx\n", | ||
549 | fp->ptregs.pc); | ||
550 | if (ssw & DF) { | ||
551 | /* was this fault incurred testing bus mappings? */ | ||
552 | if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) && | ||
553 | (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) { | ||
554 | send_fault_sig(&fp->ptregs); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
559 | ssw & RW ? "read" : "write", | ||
560 | fp->un.fmtb.daddr, | ||
561 | space_names[ssw & DFC], fp->ptregs.pc); | ||
562 | } | ||
563 | printk ("BAD KERNEL BUSERR\n"); | ||
564 | |||
565 | die_if_kernel("Oops", &fp->ptregs,0); | ||
566 | force_sig(SIGKILL, current); | ||
567 | return; | ||
568 | } | ||
569 | } else { | ||
570 | /* user fault */ | ||
571 | if (!(ssw & (FC | FB)) && !(ssw & DF)) | ||
572 | /* not an instruction fault or data fault! BAD */ | ||
573 | panic ("USER BUSERR w/o instruction or data fault"); | ||
574 | } | ||
575 | |||
576 | |||
577 | /* First handle the data fault, if any. */ | ||
578 | if (ssw & DF) { | ||
579 | addr = fp->un.fmtb.daddr; | ||
580 | |||
581 | // errorcode bit 0: 0 -> no page 1 -> protection fault | ||
582 | // errorcode bit 1: 0 -> read fault 1 -> write fault | ||
583 | |||
584 | // (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault | ||
585 | // (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault | ||
586 | |||
587 | if (buserr_type & SUN3_BUSERR_PROTERR) | ||
588 | errorcode = 0x01; | ||
589 | else if (buserr_type & SUN3_BUSERR_INVALID) | ||
590 | errorcode = 0x00; | ||
591 | else { | ||
592 | #ifdef DEBUG | ||
593 | printk ("*** unexpected busfault type=%#04x\n", buserr_type); | ||
594 | printk ("invalid %s access at %#lx from pc %#lx\n", | ||
595 | !(ssw & RW) ? "write" : "read", addr, | ||
596 | fp->ptregs.pc); | ||
597 | #endif | ||
598 | die_if_kernel ("Oops", &fp->ptregs, buserr_type); | ||
599 | force_sig (SIGBUS, current); | ||
600 | return; | ||
601 | } | ||
602 | |||
603 | //todo: wtf is RM bit? --m | ||
604 | if (!(ssw & RW) || ssw & RM) | ||
605 | errorcode |= 0x02; | ||
606 | |||
607 | /* Handle page fault. */ | ||
608 | do_page_fault (&fp->ptregs, addr, errorcode); | ||
609 | |||
610 | /* Retry the data fault now. */ | ||
611 | return; | ||
612 | } | ||
613 | |||
614 | /* Now handle the instruction fault. */ | ||
615 | |||
616 | /* Get the fault address. */ | ||
617 | if (fp->ptregs.format == 0xA) | ||
618 | addr = fp->ptregs.pc + 4; | ||
619 | else | ||
620 | addr = fp->un.fmtb.baddr; | ||
621 | if (ssw & FC) | ||
622 | addr -= 2; | ||
623 | |||
624 | if (buserr_type & SUN3_BUSERR_INVALID) { | ||
625 | if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0)) | ||
626 | do_page_fault (&fp->ptregs, addr, 0); | ||
627 | } else { | ||
628 | #ifdef DEBUG | ||
629 | printk ("protection fault on insn access (segv).\n"); | ||
630 | #endif | ||
631 | force_sig (SIGSEGV, current); | ||
632 | } | ||
633 | } | ||
634 | #else | ||
635 | #if defined(CPU_M68020_OR_M68030) | ||
636 | static inline void bus_error030 (struct frame *fp) | ||
637 | { | ||
638 | volatile unsigned short temp; | ||
639 | unsigned short mmusr; | ||
640 | unsigned long addr, errorcode; | ||
641 | unsigned short ssw = fp->un.fmtb.ssw; | ||
642 | #ifdef DEBUG | ||
643 | unsigned long desc; | ||
644 | |||
645 | printk ("pid = %x ", current->pid); | ||
646 | printk ("SSW=%#06x ", ssw); | ||
647 | |||
648 | if (ssw & (FC | FB)) | ||
649 | printk ("Instruction fault at %#010lx\n", | ||
650 | ssw & FC ? | ||
651 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 | ||
652 | : | ||
653 | fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); | ||
654 | if (ssw & DF) | ||
655 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
656 | ssw & RW ? "read" : "write", | ||
657 | fp->un.fmtb.daddr, | ||
658 | space_names[ssw & DFC], fp->ptregs.pc); | ||
659 | #endif | ||
660 | |||
661 | /* ++andreas: If a data fault and an instruction fault happen | ||
662 | at the same time map in both pages. */ | ||
663 | |||
664 | /* First handle the data fault, if any. */ | ||
665 | if (ssw & DF) { | ||
666 | addr = fp->un.fmtb.daddr; | ||
667 | |||
668 | #ifdef DEBUG | ||
669 | asm volatile ("ptestr %3,%2@,#7,%0\n\t" | ||
670 | "pmove %%psr,%1@" | ||
671 | : "=a&" (desc) | ||
672 | : "a" (&temp), "a" (addr), "d" (ssw)); | ||
673 | #else | ||
674 | asm volatile ("ptestr %2,%1@,#7\n\t" | ||
675 | "pmove %%psr,%0@" | ||
676 | : : "a" (&temp), "a" (addr), "d" (ssw)); | ||
677 | #endif | ||
678 | mmusr = temp; | ||
679 | |||
680 | #ifdef DEBUG | ||
681 | printk("mmusr is %#x for addr %#lx in task %p\n", | ||
682 | mmusr, addr, current); | ||
683 | printk("descriptor address is %#lx, contents %#lx\n", | ||
684 | __va(desc), *(unsigned long *)__va(desc)); | ||
685 | #endif | ||
686 | |||
687 | errorcode = (mmusr & MMU_I) ? 0 : 1; | ||
688 | if (!(ssw & RW) || (ssw & RM)) | ||
689 | errorcode |= 2; | ||
690 | |||
691 | if (mmusr & (MMU_I | MMU_WP)) { | ||
692 | if (ssw & 4) { | ||
693 | printk("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
694 | ssw & RW ? "read" : "write", | ||
695 | fp->un.fmtb.daddr, | ||
696 | space_names[ssw & DFC], fp->ptregs.pc); | ||
697 | goto buserr; | ||
698 | } | ||
699 | /* Don't try to do anything further if an exception was | ||
700 | handled. */ | ||
701 | if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) | ||
702 | return; | ||
703 | } else if (!(mmusr & MMU_I)) { | ||
704 | /* probably a 020 cas fault */ | ||
705 | if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0) | ||
706 | printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr); | ||
707 | } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { | ||
708 | printk("invalid %s access at %#lx from pc %#lx\n", | ||
709 | !(ssw & RW) ? "write" : "read", addr, | ||
710 | fp->ptregs.pc); | ||
711 | die_if_kernel("Oops",&fp->ptregs,mmusr); | ||
712 | force_sig(SIGSEGV, current); | ||
713 | return; | ||
714 | } else { | ||
715 | #if 0 | ||
716 | static volatile long tlong; | ||
717 | #endif | ||
718 | |||
719 | printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", | ||
720 | !(ssw & RW) ? "write" : "read", addr, | ||
721 | fp->ptregs.pc, ssw); | ||
722 | asm volatile ("ptestr #1,%1@,#0\n\t" | ||
723 | "pmove %%psr,%0@" | ||
724 | : /* no outputs */ | ||
725 | : "a" (&temp), "a" (addr)); | ||
726 | mmusr = temp; | ||
727 | |||
728 | printk ("level 0 mmusr is %#x\n", mmusr); | ||
729 | #if 0 | ||
730 | asm volatile ("pmove %%tt0,%0@" | ||
731 | : /* no outputs */ | ||
732 | : "a" (&tlong)); | ||
733 | printk("tt0 is %#lx, ", tlong); | ||
734 | asm volatile ("pmove %%tt1,%0@" | ||
735 | : /* no outputs */ | ||
736 | : "a" (&tlong)); | ||
737 | printk("tt1 is %#lx\n", tlong); | ||
738 | #endif | ||
739 | #ifdef DEBUG | ||
740 | printk("Unknown SIGSEGV - 1\n"); | ||
741 | #endif | ||
742 | die_if_kernel("Oops",&fp->ptregs,mmusr); | ||
743 | force_sig(SIGSEGV, current); | ||
744 | return; | ||
745 | } | ||
746 | |||
747 | /* setup an ATC entry for the access about to be retried */ | ||
748 | if (!(ssw & RW) || (ssw & RM)) | ||
749 | asm volatile ("ploadw %1,%0@" : /* no outputs */ | ||
750 | : "a" (addr), "d" (ssw)); | ||
751 | else | ||
752 | asm volatile ("ploadr %1,%0@" : /* no outputs */ | ||
753 | : "a" (addr), "d" (ssw)); | ||
754 | } | ||
755 | |||
756 | /* Now handle the instruction fault. */ | ||
757 | |||
758 | if (!(ssw & (FC|FB))) | ||
759 | return; | ||
760 | |||
761 | if (fp->ptregs.sr & PS_S) { | ||
762 | printk("Instruction fault at %#010lx\n", | ||
763 | fp->ptregs.pc); | ||
764 | buserr: | ||
765 | printk ("BAD KERNEL BUSERR\n"); | ||
766 | die_if_kernel("Oops",&fp->ptregs,0); | ||
767 | force_sig(SIGKILL, current); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | /* get the fault address */ | ||
772 | if (fp->ptregs.format == 10) | ||
773 | addr = fp->ptregs.pc + 4; | ||
774 | else | ||
775 | addr = fp->un.fmtb.baddr; | ||
776 | if (ssw & FC) | ||
777 | addr -= 2; | ||
778 | |||
779 | if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0) | ||
780 | /* Insn fault on same page as data fault. But we | ||
781 | should still create the ATC entry. */ | ||
782 | goto create_atc_entry; | ||
783 | |||
784 | #ifdef DEBUG | ||
785 | asm volatile ("ptestr #1,%2@,#7,%0\n\t" | ||
786 | "pmove %%psr,%1@" | ||
787 | : "=a&" (desc) | ||
788 | : "a" (&temp), "a" (addr)); | ||
789 | #else | ||
790 | asm volatile ("ptestr #1,%1@,#7\n\t" | ||
791 | "pmove %%psr,%0@" | ||
792 | : : "a" (&temp), "a" (addr)); | ||
793 | #endif | ||
794 | mmusr = temp; | ||
795 | |||
796 | #ifdef DEBUG | ||
797 | printk ("mmusr is %#x for addr %#lx in task %p\n", | ||
798 | mmusr, addr, current); | ||
799 | printk ("descriptor address is %#lx, contents %#lx\n", | ||
800 | __va(desc), *(unsigned long *)__va(desc)); | ||
801 | #endif | ||
802 | |||
803 | if (mmusr & MMU_I) | ||
804 | do_page_fault (&fp->ptregs, addr, 0); | ||
805 | else if (mmusr & (MMU_B|MMU_L|MMU_S)) { | ||
806 | printk ("invalid insn access at %#lx from pc %#lx\n", | ||
807 | addr, fp->ptregs.pc); | ||
808 | #ifdef DEBUG | ||
809 | printk("Unknown SIGSEGV - 2\n"); | ||
810 | #endif | ||
811 | die_if_kernel("Oops",&fp->ptregs,mmusr); | ||
812 | force_sig(SIGSEGV, current); | ||
813 | return; | ||
814 | } | ||
815 | |||
816 | create_atc_entry: | ||
817 | /* setup an ATC entry for the access about to be retried */ | ||
818 | asm volatile ("ploadr #2,%0@" : /* no outputs */ | ||
819 | : "a" (addr)); | ||
820 | } | ||
821 | #endif /* CPU_M68020_OR_M68030 */ | ||
822 | #endif /* !CONFIG_SUN3 */ | ||
823 | |||
824 | asmlinkage void buserr_c(struct frame *fp) | ||
825 | { | ||
826 | /* Only set esp0 if coming from user mode */ | ||
827 | if (user_mode(&fp->ptregs)) | ||
828 | current->thread.esp0 = (unsigned long) fp; | ||
829 | |||
830 | #ifdef DEBUG | ||
831 | printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format); | ||
832 | #endif | ||
833 | |||
834 | switch (fp->ptregs.format) { | ||
835 | #if defined (CONFIG_M68060) | ||
836 | case 4: /* 68060 access error */ | ||
837 | access_error060 (fp); | ||
838 | break; | ||
839 | #endif | ||
840 | #if defined (CONFIG_M68040) | ||
841 | case 0x7: /* 68040 access error */ | ||
842 | access_error040 (fp); | ||
843 | break; | ||
844 | #endif | ||
845 | #if defined (CPU_M68020_OR_M68030) | ||
846 | case 0xa: | ||
847 | case 0xb: | ||
848 | bus_error030 (fp); | ||
849 | break; | ||
850 | #endif | ||
851 | default: | ||
852 | die_if_kernel("bad frame format",&fp->ptregs,0); | ||
853 | #ifdef DEBUG | ||
854 | printk("Unknown SIGSEGV - 4\n"); | ||
855 | #endif | ||
856 | force_sig(SIGSEGV, current); | ||
857 | } | ||
858 | } | ||
859 | |||
860 | |||
861 | static int kstack_depth_to_print = 48; | ||
862 | |||
863 | void show_trace(unsigned long *stack) | ||
864 | { | ||
865 | unsigned long *endstack; | ||
866 | unsigned long addr; | ||
867 | int i; | ||
868 | |||
869 | printk("Call Trace:"); | ||
870 | addr = (unsigned long)stack + THREAD_SIZE - 1; | ||
871 | endstack = (unsigned long *)(addr & -THREAD_SIZE); | ||
872 | i = 0; | ||
873 | while (stack + 1 <= endstack) { | ||
874 | addr = *stack++; | ||
875 | /* | ||
876 | * If the address is either in the text segment of the | ||
877 | * kernel, or in the region which contains vmalloc'ed | ||
878 | * memory, it *may* be the address of a calling | ||
879 | * routine; if so, print it so that someone tracing | ||
880 | * down the cause of the crash will be able to figure | ||
881 | * out the call path that was taken. | ||
882 | */ | ||
883 | if (__kernel_text_address(addr)) { | ||
884 | #ifndef CONFIG_KALLSYMS | ||
885 | if (i % 5 == 0) | ||
886 | printk("\n "); | ||
887 | #endif | ||
888 | printk(" [<%08lx>] %pS\n", addr, (void *)addr); | ||
889 | i++; | ||
890 | } | ||
891 | } | ||
892 | printk("\n"); | ||
893 | } | ||
894 | |||
895 | void show_registers(struct pt_regs *regs) | ||
896 | { | ||
897 | struct frame *fp = (struct frame *)regs; | ||
898 | mm_segment_t old_fs = get_fs(); | ||
899 | u16 c, *cp; | ||
900 | unsigned long addr; | ||
901 | int i; | ||
902 | |||
903 | print_modules(); | ||
904 | printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc); | ||
905 | printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2); | ||
906 | printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", | ||
907 | regs->d0, regs->d1, regs->d2, regs->d3); | ||
908 | printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", | ||
909 | regs->d4, regs->d5, regs->a0, regs->a1); | ||
910 | |||
911 | printk("Process %s (pid: %d, task=%p)\n", | ||
912 | current->comm, task_pid_nr(current), current); | ||
913 | addr = (unsigned long)&fp->un; | ||
914 | printk("Frame format=%X ", regs->format); | ||
915 | switch (regs->format) { | ||
916 | case 0x2: | ||
917 | printk("instr addr=%08lx\n", fp->un.fmt2.iaddr); | ||
918 | addr += sizeof(fp->un.fmt2); | ||
919 | break; | ||
920 | case 0x3: | ||
921 | printk("eff addr=%08lx\n", fp->un.fmt3.effaddr); | ||
922 | addr += sizeof(fp->un.fmt3); | ||
923 | break; | ||
924 | case 0x4: | ||
925 | printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n" | ||
926 | : "eff addr=%08lx pc=%08lx\n"), | ||
927 | fp->un.fmt4.effaddr, fp->un.fmt4.pc); | ||
928 | addr += sizeof(fp->un.fmt4); | ||
929 | break; | ||
930 | case 0x7: | ||
931 | printk("eff addr=%08lx ssw=%04x faddr=%08lx\n", | ||
932 | fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr); | ||
933 | printk("wb 1 stat/addr/data: %04x %08lx %08lx\n", | ||
934 | fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0); | ||
935 | printk("wb 2 stat/addr/data: %04x %08lx %08lx\n", | ||
936 | fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); | ||
937 | printk("wb 3 stat/addr/data: %04x %08lx %08lx\n", | ||
938 | fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); | ||
939 | printk("push data: %08lx %08lx %08lx %08lx\n", | ||
940 | fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2, | ||
941 | fp->un.fmt7.pd3); | ||
942 | addr += sizeof(fp->un.fmt7); | ||
943 | break; | ||
944 | case 0x9: | ||
945 | printk("instr addr=%08lx\n", fp->un.fmt9.iaddr); | ||
946 | addr += sizeof(fp->un.fmt9); | ||
947 | break; | ||
948 | case 0xa: | ||
949 | printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", | ||
950 | fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb, | ||
951 | fp->un.fmta.daddr, fp->un.fmta.dobuf); | ||
952 | addr += sizeof(fp->un.fmta); | ||
953 | break; | ||
954 | case 0xb: | ||
955 | printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", | ||
956 | fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb, | ||
957 | fp->un.fmtb.daddr, fp->un.fmtb.dobuf); | ||
958 | printk("baddr=%08lx dibuf=%08lx ver=%x\n", | ||
959 | fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver); | ||
960 | addr += sizeof(fp->un.fmtb); | ||
961 | break; | ||
962 | default: | ||
963 | printk("\n"); | ||
964 | } | ||
965 | show_stack(NULL, (unsigned long *)addr); | ||
966 | |||
967 | printk("Code:"); | ||
968 | set_fs(KERNEL_DS); | ||
969 | cp = (u16 *)regs->pc; | ||
970 | for (i = -8; i < 16; i++) { | ||
971 | if (get_user(c, cp + i) && i >= 0) { | ||
972 | printk(" Bad PC value."); | ||
973 | break; | ||
974 | } | ||
975 | printk(i ? " %04x" : " <%04x>", c); | ||
976 | } | ||
977 | set_fs(old_fs); | ||
978 | printk ("\n"); | ||
979 | } | ||
980 | |||
981 | void show_stack(struct task_struct *task, unsigned long *stack) | ||
982 | { | ||
983 | unsigned long *p; | ||
984 | unsigned long *endstack; | ||
985 | int i; | ||
986 | |||
987 | if (!stack) { | ||
988 | if (task) | ||
989 | stack = (unsigned long *)task->thread.esp0; | ||
990 | else | ||
991 | stack = (unsigned long *)&stack; | ||
992 | } | ||
993 | endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); | ||
994 | |||
995 | printk("Stack from %08lx:", (unsigned long)stack); | ||
996 | p = stack; | ||
997 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
998 | if (p + 1 > endstack) | ||
999 | break; | ||
1000 | if (i % 8 == 0) | ||
1001 | printk("\n "); | ||
1002 | printk(" %08lx", *p++); | ||
1003 | } | ||
1004 | printk("\n"); | ||
1005 | show_trace(stack); | ||
1006 | } | ||
1007 | |||
1008 | /* | ||
1009 | * The architecture-independent backtrace generator | ||
1010 | */ | ||
1011 | void dump_stack(void) | ||
1012 | { | ||
1013 | unsigned long stack; | ||
1014 | |||
1015 | show_trace(&stack); | ||
1016 | } | ||
1017 | |||
1018 | EXPORT_SYMBOL(dump_stack); | ||
1019 | |||
1020 | void bad_super_trap (struct frame *fp) | ||
1021 | { | ||
1022 | console_verbose(); | ||
1023 | if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names)) | ||
1024 | printk ("*** %s *** FORMAT=%X\n", | ||
1025 | vec_names[(fp->ptregs.vector) >> 2], | ||
1026 | fp->ptregs.format); | ||
1027 | else | ||
1028 | printk ("*** Exception %d *** FORMAT=%X\n", | ||
1029 | (fp->ptregs.vector) >> 2, | ||
1030 | fp->ptregs.format); | ||
1031 | if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) { | ||
1032 | unsigned short ssw = fp->un.fmtb.ssw; | ||
1033 | |||
1034 | printk ("SSW=%#06x ", ssw); | ||
1035 | |||
1036 | if (ssw & RC) | ||
1037 | printk ("Pipe stage C instruction fault at %#010lx\n", | ||
1038 | (fp->ptregs.format) == 0xA ? | ||
1039 | fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2); | ||
1040 | if (ssw & RB) | ||
1041 | printk ("Pipe stage B instruction fault at %#010lx\n", | ||
1042 | (fp->ptregs.format) == 0xA ? | ||
1043 | fp->ptregs.pc + 4 : fp->un.fmtb.baddr); | ||
1044 | if (ssw & DF) | ||
1045 | printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", | ||
1046 | ssw & RW ? "read" : "write", | ||
1047 | fp->un.fmtb.daddr, space_names[ssw & DFC], | ||
1048 | fp->ptregs.pc); | ||
1049 | } | ||
1050 | printk ("Current process id is %d\n", task_pid_nr(current)); | ||
1051 | die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); | ||
1052 | } | ||
1053 | |||
1054 | asmlinkage void trap_c(struct frame *fp) | ||
1055 | { | ||
1056 | int sig; | ||
1057 | siginfo_t info; | ||
1058 | |||
1059 | if (fp->ptregs.sr & PS_S) { | ||
1060 | if (fp->ptregs.vector == VEC_TRACE << 2) { | ||
1061 | /* traced a trapping instruction on a 68020/30, | ||
1062 | * real exception will be executed afterwards. | ||
1063 | */ | ||
1064 | } else if (!handle_kernel_fault(&fp->ptregs)) | ||
1065 | bad_super_trap(fp); | ||
1066 | return; | ||
1067 | } | ||
1068 | |||
1069 | /* send the appropriate signal to the user program */ | ||
1070 | switch ((fp->ptregs.vector) >> 2) { | ||
1071 | case VEC_ADDRERR: | ||
1072 | info.si_code = BUS_ADRALN; | ||
1073 | sig = SIGBUS; | ||
1074 | break; | ||
1075 | case VEC_ILLEGAL: | ||
1076 | case VEC_LINE10: | ||
1077 | case VEC_LINE11: | ||
1078 | info.si_code = ILL_ILLOPC; | ||
1079 | sig = SIGILL; | ||
1080 | break; | ||
1081 | case VEC_PRIV: | ||
1082 | info.si_code = ILL_PRVOPC; | ||
1083 | sig = SIGILL; | ||
1084 | break; | ||
1085 | case VEC_COPROC: | ||
1086 | info.si_code = ILL_COPROC; | ||
1087 | sig = SIGILL; | ||
1088 | break; | ||
1089 | case VEC_TRAP1: | ||
1090 | case VEC_TRAP2: | ||
1091 | case VEC_TRAP3: | ||
1092 | case VEC_TRAP4: | ||
1093 | case VEC_TRAP5: | ||
1094 | case VEC_TRAP6: | ||
1095 | case VEC_TRAP7: | ||
1096 | case VEC_TRAP8: | ||
1097 | case VEC_TRAP9: | ||
1098 | case VEC_TRAP10: | ||
1099 | case VEC_TRAP11: | ||
1100 | case VEC_TRAP12: | ||
1101 | case VEC_TRAP13: | ||
1102 | case VEC_TRAP14: | ||
1103 | info.si_code = ILL_ILLTRP; | ||
1104 | sig = SIGILL; | ||
1105 | break; | ||
1106 | case VEC_FPBRUC: | ||
1107 | case VEC_FPOE: | ||
1108 | case VEC_FPNAN: | ||
1109 | info.si_code = FPE_FLTINV; | ||
1110 | sig = SIGFPE; | ||
1111 | break; | ||
1112 | case VEC_FPIR: | ||
1113 | info.si_code = FPE_FLTRES; | ||
1114 | sig = SIGFPE; | ||
1115 | break; | ||
1116 | case VEC_FPDIVZ: | ||
1117 | info.si_code = FPE_FLTDIV; | ||
1118 | sig = SIGFPE; | ||
1119 | break; | ||
1120 | case VEC_FPUNDER: | ||
1121 | info.si_code = FPE_FLTUND; | ||
1122 | sig = SIGFPE; | ||
1123 | break; | ||
1124 | case VEC_FPOVER: | ||
1125 | info.si_code = FPE_FLTOVF; | ||
1126 | sig = SIGFPE; | ||
1127 | break; | ||
1128 | case VEC_ZERODIV: | ||
1129 | info.si_code = FPE_INTDIV; | ||
1130 | sig = SIGFPE; | ||
1131 | break; | ||
1132 | case VEC_CHK: | ||
1133 | case VEC_TRAP: | ||
1134 | info.si_code = FPE_INTOVF; | ||
1135 | sig = SIGFPE; | ||
1136 | break; | ||
1137 | case VEC_TRACE: /* ptrace single step */ | ||
1138 | info.si_code = TRAP_TRACE; | ||
1139 | sig = SIGTRAP; | ||
1140 | break; | ||
1141 | case VEC_TRAP15: /* breakpoint */ | ||
1142 | info.si_code = TRAP_BRKPT; | ||
1143 | sig = SIGTRAP; | ||
1144 | break; | ||
1145 | default: | ||
1146 | info.si_code = ILL_ILLOPC; | ||
1147 | sig = SIGILL; | ||
1148 | break; | ||
1149 | } | ||
1150 | info.si_signo = sig; | ||
1151 | info.si_errno = 0; | ||
1152 | switch (fp->ptregs.format) { | ||
1153 | default: | ||
1154 | info.si_addr = (void *) fp->ptregs.pc; | ||
1155 | break; | ||
1156 | case 2: | ||
1157 | info.si_addr = (void *) fp->un.fmt2.iaddr; | ||
1158 | break; | ||
1159 | case 7: | ||
1160 | info.si_addr = (void *) fp->un.fmt7.effaddr; | ||
1161 | break; | ||
1162 | case 9: | ||
1163 | info.si_addr = (void *) fp->un.fmt9.iaddr; | ||
1164 | break; | ||
1165 | case 10: | ||
1166 | info.si_addr = (void *) fp->un.fmta.daddr; | ||
1167 | break; | ||
1168 | case 11: | ||
1169 | info.si_addr = (void *) fp->un.fmtb.daddr; | ||
1170 | break; | ||
1171 | } | ||
1172 | force_sig_info (sig, &info, current); | ||
1173 | } | ||
1174 | |||
1175 | void die_if_kernel (char *str, struct pt_regs *fp, int nr) | ||
1176 | { | ||
1177 | if (!(fp->sr & PS_S)) | ||
1178 | return; | ||
1179 | |||
1180 | console_verbose(); | ||
1181 | printk("%s: %08x\n",str,nr); | ||
1182 | show_registers(fp); | ||
1183 | add_taint(TAINT_DIE); | ||
1184 | do_exit(SIGSEGV); | ||
1185 | } | ||
1186 | |||
1187 | /* | ||
1188 | * This function is called if an error occur while accessing | ||
1189 | * user-space from the fpsp040 code. | ||
1190 | */ | ||
1191 | asmlinkage void fpsp040_die(void) | ||
1192 | { | ||
1193 | do_exit(SIGSEGV); | ||
1194 | } | ||
1195 | |||
1196 | #ifdef CONFIG_M68KFPU_EMU | ||
1197 | asmlinkage void fpemu_signal(int signal, int code, void *addr) | ||
1198 | { | ||
1199 | siginfo_t info; | ||
1200 | |||
1201 | info.si_signo = signal; | ||
1202 | info.si_errno = 0; | ||
1203 | info.si_code = code; | ||
1204 | info.si_addr = addr; | ||
1205 | force_sig_info(signal, &info, current); | ||
1206 | } | ||
1207 | #endif | ||
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68k/kernel/traps_no.c index a768008dfd06..a768008dfd06 100644 --- a/arch/m68knommu/kernel/traps.c +++ b/arch/m68k/kernel/traps_no.c | |||
diff --git a/arch/m68k/kernel/vmlinux.lds.S b/arch/m68k/kernel/vmlinux.lds.S index 99ba315bd0a8..030dabf0bc53 100644 --- a/arch/m68k/kernel/vmlinux.lds.S +++ b/arch/m68k/kernel/vmlinux.lds.S | |||
@@ -1,10 +1,5 @@ | |||
1 | PHDRS | 1 | #ifdef CONFIG_MMU |
2 | { | 2 | #include "vmlinux.lds_mm.S" |
3 | text PT_LOAD FILEHDR PHDRS FLAGS (7); | ||
4 | data PT_LOAD FLAGS (7); | ||
5 | } | ||
6 | #ifdef CONFIG_SUN3 | ||
7 | #include "vmlinux-sun3.lds" | ||
8 | #else | 3 | #else |
9 | #include "vmlinux-std.lds" | 4 | #include "vmlinux.lds_no.S" |
10 | #endif | 5 | #endif |
diff --git a/arch/m68k/kernel/vmlinux.lds_mm.S b/arch/m68k/kernel/vmlinux.lds_mm.S new file mode 100644 index 000000000000..99ba315bd0a8 --- /dev/null +++ b/arch/m68k/kernel/vmlinux.lds_mm.S | |||
@@ -0,0 +1,10 @@ | |||
1 | PHDRS | ||
2 | { | ||
3 | text PT_LOAD FILEHDR PHDRS FLAGS (7); | ||
4 | data PT_LOAD FLAGS (7); | ||
5 | } | ||
6 | #ifdef CONFIG_SUN3 | ||
7 | #include "vmlinux-sun3.lds" | ||
8 | #else | ||
9 | #include "vmlinux-std.lds" | ||
10 | #endif | ||
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68k/kernel/vmlinux.lds_no.S index 47e15ebfd893..47e15ebfd893 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68k/kernel/vmlinux.lds_no.S | |||
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index af9abf8d9d98..1f95881d8437 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile | |||
@@ -1,6 +1,5 @@ | |||
1 | # | 1 | ifdef CONFIG_MMU |
2 | # Makefile for m68k-specific library files.. | 2 | include arch/m68k/lib/Makefile_mm |
3 | # | 3 | else |
4 | 4 | include arch/m68k/lib/Makefile_no | |
5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ | 5 | endif |
6 | checksum.o string.o uaccess.o | ||
diff --git a/arch/m68k/lib/Makefile_mm b/arch/m68k/lib/Makefile_mm new file mode 100644 index 000000000000..af9abf8d9d98 --- /dev/null +++ b/arch/m68k/lib/Makefile_mm | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile for m68k-specific library files.. | ||
3 | # | ||
4 | |||
5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ | ||
6 | checksum.o string.o uaccess.o | ||
diff --git a/arch/m68knommu/lib/Makefile b/arch/m68k/lib/Makefile_no index 32d852e586d7..32d852e586d7 100644 --- a/arch/m68knommu/lib/Makefile +++ b/arch/m68k/lib/Makefile_no | |||
diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c index 6216f12a756b..1297536060de 100644 --- a/arch/m68k/lib/checksum.c +++ b/arch/m68k/lib/checksum.c | |||
@@ -1,425 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | 2 | #include "checksum_mm.c" |
3 | * operating system. INET is implemented using the BSD Socket | 3 | #else |
4 | * interface as the means of communication with the user level. | 4 | #include "checksum_no.c" |
5 | * | 5 | #endif |
6 | * IP/TCP/UDP checksumming routines | ||
7 | * | ||
8 | * Authors: Jorge Cwik, <jorge@laser.satlink.net> | ||
9 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | ||
10 | * Tom May, <ftom@netcom.com> | ||
11 | * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> | ||
12 | * Lots of code moved from tcp.c and ip.c; see those files | ||
13 | * for more names. | ||
14 | * | ||
15 | * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: | ||
16 | * Fixed some nasty bugs, causing some horrible crashes. | ||
17 | * A: At some points, the sum (%0) was used as | ||
18 | * length-counter instead of the length counter | ||
19 | * (%1). Thanks to Roman Hodek for pointing this out. | ||
20 | * B: GCC seems to mess up if one uses too many | ||
21 | * data-registers to hold input values and one tries to | ||
22 | * specify d0 and d1 as scratch registers. Letting gcc | ||
23 | * choose these registers itself solves the problem. | ||
24 | * | ||
25 | * This program is free software; you can redistribute it and/or | ||
26 | * modify it under the terms of the GNU General Public License | ||
27 | * as published by the Free Software Foundation; either version | ||
28 | * 2 of the License, or (at your option) any later version. | ||
29 | * | ||
30 | * 1998/8/31 Andreas Schwab: | ||
31 | * Zero out rest of buffer on exception in | ||
32 | * csum_partial_copy_from_user. | ||
33 | */ | ||
34 | |||
35 | #include <linux/module.h> | ||
36 | #include <net/checksum.h> | ||
37 | |||
38 | /* | ||
39 | * computes a partial checksum, e.g. for TCP/UDP fragments | ||
40 | */ | ||
41 | |||
42 | __wsum csum_partial(const void *buff, int len, __wsum sum) | ||
43 | { | ||
44 | unsigned long tmp1, tmp2; | ||
45 | /* | ||
46 | * Experiments with ethernet and slip connections show that buff | ||
47 | * is aligned on either a 2-byte or 4-byte boundary. | ||
48 | */ | ||
49 | __asm__("movel %2,%3\n\t" | ||
50 | "btst #1,%3\n\t" /* Check alignment */ | ||
51 | "jeq 2f\n\t" | ||
52 | "subql #2,%1\n\t" /* buff%4==2: treat first word */ | ||
53 | "jgt 1f\n\t" | ||
54 | "addql #2,%1\n\t" /* len was == 2, treat only rest */ | ||
55 | "jra 4f\n" | ||
56 | "1:\t" | ||
57 | "addw %2@+,%0\n\t" /* add first word to sum */ | ||
58 | "clrl %3\n\t" | ||
59 | "addxl %3,%0\n" /* add X bit */ | ||
60 | "2:\t" | ||
61 | /* unrolled loop for the main part: do 8 longs at once */ | ||
62 | "movel %1,%3\n\t" /* save len in tmp1 */ | ||
63 | "lsrl #5,%1\n\t" /* len/32 */ | ||
64 | "jeq 2f\n\t" /* not enough... */ | ||
65 | "subql #1,%1\n" | ||
66 | "1:\t" | ||
67 | "movel %2@+,%4\n\t" | ||
68 | "addxl %4,%0\n\t" | ||
69 | "movel %2@+,%4\n\t" | ||
70 | "addxl %4,%0\n\t" | ||
71 | "movel %2@+,%4\n\t" | ||
72 | "addxl %4,%0\n\t" | ||
73 | "movel %2@+,%4\n\t" | ||
74 | "addxl %4,%0\n\t" | ||
75 | "movel %2@+,%4\n\t" | ||
76 | "addxl %4,%0\n\t" | ||
77 | "movel %2@+,%4\n\t" | ||
78 | "addxl %4,%0\n\t" | ||
79 | "movel %2@+,%4\n\t" | ||
80 | "addxl %4,%0\n\t" | ||
81 | "movel %2@+,%4\n\t" | ||
82 | "addxl %4,%0\n\t" | ||
83 | "dbra %1,1b\n\t" | ||
84 | "clrl %4\n\t" | ||
85 | "addxl %4,%0\n\t" /* add X bit */ | ||
86 | "clrw %1\n\t" | ||
87 | "subql #1,%1\n\t" | ||
88 | "jcc 1b\n" | ||
89 | "2:\t" | ||
90 | "movel %3,%1\n\t" /* restore len from tmp1 */ | ||
91 | "andw #0x1c,%3\n\t" /* number of rest longs */ | ||
92 | "jeq 4f\n\t" | ||
93 | "lsrw #2,%3\n\t" | ||
94 | "subqw #1,%3\n" | ||
95 | "3:\t" | ||
96 | /* loop for rest longs */ | ||
97 | "movel %2@+,%4\n\t" | ||
98 | "addxl %4,%0\n\t" | ||
99 | "dbra %3,3b\n\t" | ||
100 | "clrl %4\n\t" | ||
101 | "addxl %4,%0\n" /* add X bit */ | ||
102 | "4:\t" | ||
103 | /* now check for rest bytes that do not fit into longs */ | ||
104 | "andw #3,%1\n\t" | ||
105 | "jeq 7f\n\t" | ||
106 | "clrl %4\n\t" /* clear tmp2 for rest bytes */ | ||
107 | "subqw #2,%1\n\t" | ||
108 | "jlt 5f\n\t" | ||
109 | "movew %2@+,%4\n\t" /* have rest >= 2: get word */ | ||
110 | "swap %4\n\t" /* into bits 16..31 */ | ||
111 | "tstw %1\n\t" /* another byte? */ | ||
112 | "jeq 6f\n" | ||
113 | "5:\t" | ||
114 | "moveb %2@,%4\n\t" /* have odd rest: get byte */ | ||
115 | "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ | ||
116 | "6:\t" | ||
117 | "addl %4,%0\n\t" /* now add rest long to sum */ | ||
118 | "clrl %4\n\t" | ||
119 | "addxl %4,%0\n" /* add X bit */ | ||
120 | "7:\t" | ||
121 | : "=d" (sum), "=d" (len), "=a" (buff), | ||
122 | "=&d" (tmp1), "=&d" (tmp2) | ||
123 | : "0" (sum), "1" (len), "2" (buff) | ||
124 | ); | ||
125 | return(sum); | ||
126 | } | ||
127 | |||
128 | EXPORT_SYMBOL(csum_partial); | ||
129 | |||
130 | |||
131 | /* | ||
132 | * copy from user space while checksumming, with exception handling. | ||
133 | */ | ||
134 | |||
135 | __wsum | ||
136 | csum_partial_copy_from_user(const void __user *src, void *dst, | ||
137 | int len, __wsum sum, int *csum_err) | ||
138 | { | ||
139 | /* | ||
140 | * GCC doesn't like more than 10 operands for the asm | ||
141 | * statements so we have to use tmp2 for the error | ||
142 | * code. | ||
143 | */ | ||
144 | unsigned long tmp1, tmp2; | ||
145 | |||
146 | __asm__("movel %2,%4\n\t" | ||
147 | "btst #1,%4\n\t" /* Check alignment */ | ||
148 | "jeq 2f\n\t" | ||
149 | "subql #2,%1\n\t" /* buff%4==2: treat first word */ | ||
150 | "jgt 1f\n\t" | ||
151 | "addql #2,%1\n\t" /* len was == 2, treat only rest */ | ||
152 | "jra 4f\n" | ||
153 | "1:\n" | ||
154 | "10:\t" | ||
155 | "movesw %2@+,%4\n\t" /* add first word to sum */ | ||
156 | "addw %4,%0\n\t" | ||
157 | "movew %4,%3@+\n\t" | ||
158 | "clrl %4\n\t" | ||
159 | "addxl %4,%0\n" /* add X bit */ | ||
160 | "2:\t" | ||
161 | /* unrolled loop for the main part: do 8 longs at once */ | ||
162 | "movel %1,%4\n\t" /* save len in tmp1 */ | ||
163 | "lsrl #5,%1\n\t" /* len/32 */ | ||
164 | "jeq 2f\n\t" /* not enough... */ | ||
165 | "subql #1,%1\n" | ||
166 | "1:\n" | ||
167 | "11:\t" | ||
168 | "movesl %2@+,%5\n\t" | ||
169 | "addxl %5,%0\n\t" | ||
170 | "movel %5,%3@+\n\t" | ||
171 | "12:\t" | ||
172 | "movesl %2@+,%5\n\t" | ||
173 | "addxl %5,%0\n\t" | ||
174 | "movel %5,%3@+\n\t" | ||
175 | "13:\t" | ||
176 | "movesl %2@+,%5\n\t" | ||
177 | "addxl %5,%0\n\t" | ||
178 | "movel %5,%3@+\n\t" | ||
179 | "14:\t" | ||
180 | "movesl %2@+,%5\n\t" | ||
181 | "addxl %5,%0\n\t" | ||
182 | "movel %5,%3@+\n\t" | ||
183 | "15:\t" | ||
184 | "movesl %2@+,%5\n\t" | ||
185 | "addxl %5,%0\n\t" | ||
186 | "movel %5,%3@+\n\t" | ||
187 | "16:\t" | ||
188 | "movesl %2@+,%5\n\t" | ||
189 | "addxl %5,%0\n\t" | ||
190 | "movel %5,%3@+\n\t" | ||
191 | "17:\t" | ||
192 | "movesl %2@+,%5\n\t" | ||
193 | "addxl %5,%0\n\t" | ||
194 | "movel %5,%3@+\n\t" | ||
195 | "18:\t" | ||
196 | "movesl %2@+,%5\n\t" | ||
197 | "addxl %5,%0\n\t" | ||
198 | "movel %5,%3@+\n\t" | ||
199 | "dbra %1,1b\n\t" | ||
200 | "clrl %5\n\t" | ||
201 | "addxl %5,%0\n\t" /* add X bit */ | ||
202 | "clrw %1\n\t" | ||
203 | "subql #1,%1\n\t" | ||
204 | "jcc 1b\n" | ||
205 | "2:\t" | ||
206 | "movel %4,%1\n\t" /* restore len from tmp1 */ | ||
207 | "andw #0x1c,%4\n\t" /* number of rest longs */ | ||
208 | "jeq 4f\n\t" | ||
209 | "lsrw #2,%4\n\t" | ||
210 | "subqw #1,%4\n" | ||
211 | "3:\n" | ||
212 | /* loop for rest longs */ | ||
213 | "19:\t" | ||
214 | "movesl %2@+,%5\n\t" | ||
215 | "addxl %5,%0\n\t" | ||
216 | "movel %5,%3@+\n\t" | ||
217 | "dbra %4,3b\n\t" | ||
218 | "clrl %5\n\t" | ||
219 | "addxl %5,%0\n" /* add X bit */ | ||
220 | "4:\t" | ||
221 | /* now check for rest bytes that do not fit into longs */ | ||
222 | "andw #3,%1\n\t" | ||
223 | "jeq 7f\n\t" | ||
224 | "clrl %5\n\t" /* clear tmp2 for rest bytes */ | ||
225 | "subqw #2,%1\n\t" | ||
226 | "jlt 5f\n\t" | ||
227 | "20:\t" | ||
228 | "movesw %2@+,%5\n\t" /* have rest >= 2: get word */ | ||
229 | "movew %5,%3@+\n\t" | ||
230 | "swap %5\n\t" /* into bits 16..31 */ | ||
231 | "tstw %1\n\t" /* another byte? */ | ||
232 | "jeq 6f\n" | ||
233 | "5:\n" | ||
234 | "21:\t" | ||
235 | "movesb %2@,%5\n\t" /* have odd rest: get byte */ | ||
236 | "moveb %5,%3@+\n\t" | ||
237 | "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ | ||
238 | "6:\t" | ||
239 | "addl %5,%0\n\t" /* now add rest long to sum */ | ||
240 | "clrl %5\n\t" | ||
241 | "addxl %5,%0\n\t" /* add X bit */ | ||
242 | "7:\t" | ||
243 | "clrl %5\n" /* no error - clear return value */ | ||
244 | "8:\n" | ||
245 | ".section .fixup,\"ax\"\n" | ||
246 | ".even\n" | ||
247 | /* If any exception occurs zero out the rest. | ||
248 | Similarities with the code above are intentional :-) */ | ||
249 | "90:\t" | ||
250 | "clrw %3@+\n\t" | ||
251 | "movel %1,%4\n\t" | ||
252 | "lsrl #5,%1\n\t" | ||
253 | "jeq 1f\n\t" | ||
254 | "subql #1,%1\n" | ||
255 | "91:\t" | ||
256 | "clrl %3@+\n" | ||
257 | "92:\t" | ||
258 | "clrl %3@+\n" | ||
259 | "93:\t" | ||
260 | "clrl %3@+\n" | ||
261 | "94:\t" | ||
262 | "clrl %3@+\n" | ||
263 | "95:\t" | ||
264 | "clrl %3@+\n" | ||
265 | "96:\t" | ||
266 | "clrl %3@+\n" | ||
267 | "97:\t" | ||
268 | "clrl %3@+\n" | ||
269 | "98:\t" | ||
270 | "clrl %3@+\n\t" | ||
271 | "dbra %1,91b\n\t" | ||
272 | "clrw %1\n\t" | ||
273 | "subql #1,%1\n\t" | ||
274 | "jcc 91b\n" | ||
275 | "1:\t" | ||
276 | "movel %4,%1\n\t" | ||
277 | "andw #0x1c,%4\n\t" | ||
278 | "jeq 1f\n\t" | ||
279 | "lsrw #2,%4\n\t" | ||
280 | "subqw #1,%4\n" | ||
281 | "99:\t" | ||
282 | "clrl %3@+\n\t" | ||
283 | "dbra %4,99b\n\t" | ||
284 | "1:\t" | ||
285 | "andw #3,%1\n\t" | ||
286 | "jeq 9f\n" | ||
287 | "100:\t" | ||
288 | "clrw %3@+\n\t" | ||
289 | "tstw %1\n\t" | ||
290 | "jeq 9f\n" | ||
291 | "101:\t" | ||
292 | "clrb %3@+\n" | ||
293 | "9:\t" | ||
294 | #define STR(X) STR1(X) | ||
295 | #define STR1(X) #X | ||
296 | "moveq #-" STR(EFAULT) ",%5\n\t" | ||
297 | "jra 8b\n" | ||
298 | ".previous\n" | ||
299 | ".section __ex_table,\"a\"\n" | ||
300 | ".long 10b,90b\n" | ||
301 | ".long 11b,91b\n" | ||
302 | ".long 12b,92b\n" | ||
303 | ".long 13b,93b\n" | ||
304 | ".long 14b,94b\n" | ||
305 | ".long 15b,95b\n" | ||
306 | ".long 16b,96b\n" | ||
307 | ".long 17b,97b\n" | ||
308 | ".long 18b,98b\n" | ||
309 | ".long 19b,99b\n" | ||
310 | ".long 20b,100b\n" | ||
311 | ".long 21b,101b\n" | ||
312 | ".previous" | ||
313 | : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), | ||
314 | "=&d" (tmp1), "=d" (tmp2) | ||
315 | : "0" (sum), "1" (len), "2" (src), "3" (dst) | ||
316 | ); | ||
317 | |||
318 | *csum_err = tmp2; | ||
319 | |||
320 | return(sum); | ||
321 | } | ||
322 | |||
323 | EXPORT_SYMBOL(csum_partial_copy_from_user); | ||
324 | |||
325 | |||
326 | /* | ||
327 | * copy from kernel space while checksumming, otherwise like csum_partial | ||
328 | */ | ||
329 | |||
330 | __wsum | ||
331 | csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) | ||
332 | { | ||
333 | unsigned long tmp1, tmp2; | ||
334 | __asm__("movel %2,%4\n\t" | ||
335 | "btst #1,%4\n\t" /* Check alignment */ | ||
336 | "jeq 2f\n\t" | ||
337 | "subql #2,%1\n\t" /* buff%4==2: treat first word */ | ||
338 | "jgt 1f\n\t" | ||
339 | "addql #2,%1\n\t" /* len was == 2, treat only rest */ | ||
340 | "jra 4f\n" | ||
341 | "1:\t" | ||
342 | "movew %2@+,%4\n\t" /* add first word to sum */ | ||
343 | "addw %4,%0\n\t" | ||
344 | "movew %4,%3@+\n\t" | ||
345 | "clrl %4\n\t" | ||
346 | "addxl %4,%0\n" /* add X bit */ | ||
347 | "2:\t" | ||
348 | /* unrolled loop for the main part: do 8 longs at once */ | ||
349 | "movel %1,%4\n\t" /* save len in tmp1 */ | ||
350 | "lsrl #5,%1\n\t" /* len/32 */ | ||
351 | "jeq 2f\n\t" /* not enough... */ | ||
352 | "subql #1,%1\n" | ||
353 | "1:\t" | ||
354 | "movel %2@+,%5\n\t" | ||
355 | "addxl %5,%0\n\t" | ||
356 | "movel %5,%3@+\n\t" | ||
357 | "movel %2@+,%5\n\t" | ||
358 | "addxl %5,%0\n\t" | ||
359 | "movel %5,%3@+\n\t" | ||
360 | "movel %2@+,%5\n\t" | ||
361 | "addxl %5,%0\n\t" | ||
362 | "movel %5,%3@+\n\t" | ||
363 | "movel %2@+,%5\n\t" | ||
364 | "addxl %5,%0\n\t" | ||
365 | "movel %5,%3@+\n\t" | ||
366 | "movel %2@+,%5\n\t" | ||
367 | "addxl %5,%0\n\t" | ||
368 | "movel %5,%3@+\n\t" | ||
369 | "movel %2@+,%5\n\t" | ||
370 | "addxl %5,%0\n\t" | ||
371 | "movel %5,%3@+\n\t" | ||
372 | "movel %2@+,%5\n\t" | ||
373 | "addxl %5,%0\n\t" | ||
374 | "movel %5,%3@+\n\t" | ||
375 | "movel %2@+,%5\n\t" | ||
376 | "addxl %5,%0\n\t" | ||
377 | "movel %5,%3@+\n\t" | ||
378 | "dbra %1,1b\n\t" | ||
379 | "clrl %5\n\t" | ||
380 | "addxl %5,%0\n\t" /* add X bit */ | ||
381 | "clrw %1\n\t" | ||
382 | "subql #1,%1\n\t" | ||
383 | "jcc 1b\n" | ||
384 | "2:\t" | ||
385 | "movel %4,%1\n\t" /* restore len from tmp1 */ | ||
386 | "andw #0x1c,%4\n\t" /* number of rest longs */ | ||
387 | "jeq 4f\n\t" | ||
388 | "lsrw #2,%4\n\t" | ||
389 | "subqw #1,%4\n" | ||
390 | "3:\t" | ||
391 | /* loop for rest longs */ | ||
392 | "movel %2@+,%5\n\t" | ||
393 | "addxl %5,%0\n\t" | ||
394 | "movel %5,%3@+\n\t" | ||
395 | "dbra %4,3b\n\t" | ||
396 | "clrl %5\n\t" | ||
397 | "addxl %5,%0\n" /* add X bit */ | ||
398 | "4:\t" | ||
399 | /* now check for rest bytes that do not fit into longs */ | ||
400 | "andw #3,%1\n\t" | ||
401 | "jeq 7f\n\t" | ||
402 | "clrl %5\n\t" /* clear tmp2 for rest bytes */ | ||
403 | "subqw #2,%1\n\t" | ||
404 | "jlt 5f\n\t" | ||
405 | "movew %2@+,%5\n\t" /* have rest >= 2: get word */ | ||
406 | "movew %5,%3@+\n\t" | ||
407 | "swap %5\n\t" /* into bits 16..31 */ | ||
408 | "tstw %1\n\t" /* another byte? */ | ||
409 | "jeq 6f\n" | ||
410 | "5:\t" | ||
411 | "moveb %2@,%5\n\t" /* have odd rest: get byte */ | ||
412 | "moveb %5,%3@+\n\t" | ||
413 | "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ | ||
414 | "6:\t" | ||
415 | "addl %5,%0\n\t" /* now add rest long to sum */ | ||
416 | "clrl %5\n\t" | ||
417 | "addxl %5,%0\n" /* add X bit */ | ||
418 | "7:\t" | ||
419 | : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), | ||
420 | "=&d" (tmp1), "=&d" (tmp2) | ||
421 | : "0" (sum), "1" (len), "2" (src), "3" (dst) | ||
422 | ); | ||
423 | return(sum); | ||
424 | } | ||
425 | EXPORT_SYMBOL(csum_partial_copy_nocheck); | ||
diff --git a/arch/m68k/lib/checksum_mm.c b/arch/m68k/lib/checksum_mm.c new file mode 100644 index 000000000000..6216f12a756b --- /dev/null +++ b/arch/m68k/lib/checksum_mm.c | |||
@@ -0,0 +1,425 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * IP/TCP/UDP checksumming routines | ||
7 | * | ||
8 | * Authors: Jorge Cwik, <jorge@laser.satlink.net> | ||
9 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | ||
10 | * Tom May, <ftom@netcom.com> | ||
11 | * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> | ||
12 | * Lots of code moved from tcp.c and ip.c; see those files | ||
13 | * for more names. | ||
14 | * | ||
15 | * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: | ||
16 | * Fixed some nasty bugs, causing some horrible crashes. | ||
17 | * A: At some points, the sum (%0) was used as | ||
18 | * length-counter instead of the length counter | ||
19 | * (%1). Thanks to Roman Hodek for pointing this out. | ||
20 | * B: GCC seems to mess up if one uses too many | ||
21 | * data-registers to hold input values and one tries to | ||
22 | * specify d0 and d1 as scratch registers. Letting gcc | ||
23 | * choose these registers itself solves the problem. | ||
24 | * | ||
25 | * This program is free software; you can redistribute it and/or | ||
26 | * modify it under the terms of the GNU General Public License | ||
27 | * as published by the Free Software Foundation; either version | ||
28 | * 2 of the License, or (at your option) any later version. | ||
29 | * | ||
30 | * 1998/8/31 Andreas Schwab: | ||
31 | * Zero out rest of buffer on exception in | ||
32 | * csum_partial_copy_from_user. | ||
33 | */ | ||
34 | |||
35 | #include <linux/module.h> | ||
36 | #include <net/checksum.h> | ||
37 | |||
38 | /* | ||
39 | * computes a partial checksum, e.g. for TCP/UDP fragments | ||
40 | */ | ||
41 | |||
42 | __wsum csum_partial(const void *buff, int len, __wsum sum) | ||
43 | { | ||
44 | unsigned long tmp1, tmp2; | ||
45 | /* | ||
46 | * Experiments with ethernet and slip connections show that buff | ||
47 | * is aligned on either a 2-byte or 4-byte boundary. | ||
48 | */ | ||
49 | __asm__("movel %2,%3\n\t" | ||
50 | "btst #1,%3\n\t" /* Check alignment */ | ||
51 | "jeq 2f\n\t" | ||
52 | "subql #2,%1\n\t" /* buff%4==2: treat first word */ | ||
53 | "jgt 1f\n\t" | ||
54 | "addql #2,%1\n\t" /* len was == 2, treat only rest */ | ||
55 | "jra 4f\n" | ||
56 | "1:\t" | ||
57 | "addw %2@+,%0\n\t" /* add first word to sum */ | ||
58 | "clrl %3\n\t" | ||
59 | "addxl %3,%0\n" /* add X bit */ | ||
60 | "2:\t" | ||
61 | /* unrolled loop for the main part: do 8 longs at once */ | ||
62 | "movel %1,%3\n\t" /* save len in tmp1 */ | ||
63 | "lsrl #5,%1\n\t" /* len/32 */ | ||
64 | "jeq 2f\n\t" /* not enough... */ | ||
65 | "subql #1,%1\n" | ||
66 | "1:\t" | ||
67 | "movel %2@+,%4\n\t" | ||
68 | "addxl %4,%0\n\t" | ||
69 | "movel %2@+,%4\n\t" | ||
70 | "addxl %4,%0\n\t" | ||
71 | "movel %2@+,%4\n\t" | ||
72 | "addxl %4,%0\n\t" | ||
73 | "movel %2@+,%4\n\t" | ||
74 | "addxl %4,%0\n\t" | ||
75 | "movel %2@+,%4\n\t" | ||
76 | "addxl %4,%0\n\t" | ||
77 | "movel %2@+,%4\n\t" | ||
78 | "addxl %4,%0\n\t" | ||
79 | "movel %2@+,%4\n\t" | ||
80 | "addxl %4,%0\n\t" | ||
81 | "movel %2@+,%4\n\t" | ||
82 | "addxl %4,%0\n\t" | ||
83 | "dbra %1,1b\n\t" | ||
84 | "clrl %4\n\t" | ||
85 | "addxl %4,%0\n\t" /* add X bit */ | ||
86 | "clrw %1\n\t" | ||
87 | "subql #1,%1\n\t" | ||
88 | "jcc 1b\n" | ||
89 | "2:\t" | ||
90 | "movel %3,%1\n\t" /* restore len from tmp1 */ | ||
91 | "andw #0x1c,%3\n\t" /* number of rest longs */ | ||
92 | "jeq 4f\n\t" | ||
93 | "lsrw #2,%3\n\t" | ||
94 | "subqw #1,%3\n" | ||
95 | "3:\t" | ||
96 | /* loop for rest longs */ | ||
97 | "movel %2@+,%4\n\t" | ||
98 | "addxl %4,%0\n\t" | ||
99 | "dbra %3,3b\n\t" | ||
100 | "clrl %4\n\t" | ||
101 | "addxl %4,%0\n" /* add X bit */ | ||
102 | "4:\t" | ||
103 | /* now check for rest bytes that do not fit into longs */ | ||
104 | "andw #3,%1\n\t" | ||
105 | "jeq 7f\n\t" | ||
106 | "clrl %4\n\t" /* clear tmp2 for rest bytes */ | ||
107 | "subqw #2,%1\n\t" | ||
108 | "jlt 5f\n\t" | ||
109 | "movew %2@+,%4\n\t" /* have rest >= 2: get word */ | ||
110 | "swap %4\n\t" /* into bits 16..31 */ | ||
111 | "tstw %1\n\t" /* another byte? */ | ||
112 | "jeq 6f\n" | ||
113 | "5:\t" | ||
114 | "moveb %2@,%4\n\t" /* have odd rest: get byte */ | ||
115 | "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ | ||
116 | "6:\t" | ||
117 | "addl %4,%0\n\t" /* now add rest long to sum */ | ||
118 | "clrl %4\n\t" | ||
119 | "addxl %4,%0\n" /* add X bit */ | ||
120 | "7:\t" | ||
121 | : "=d" (sum), "=d" (len), "=a" (buff), | ||
122 | "=&d" (tmp1), "=&d" (tmp2) | ||
123 | : "0" (sum), "1" (len), "2" (buff) | ||
124 | ); | ||
125 | return(sum); | ||
126 | } | ||
127 | |||
128 | EXPORT_SYMBOL(csum_partial); | ||
129 | |||
130 | |||
131 | /* | ||
132 | * copy from user space while checksumming, with exception handling. | ||
133 | */ | ||
134 | |||
135 | __wsum | ||
136 | csum_partial_copy_from_user(const void __user *src, void *dst, | ||
137 | int len, __wsum sum, int *csum_err) | ||
138 | { | ||
139 | /* | ||
140 | * GCC doesn't like more than 10 operands for the asm | ||
141 | * statements so we have to use tmp2 for the error | ||
142 | * code. | ||
143 | */ | ||
144 | unsigned long tmp1, tmp2; | ||
145 | |||
146 | __asm__("movel %2,%4\n\t" | ||
147 | "btst #1,%4\n\t" /* Check alignment */ | ||
148 | "jeq 2f\n\t" | ||
149 | "subql #2,%1\n\t" /* buff%4==2: treat first word */ | ||
150 | "jgt 1f\n\t" | ||
151 | "addql #2,%1\n\t" /* len was == 2, treat only rest */ | ||
152 | "jra 4f\n" | ||
153 | "1:\n" | ||
154 | "10:\t" | ||
155 | "movesw %2@+,%4\n\t" /* add first word to sum */ | ||
156 | "addw %4,%0\n\t" | ||
157 | "movew %4,%3@+\n\t" | ||
158 | "clrl %4\n\t" | ||
159 | "addxl %4,%0\n" /* add X bit */ | ||
160 | "2:\t" | ||
161 | /* unrolled loop for the main part: do 8 longs at once */ | ||
162 | "movel %1,%4\n\t" /* save len in tmp1 */ | ||
163 | "lsrl #5,%1\n\t" /* len/32 */ | ||
164 | "jeq 2f\n\t" /* not enough... */ | ||
165 | "subql #1,%1\n" | ||
166 | "1:\n" | ||
167 | "11:\t" | ||
168 | "movesl %2@+,%5\n\t" | ||
169 | "addxl %5,%0\n\t" | ||
170 | "movel %5,%3@+\n\t" | ||
171 | "12:\t" | ||
172 | "movesl %2@+,%5\n\t" | ||
173 | "addxl %5,%0\n\t" | ||
174 | "movel %5,%3@+\n\t" | ||
175 | "13:\t" | ||
176 | "movesl %2@+,%5\n\t" | ||
177 | "addxl %5,%0\n\t" | ||
178 | "movel %5,%3@+\n\t" | ||
179 | "14:\t" | ||
180 | "movesl %2@+,%5\n\t" | ||
181 | "addxl %5,%0\n\t" | ||
182 | "movel %5,%3@+\n\t" | ||
183 | "15:\t" | ||
184 | "movesl %2@+,%5\n\t" | ||
185 | "addxl %5,%0\n\t" | ||
186 | "movel %5,%3@+\n\t" | ||
187 | "16:\t" | ||
188 | "movesl %2@+,%5\n\t" | ||
189 | "addxl %5,%0\n\t" | ||
190 | "movel %5,%3@+\n\t" | ||
191 | "17:\t" | ||
192 | "movesl %2@+,%5\n\t" | ||
193 | "addxl %5,%0\n\t" | ||
194 | "movel %5,%3@+\n\t" | ||
195 | "18:\t" | ||
196 | "movesl %2@+,%5\n\t" | ||
197 | "addxl %5,%0\n\t" | ||
198 | "movel %5,%3@+\n\t" | ||
199 | "dbra %1,1b\n\t" | ||
200 | "clrl %5\n\t" | ||
201 | "addxl %5,%0\n\t" /* add X bit */ | ||
202 | "clrw %1\n\t" | ||
203 | "subql #1,%1\n\t" | ||
204 | "jcc 1b\n" | ||
205 | "2:\t" | ||
206 | "movel %4,%1\n\t" /* restore len from tmp1 */ | ||
207 | "andw #0x1c,%4\n\t" /* number of rest longs */ | ||
208 | "jeq 4f\n\t" | ||
209 | "lsrw #2,%4\n\t" | ||
210 | "subqw #1,%4\n" | ||
211 | "3:\n" | ||
212 | /* loop for rest longs */ | ||
213 | "19:\t" | ||
214 | "movesl %2@+,%5\n\t" | ||
215 | "addxl %5,%0\n\t" | ||
216 | "movel %5,%3@+\n\t" | ||
217 | "dbra %4,3b\n\t" | ||
218 | "clrl %5\n\t" | ||
219 | "addxl %5,%0\n" /* add X bit */ | ||
220 | "4:\t" | ||
221 | /* now check for rest bytes that do not fit into longs */ | ||
222 | "andw #3,%1\n\t" | ||
223 | "jeq 7f\n\t" | ||
224 | "clrl %5\n\t" /* clear tmp2 for rest bytes */ | ||
225 | "subqw #2,%1\n\t" | ||
226 | "jlt 5f\n\t" | ||
227 | "20:\t" | ||
228 | "movesw %2@+,%5\n\t" /* have rest >= 2: get word */ | ||
229 | "movew %5,%3@+\n\t" | ||
230 | "swap %5\n\t" /* into bits 16..31 */ | ||
231 | "tstw %1\n\t" /* another byte? */ | ||
232 | "jeq 6f\n" | ||
233 | "5:\n" | ||
234 | "21:\t" | ||
235 | "movesb %2@,%5\n\t" /* have odd rest: get byte */ | ||
236 | "moveb %5,%3@+\n\t" | ||
237 | "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ | ||
238 | "6:\t" | ||
239 | "addl %5,%0\n\t" /* now add rest long to sum */ | ||
240 | "clrl %5\n\t" | ||
241 | "addxl %5,%0\n\t" /* add X bit */ | ||
242 | "7:\t" | ||
243 | "clrl %5\n" /* no error - clear return value */ | ||
244 | "8:\n" | ||
245 | ".section .fixup,\"ax\"\n" | ||
246 | ".even\n" | ||
247 | /* If any exception occurs zero out the rest. | ||
248 | Similarities with the code above are intentional :-) */ | ||
249 | "90:\t" | ||
250 | "clrw %3@+\n\t" | ||
251 | "movel %1,%4\n\t" | ||
252 | "lsrl #5,%1\n\t" | ||
253 | "jeq 1f\n\t" | ||
254 | "subql #1,%1\n" | ||
255 | "91:\t" | ||
256 | "clrl %3@+\n" | ||
257 | "92:\t" | ||
258 | "clrl %3@+\n" | ||
259 | "93:\t" | ||
260 | "clrl %3@+\n" | ||
261 | "94:\t" | ||
262 | "clrl %3@+\n" | ||
263 | "95:\t" | ||
264 | "clrl %3@+\n" | ||
265 | "96:\t" | ||
266 | "clrl %3@+\n" | ||
267 | "97:\t" | ||
268 | "clrl %3@+\n" | ||
269 | "98:\t" | ||
270 | "clrl %3@+\n\t" | ||
271 | "dbra %1,91b\n\t" | ||
272 | "clrw %1\n\t" | ||
273 | "subql #1,%1\n\t" | ||
274 | "jcc 91b\n" | ||
275 | "1:\t" | ||
276 | "movel %4,%1\n\t" | ||
277 | "andw #0x1c,%4\n\t" | ||
278 | "jeq 1f\n\t" | ||
279 | "lsrw #2,%4\n\t" | ||
280 | "subqw #1,%4\n" | ||
281 | "99:\t" | ||
282 | "clrl %3@+\n\t" | ||
283 | "dbra %4,99b\n\t" | ||
284 | "1:\t" | ||
285 | "andw #3,%1\n\t" | ||
286 | "jeq 9f\n" | ||
287 | "100:\t" | ||
288 | "clrw %3@+\n\t" | ||
289 | "tstw %1\n\t" | ||
290 | "jeq 9f\n" | ||
291 | "101:\t" | ||
292 | "clrb %3@+\n" | ||
293 | "9:\t" | ||
294 | #define STR(X) STR1(X) | ||
295 | #define STR1(X) #X | ||
296 | "moveq #-" STR(EFAULT) ",%5\n\t" | ||
297 | "jra 8b\n" | ||
298 | ".previous\n" | ||
299 | ".section __ex_table,\"a\"\n" | ||
300 | ".long 10b,90b\n" | ||
301 | ".long 11b,91b\n" | ||
302 | ".long 12b,92b\n" | ||
303 | ".long 13b,93b\n" | ||
304 | ".long 14b,94b\n" | ||
305 | ".long 15b,95b\n" | ||
306 | ".long 16b,96b\n" | ||
307 | ".long 17b,97b\n" | ||
308 | ".long 18b,98b\n" | ||
309 | ".long 19b,99b\n" | ||
310 | ".long 20b,100b\n" | ||
311 | ".long 21b,101b\n" | ||
312 | ".previous" | ||
313 | : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), | ||
314 | "=&d" (tmp1), "=d" (tmp2) | ||
315 | : "0" (sum), "1" (len), "2" (src), "3" (dst) | ||
316 | ); | ||
317 | |||
318 | *csum_err = tmp2; | ||
319 | |||
320 | return(sum); | ||
321 | } | ||
322 | |||
323 | EXPORT_SYMBOL(csum_partial_copy_from_user); | ||
324 | |||
325 | |||
326 | /* | ||
327 | * copy from kernel space while checksumming, otherwise like csum_partial | ||
328 | */ | ||
329 | |||
330 | __wsum | ||
331 | csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) | ||
332 | { | ||
333 | unsigned long tmp1, tmp2; | ||
334 | __asm__("movel %2,%4\n\t" | ||
335 | "btst #1,%4\n\t" /* Check alignment */ | ||
336 | "jeq 2f\n\t" | ||
337 | "subql #2,%1\n\t" /* buff%4==2: treat first word */ | ||
338 | "jgt 1f\n\t" | ||
339 | "addql #2,%1\n\t" /* len was == 2, treat only rest */ | ||
340 | "jra 4f\n" | ||
341 | "1:\t" | ||
342 | "movew %2@+,%4\n\t" /* add first word to sum */ | ||
343 | "addw %4,%0\n\t" | ||
344 | "movew %4,%3@+\n\t" | ||
345 | "clrl %4\n\t" | ||
346 | "addxl %4,%0\n" /* add X bit */ | ||
347 | "2:\t" | ||
348 | /* unrolled loop for the main part: do 8 longs at once */ | ||
349 | "movel %1,%4\n\t" /* save len in tmp1 */ | ||
350 | "lsrl #5,%1\n\t" /* len/32 */ | ||
351 | "jeq 2f\n\t" /* not enough... */ | ||
352 | "subql #1,%1\n" | ||
353 | "1:\t" | ||
354 | "movel %2@+,%5\n\t" | ||
355 | "addxl %5,%0\n\t" | ||
356 | "movel %5,%3@+\n\t" | ||
357 | "movel %2@+,%5\n\t" | ||
358 | "addxl %5,%0\n\t" | ||
359 | "movel %5,%3@+\n\t" | ||
360 | "movel %2@+,%5\n\t" | ||
361 | "addxl %5,%0\n\t" | ||
362 | "movel %5,%3@+\n\t" | ||
363 | "movel %2@+,%5\n\t" | ||
364 | "addxl %5,%0\n\t" | ||
365 | "movel %5,%3@+\n\t" | ||
366 | "movel %2@+,%5\n\t" | ||
367 | "addxl %5,%0\n\t" | ||
368 | "movel %5,%3@+\n\t" | ||
369 | "movel %2@+,%5\n\t" | ||
370 | "addxl %5,%0\n\t" | ||
371 | "movel %5,%3@+\n\t" | ||
372 | "movel %2@+,%5\n\t" | ||
373 | "addxl %5,%0\n\t" | ||
374 | "movel %5,%3@+\n\t" | ||
375 | "movel %2@+,%5\n\t" | ||
376 | "addxl %5,%0\n\t" | ||
377 | "movel %5,%3@+\n\t" | ||
378 | "dbra %1,1b\n\t" | ||
379 | "clrl %5\n\t" | ||
380 | "addxl %5,%0\n\t" /* add X bit */ | ||
381 | "clrw %1\n\t" | ||
382 | "subql #1,%1\n\t" | ||
383 | "jcc 1b\n" | ||
384 | "2:\t" | ||
385 | "movel %4,%1\n\t" /* restore len from tmp1 */ | ||
386 | "andw #0x1c,%4\n\t" /* number of rest longs */ | ||
387 | "jeq 4f\n\t" | ||
388 | "lsrw #2,%4\n\t" | ||
389 | "subqw #1,%4\n" | ||
390 | "3:\t" | ||
391 | /* loop for rest longs */ | ||
392 | "movel %2@+,%5\n\t" | ||
393 | "addxl %5,%0\n\t" | ||
394 | "movel %5,%3@+\n\t" | ||
395 | "dbra %4,3b\n\t" | ||
396 | "clrl %5\n\t" | ||
397 | "addxl %5,%0\n" /* add X bit */ | ||
398 | "4:\t" | ||
399 | /* now check for rest bytes that do not fit into longs */ | ||
400 | "andw #3,%1\n\t" | ||
401 | "jeq 7f\n\t" | ||
402 | "clrl %5\n\t" /* clear tmp2 for rest bytes */ | ||
403 | "subqw #2,%1\n\t" | ||
404 | "jlt 5f\n\t" | ||
405 | "movew %2@+,%5\n\t" /* have rest >= 2: get word */ | ||
406 | "movew %5,%3@+\n\t" | ||
407 | "swap %5\n\t" /* into bits 16..31 */ | ||
408 | "tstw %1\n\t" /* another byte? */ | ||
409 | "jeq 6f\n" | ||
410 | "5:\t" | ||
411 | "moveb %2@,%5\n\t" /* have odd rest: get byte */ | ||
412 | "moveb %5,%3@+\n\t" | ||
413 | "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ | ||
414 | "6:\t" | ||
415 | "addl %5,%0\n\t" /* now add rest long to sum */ | ||
416 | "clrl %5\n\t" | ||
417 | "addxl %5,%0\n" /* add X bit */ | ||
418 | "7:\t" | ||
419 | : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), | ||
420 | "=&d" (tmp1), "=&d" (tmp2) | ||
421 | : "0" (sum), "1" (len), "2" (src), "3" (dst) | ||
422 | ); | ||
423 | return(sum); | ||
424 | } | ||
425 | EXPORT_SYMBOL(csum_partial_copy_nocheck); | ||
diff --git a/arch/m68knommu/lib/checksum.c b/arch/m68k/lib/checksum_no.c index eccf25d3d73e..eccf25d3d73e 100644 --- a/arch/m68knommu/lib/checksum.c +++ b/arch/m68k/lib/checksum_no.c | |||
diff --git a/arch/m68knommu/lib/delay.c b/arch/m68k/lib/delay.c index 5bd5472d38a0..5bd5472d38a0 100644 --- a/arch/m68knommu/lib/delay.c +++ b/arch/m68k/lib/delay.c | |||
diff --git a/arch/m68knommu/lib/divsi3.S b/arch/m68k/lib/divsi3.S index ec307b61991e..ec307b61991e 100644 --- a/arch/m68knommu/lib/divsi3.S +++ b/arch/m68k/lib/divsi3.S | |||
diff --git a/arch/m68knommu/lib/memcpy.c b/arch/m68k/lib/memcpy.c index b50dbcad4746..b50dbcad4746 100644 --- a/arch/m68knommu/lib/memcpy.c +++ b/arch/m68k/lib/memcpy.c | |||
diff --git a/arch/m68knommu/lib/memmove.c b/arch/m68k/lib/memmove.c index b3dcfe9dab7e..b3dcfe9dab7e 100644 --- a/arch/m68knommu/lib/memmove.c +++ b/arch/m68k/lib/memmove.c | |||
diff --git a/arch/m68knommu/lib/memset.c b/arch/m68k/lib/memset.c index 1389bf455633..1389bf455633 100644 --- a/arch/m68knommu/lib/memset.c +++ b/arch/m68k/lib/memset.c | |||
diff --git a/arch/m68knommu/lib/modsi3.S b/arch/m68k/lib/modsi3.S index ef3849435768..ef3849435768 100644 --- a/arch/m68knommu/lib/modsi3.S +++ b/arch/m68k/lib/modsi3.S | |||
diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c index be4f275649e3..16e0eb338ee0 100644 --- a/arch/m68k/lib/muldi3.c +++ b/arch/m68k/lib/muldi3.c | |||
@@ -1,63 +1,5 @@ | |||
1 | /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and | 1 | #ifdef CONFIG_MMU |
2 | gcc-2.7.2.3/longlong.h which is: */ | 2 | #include "muldi3_mm.c" |
3 | /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | 3 | #else |
4 | 4 | #include "muldi3_no.c" | |
5 | This file is part of GNU CC. | 5 | #endif |
6 | |||
7 | GNU CC is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2, or (at your option) | ||
10 | any later version. | ||
11 | |||
12 | GNU CC is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with GNU CC; see the file COPYING. If not, write to | ||
19 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
20 | Boston, MA 02111-1307, USA. */ | ||
21 | |||
22 | #define BITS_PER_UNIT 8 | ||
23 | |||
24 | #define umul_ppmm(w1, w0, u, v) \ | ||
25 | __asm__ ("mulu%.l %3,%1:%0" \ | ||
26 | : "=d" ((USItype)(w0)), \ | ||
27 | "=d" ((USItype)(w1)) \ | ||
28 | : "%0" ((USItype)(u)), \ | ||
29 | "dmi" ((USItype)(v))) | ||
30 | |||
31 | #define __umulsidi3(u, v) \ | ||
32 | ({DIunion __w; \ | ||
33 | umul_ppmm (__w.s.high, __w.s.low, u, v); \ | ||
34 | __w.ll; }) | ||
35 | |||
36 | typedef int SItype __attribute__ ((mode (SI))); | ||
37 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
38 | typedef int DItype __attribute__ ((mode (DI))); | ||
39 | typedef int word_type __attribute__ ((mode (__word__))); | ||
40 | |||
41 | struct DIstruct {SItype high, low;}; | ||
42 | |||
43 | typedef union | ||
44 | { | ||
45 | struct DIstruct s; | ||
46 | DItype ll; | ||
47 | } DIunion; | ||
48 | |||
49 | DItype | ||
50 | __muldi3 (DItype u, DItype v) | ||
51 | { | ||
52 | DIunion w; | ||
53 | DIunion uu, vv; | ||
54 | |||
55 | uu.ll = u, | ||
56 | vv.ll = v; | ||
57 | |||
58 | w.ll = __umulsidi3 (uu.s.low, vv.s.low); | ||
59 | w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high | ||
60 | + (USItype) uu.s.high * (USItype) vv.s.low); | ||
61 | |||
62 | return w.ll; | ||
63 | } | ||
diff --git a/arch/m68knommu/lib/ashrdi3.c b/arch/m68k/lib/muldi3_mm.c index 78efb65e315a..be4f275649e3 100644 --- a/arch/m68knommu/lib/ashrdi3.c +++ b/arch/m68k/lib/muldi3_mm.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ | 1 | /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and |
2 | gcc-2.7.2.3/longlong.h which is: */ | ||
2 | /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | 3 | /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. |
3 | 4 | ||
4 | This file is part of GNU CC. | 5 | This file is part of GNU CC. |
@@ -20,7 +21,19 @@ Boston, MA 02111-1307, USA. */ | |||
20 | 21 | ||
21 | #define BITS_PER_UNIT 8 | 22 | #define BITS_PER_UNIT 8 |
22 | 23 | ||
23 | typedef int SItype __attribute__ ((mode (SI))); | 24 | #define umul_ppmm(w1, w0, u, v) \ |
25 | __asm__ ("mulu%.l %3,%1:%0" \ | ||
26 | : "=d" ((USItype)(w0)), \ | ||
27 | "=d" ((USItype)(w1)) \ | ||
28 | : "%0" ((USItype)(u)), \ | ||
29 | "dmi" ((USItype)(v))) | ||
30 | |||
31 | #define __umulsidi3(u, v) \ | ||
32 | ({DIunion __w; \ | ||
33 | umul_ppmm (__w.s.high, __w.s.low, u, v); \ | ||
34 | __w.ll; }) | ||
35 | |||
36 | typedef int SItype __attribute__ ((mode (SI))); | ||
24 | typedef unsigned int USItype __attribute__ ((mode (SI))); | 37 | typedef unsigned int USItype __attribute__ ((mode (SI))); |
25 | typedef int DItype __attribute__ ((mode (DI))); | 38 | typedef int DItype __attribute__ ((mode (DI))); |
26 | typedef int word_type __attribute__ ((mode (__word__))); | 39 | typedef int word_type __attribute__ ((mode (__word__))); |
@@ -34,30 +47,17 @@ typedef union | |||
34 | } DIunion; | 47 | } DIunion; |
35 | 48 | ||
36 | DItype | 49 | DItype |
37 | __ashrdi3 (DItype u, word_type b) | 50 | __muldi3 (DItype u, DItype v) |
38 | { | 51 | { |
39 | DIunion w; | 52 | DIunion w; |
40 | word_type bm; | 53 | DIunion uu, vv; |
41 | DIunion uu; | 54 | |
42 | 55 | uu.ll = u, | |
43 | if (b == 0) | 56 | vv.ll = v; |
44 | return u; | 57 | |
45 | 58 | w.ll = __umulsidi3 (uu.s.low, vv.s.low); | |
46 | uu.ll = u; | 59 | w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high |
47 | 60 | + (USItype) uu.s.high * (USItype) vv.s.low); | |
48 | bm = (sizeof (SItype) * BITS_PER_UNIT) - b; | ||
49 | if (bm <= 0) | ||
50 | { | ||
51 | /* w.s.high = 1..1 or 0..0 */ | ||
52 | w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); | ||
53 | w.s.low = uu.s.high >> -bm; | ||
54 | } | ||
55 | else | ||
56 | { | ||
57 | USItype carries = (USItype)uu.s.high << bm; | ||
58 | w.s.high = uu.s.high >> b; | ||
59 | w.s.low = ((USItype)uu.s.low >> b) | carries; | ||
60 | } | ||
61 | 61 | ||
62 | return w.ll; | 62 | return w.ll; |
63 | } | 63 | } |
diff --git a/arch/m68knommu/lib/muldi3.c b/arch/m68k/lib/muldi3_no.c index 34af72c30303..34af72c30303 100644 --- a/arch/m68knommu/lib/muldi3.c +++ b/arch/m68k/lib/muldi3_no.c | |||
diff --git a/arch/m68knommu/lib/mulsi3.S b/arch/m68k/lib/mulsi3.S index ce29ea37b45f..ce29ea37b45f 100644 --- a/arch/m68knommu/lib/mulsi3.S +++ b/arch/m68k/lib/mulsi3.S | |||
diff --git a/arch/m68knommu/lib/udivsi3.S b/arch/m68k/lib/udivsi3.S index c424c4a1f0a3..c424c4a1f0a3 100644 --- a/arch/m68knommu/lib/udivsi3.S +++ b/arch/m68k/lib/udivsi3.S | |||
diff --git a/arch/m68knommu/lib/umodsi3.S b/arch/m68k/lib/umodsi3.S index 5def5f626478..5def5f626478 100644 --- a/arch/m68knommu/lib/umodsi3.S +++ b/arch/m68k/lib/umodsi3.S | |||
diff --git a/arch/m68k/mm/Makefile b/arch/m68k/mm/Makefile index 5eaa43c4cb3c..b60270e4954b 100644 --- a/arch/m68k/mm/Makefile +++ b/arch/m68k/mm/Makefile | |||
@@ -1,8 +1,5 @@ | |||
1 | # | 1 | ifdef CONFIG_MMU |
2 | # Makefile for the linux m68k-specific parts of the memory manager. | 2 | include arch/m68k/mm/Makefile_mm |
3 | # | 3 | else |
4 | 4 | include arch/m68k/mm/Makefile_no | |
5 | obj-y := cache.o init.o fault.o hwtest.o | 5 | endif |
6 | |||
7 | obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o | ||
8 | obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o | ||
diff --git a/arch/m68k/mm/Makefile_mm b/arch/m68k/mm/Makefile_mm new file mode 100644 index 000000000000..5eaa43c4cb3c --- /dev/null +++ b/arch/m68k/mm/Makefile_mm | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the linux m68k-specific parts of the memory manager. | ||
3 | # | ||
4 | |||
5 | obj-y := cache.o init.o fault.o hwtest.o | ||
6 | |||
7 | obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o | ||
8 | obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o | ||
diff --git a/arch/m68knommu/mm/Makefile b/arch/m68k/mm/Makefile_no index b54ab6b4b523..b54ab6b4b523 100644 --- a/arch/m68knommu/mm/Makefile +++ b/arch/m68k/mm/Makefile_no | |||
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index 8bc842554e5b..27b5ce089a34 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c | |||
@@ -1,150 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/mm/init.c | 2 | #include "init_mm.c" |
3 | * | 3 | #else |
4 | * Copyright (C) 1995 Hamish Macdonald | 4 | #include "init_no.c" |
5 | * | ||
6 | * Contains common initialization routines, specific init code moved | ||
7 | * to motorola.c and sun3mmu.c | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/signal.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/mm.h> | ||
14 | #include <linux/swap.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/gfp.h> | ||
21 | |||
22 | #include <asm/setup.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | #include <asm/page.h> | ||
25 | #include <asm/pgalloc.h> | ||
26 | #include <asm/system.h> | ||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/io.h> | ||
29 | #ifdef CONFIG_ATARI | ||
30 | #include <asm/atari_stram.h> | ||
31 | #endif | ||
32 | #include <asm/sections.h> | ||
33 | #include <asm/tlb.h> | ||
34 | |||
35 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
36 | |||
37 | pg_data_t pg_data_map[MAX_NUMNODES]; | ||
38 | EXPORT_SYMBOL(pg_data_map); | ||
39 | |||
40 | int m68k_virt_to_node_shift; | ||
41 | |||
42 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
43 | pg_data_t *pg_data_table[65]; | ||
44 | EXPORT_SYMBOL(pg_data_table); | ||
45 | #endif | ||
46 | |||
47 | void __init m68k_setup_node(int node) | ||
48 | { | ||
49 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
50 | struct mem_info *info = m68k_memory + node; | ||
51 | int i, end; | ||
52 | |||
53 | i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift(); | ||
54 | end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift(); | ||
55 | for (; i <= end; i++) { | ||
56 | if (pg_data_table[i]) | ||
57 | printk("overlap at %u for chunk %u\n", i, node); | ||
58 | pg_data_table[i] = pg_data_map + node; | ||
59 | } | ||
60 | #endif | ||
61 | pg_data_map[node].bdata = bootmem_node_data + node; | ||
62 | node_set_online(node); | ||
63 | } | ||
64 | |||
65 | |||
66 | /* | ||
67 | * ZERO_PAGE is a special page that is used for zero-initialized | ||
68 | * data and COW. | ||
69 | */ | ||
70 | |||
71 | void *empty_zero_page; | ||
72 | EXPORT_SYMBOL(empty_zero_page); | ||
73 | |||
74 | extern void init_pointer_table(unsigned long ptable); | ||
75 | |||
76 | /* References to section boundaries */ | ||
77 | |||
78 | extern pmd_t *zero_pgtable; | ||
79 | |||
80 | void __init mem_init(void) | ||
81 | { | ||
82 | pg_data_t *pgdat; | ||
83 | int codepages = 0; | ||
84 | int datapages = 0; | ||
85 | int initpages = 0; | ||
86 | int i; | ||
87 | |||
88 | #ifdef CONFIG_ATARI | ||
89 | if (MACH_IS_ATARI) | ||
90 | atari_stram_mem_init_hook(); | ||
91 | #endif | ||
92 | |||
93 | /* this will put all memory onto the freelists */ | ||
94 | totalram_pages = num_physpages = 0; | ||
95 | for_each_online_pgdat(pgdat) { | ||
96 | num_physpages += pgdat->node_present_pages; | ||
97 | |||
98 | totalram_pages += free_all_bootmem_node(pgdat); | ||
99 | for (i = 0; i < pgdat->node_spanned_pages; i++) { | ||
100 | struct page *page = pgdat->node_mem_map + i; | ||
101 | char *addr = page_to_virt(page); | ||
102 | |||
103 | if (!PageReserved(page)) | ||
104 | continue; | ||
105 | if (addr >= _text && | ||
106 | addr < _etext) | ||
107 | codepages++; | ||
108 | else if (addr >= __init_begin && | ||
109 | addr < __init_end) | ||
110 | initpages++; | ||
111 | else | ||
112 | datapages++; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | #ifndef CONFIG_SUN3 | ||
117 | /* insert pointer tables allocated so far into the tablelist */ | ||
118 | init_pointer_table((unsigned long)kernel_pg_dir); | ||
119 | for (i = 0; i < PTRS_PER_PGD; i++) { | ||
120 | if (pgd_present(kernel_pg_dir[i])) | ||
121 | init_pointer_table(__pgd_page(kernel_pg_dir[i])); | ||
122 | } | ||
123 | |||
124 | /* insert also pointer table that we used to unmap the zero page */ | ||
125 | if (zero_pgtable) | ||
126 | init_pointer_table((unsigned long)zero_pgtable); | ||
127 | #endif | ||
128 | |||
129 | printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", | ||
130 | nr_free_pages() << (PAGE_SHIFT-10), | ||
131 | totalram_pages << (PAGE_SHIFT-10), | ||
132 | codepages << (PAGE_SHIFT-10), | ||
133 | datapages << (PAGE_SHIFT-10), | ||
134 | initpages << (PAGE_SHIFT-10)); | ||
135 | } | ||
136 | |||
137 | #ifdef CONFIG_BLK_DEV_INITRD | ||
138 | void free_initrd_mem(unsigned long start, unsigned long end) | ||
139 | { | ||
140 | int pages = 0; | ||
141 | for (; start < end; start += PAGE_SIZE) { | ||
142 | ClearPageReserved(virt_to_page(start)); | ||
143 | init_page_count(virt_to_page(start)); | ||
144 | free_page(start); | ||
145 | totalram_pages++; | ||
146 | pages++; | ||
147 | } | ||
148 | printk ("Freeing initrd memory: %dk freed\n", pages); | ||
149 | } | ||
150 | #endif | 5 | #endif |
diff --git a/arch/m68k/mm/init_mm.c b/arch/m68k/mm/init_mm.c new file mode 100644 index 000000000000..8bc842554e5b --- /dev/null +++ b/arch/m68k/mm/init_mm.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/mm/init.c | ||
3 | * | ||
4 | * Copyright (C) 1995 Hamish Macdonald | ||
5 | * | ||
6 | * Contains common initialization routines, specific init code moved | ||
7 | * to motorola.c and sun3mmu.c | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/signal.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/mm.h> | ||
14 | #include <linux/swap.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/gfp.h> | ||
21 | |||
22 | #include <asm/setup.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | #include <asm/page.h> | ||
25 | #include <asm/pgalloc.h> | ||
26 | #include <asm/system.h> | ||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/io.h> | ||
29 | #ifdef CONFIG_ATARI | ||
30 | #include <asm/atari_stram.h> | ||
31 | #endif | ||
32 | #include <asm/sections.h> | ||
33 | #include <asm/tlb.h> | ||
34 | |||
35 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
36 | |||
37 | pg_data_t pg_data_map[MAX_NUMNODES]; | ||
38 | EXPORT_SYMBOL(pg_data_map); | ||
39 | |||
40 | int m68k_virt_to_node_shift; | ||
41 | |||
42 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
43 | pg_data_t *pg_data_table[65]; | ||
44 | EXPORT_SYMBOL(pg_data_table); | ||
45 | #endif | ||
46 | |||
47 | void __init m68k_setup_node(int node) | ||
48 | { | ||
49 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
50 | struct mem_info *info = m68k_memory + node; | ||
51 | int i, end; | ||
52 | |||
53 | i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift(); | ||
54 | end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift(); | ||
55 | for (; i <= end; i++) { | ||
56 | if (pg_data_table[i]) | ||
57 | printk("overlap at %u for chunk %u\n", i, node); | ||
58 | pg_data_table[i] = pg_data_map + node; | ||
59 | } | ||
60 | #endif | ||
61 | pg_data_map[node].bdata = bootmem_node_data + node; | ||
62 | node_set_online(node); | ||
63 | } | ||
64 | |||
65 | |||
66 | /* | ||
67 | * ZERO_PAGE is a special page that is used for zero-initialized | ||
68 | * data and COW. | ||
69 | */ | ||
70 | |||
71 | void *empty_zero_page; | ||
72 | EXPORT_SYMBOL(empty_zero_page); | ||
73 | |||
74 | extern void init_pointer_table(unsigned long ptable); | ||
75 | |||
76 | /* References to section boundaries */ | ||
77 | |||
78 | extern pmd_t *zero_pgtable; | ||
79 | |||
80 | void __init mem_init(void) | ||
81 | { | ||
82 | pg_data_t *pgdat; | ||
83 | int codepages = 0; | ||
84 | int datapages = 0; | ||
85 | int initpages = 0; | ||
86 | int i; | ||
87 | |||
88 | #ifdef CONFIG_ATARI | ||
89 | if (MACH_IS_ATARI) | ||
90 | atari_stram_mem_init_hook(); | ||
91 | #endif | ||
92 | |||
93 | /* this will put all memory onto the freelists */ | ||
94 | totalram_pages = num_physpages = 0; | ||
95 | for_each_online_pgdat(pgdat) { | ||
96 | num_physpages += pgdat->node_present_pages; | ||
97 | |||
98 | totalram_pages += free_all_bootmem_node(pgdat); | ||
99 | for (i = 0; i < pgdat->node_spanned_pages; i++) { | ||
100 | struct page *page = pgdat->node_mem_map + i; | ||
101 | char *addr = page_to_virt(page); | ||
102 | |||
103 | if (!PageReserved(page)) | ||
104 | continue; | ||
105 | if (addr >= _text && | ||
106 | addr < _etext) | ||
107 | codepages++; | ||
108 | else if (addr >= __init_begin && | ||
109 | addr < __init_end) | ||
110 | initpages++; | ||
111 | else | ||
112 | datapages++; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | #ifndef CONFIG_SUN3 | ||
117 | /* insert pointer tables allocated so far into the tablelist */ | ||
118 | init_pointer_table((unsigned long)kernel_pg_dir); | ||
119 | for (i = 0; i < PTRS_PER_PGD; i++) { | ||
120 | if (pgd_present(kernel_pg_dir[i])) | ||
121 | init_pointer_table(__pgd_page(kernel_pg_dir[i])); | ||
122 | } | ||
123 | |||
124 | /* insert also pointer table that we used to unmap the zero page */ | ||
125 | if (zero_pgtable) | ||
126 | init_pointer_table((unsigned long)zero_pgtable); | ||
127 | #endif | ||
128 | |||
129 | printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", | ||
130 | nr_free_pages() << (PAGE_SHIFT-10), | ||
131 | totalram_pages << (PAGE_SHIFT-10), | ||
132 | codepages << (PAGE_SHIFT-10), | ||
133 | datapages << (PAGE_SHIFT-10), | ||
134 | initpages << (PAGE_SHIFT-10)); | ||
135 | } | ||
136 | |||
137 | #ifdef CONFIG_BLK_DEV_INITRD | ||
138 | void free_initrd_mem(unsigned long start, unsigned long end) | ||
139 | { | ||
140 | int pages = 0; | ||
141 | for (; start < end; start += PAGE_SIZE) { | ||
142 | ClearPageReserved(virt_to_page(start)); | ||
143 | init_page_count(virt_to_page(start)); | ||
144 | free_page(start); | ||
145 | totalram_pages++; | ||
146 | pages++; | ||
147 | } | ||
148 | printk ("Freeing initrd memory: %dk freed\n", pages); | ||
149 | } | ||
150 | #endif | ||
diff --git a/arch/m68knommu/mm/init.c b/arch/m68k/mm/init_no.c index 8a6653f56bd8..8a6653f56bd8 100644 --- a/arch/m68knommu/mm/init.c +++ b/arch/m68k/mm/init_no.c | |||
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index 69345849454b..a373d136b2b2 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c | |||
@@ -1,367 +1,5 @@ | |||
1 | /* | 1 | #ifdef CONFIG_MMU |
2 | * linux/arch/m68k/mm/kmap.c | 2 | #include "kmap_mm.c" |
3 | * | ||
4 | * Copyright (C) 1997 Roman Hodek | ||
5 | * | ||
6 | * 10/01/99 cleaned up the code and changing to the same interface | ||
7 | * used by other architectures /Roman Zippel | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/vmalloc.h> | ||
17 | |||
18 | #include <asm/setup.h> | ||
19 | #include <asm/segment.h> | ||
20 | #include <asm/page.h> | ||
21 | #include <asm/pgalloc.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <asm/system.h> | ||
24 | |||
25 | #undef DEBUG | ||
26 | |||
27 | #define PTRTREESIZE (256*1024) | ||
28 | |||
29 | /* | ||
30 | * For 040/060 we can use the virtual memory area like other architectures, | ||
31 | * but for 020/030 we want to use early termination page descriptor and we | ||
32 | * can't mix this with normal page descriptors, so we have to copy that code | ||
33 | * (mm/vmalloc.c) and return appriorate aligned addresses. | ||
34 | */ | ||
35 | |||
36 | #ifdef CPU_M68040_OR_M68060_ONLY | ||
37 | |||
38 | #define IO_SIZE PAGE_SIZE | ||
39 | |||
40 | static inline struct vm_struct *get_io_area(unsigned long size) | ||
41 | { | ||
42 | return get_vm_area(size, VM_IOREMAP); | ||
43 | } | ||
44 | |||
45 | |||
46 | static inline void free_io_area(void *addr) | ||
47 | { | ||
48 | vfree((void *)(PAGE_MASK & (unsigned long)addr)); | ||
49 | } | ||
50 | |||
51 | #else | 3 | #else |
52 | 4 | #include "kmap_no.c" | |
53 | #define IO_SIZE (256*1024) | ||
54 | |||
55 | static struct vm_struct *iolist; | ||
56 | |||
57 | static struct vm_struct *get_io_area(unsigned long size) | ||
58 | { | ||
59 | unsigned long addr; | ||
60 | struct vm_struct **p, *tmp, *area; | ||
61 | |||
62 | area = kmalloc(sizeof(*area), GFP_KERNEL); | ||
63 | if (!area) | ||
64 | return NULL; | ||
65 | addr = KMAP_START; | ||
66 | for (p = &iolist; (tmp = *p) ; p = &tmp->next) { | ||
67 | if (size + addr < (unsigned long)tmp->addr) | ||
68 | break; | ||
69 | if (addr > KMAP_END-size) { | ||
70 | kfree(area); | ||
71 | return NULL; | ||
72 | } | ||
73 | addr = tmp->size + (unsigned long)tmp->addr; | ||
74 | } | ||
75 | area->addr = (void *)addr; | ||
76 | area->size = size + IO_SIZE; | ||
77 | area->next = *p; | ||
78 | *p = area; | ||
79 | return area; | ||
80 | } | ||
81 | |||
82 | static inline void free_io_area(void *addr) | ||
83 | { | ||
84 | struct vm_struct **p, *tmp; | ||
85 | |||
86 | if (!addr) | ||
87 | return; | ||
88 | addr = (void *)((unsigned long)addr & -IO_SIZE); | ||
89 | for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { | ||
90 | if (tmp->addr == addr) { | ||
91 | *p = tmp->next; | ||
92 | __iounmap(tmp->addr, tmp->size); | ||
93 | kfree(tmp); | ||
94 | return; | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
99 | #endif | 5 | #endif |
100 | |||
101 | /* | ||
102 | * Map some physical address range into the kernel address space. | ||
103 | */ | ||
104 | /* Rewritten by Andreas Schwab to remove all races. */ | ||
105 | |||
106 | void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) | ||
107 | { | ||
108 | struct vm_struct *area; | ||
109 | unsigned long virtaddr, retaddr; | ||
110 | long offset; | ||
111 | pgd_t *pgd_dir; | ||
112 | pmd_t *pmd_dir; | ||
113 | pte_t *pte_dir; | ||
114 | |||
115 | /* | ||
116 | * Don't allow mappings that wrap.. | ||
117 | */ | ||
118 | if (!size || physaddr > (unsigned long)(-size)) | ||
119 | return NULL; | ||
120 | |||
121 | #ifdef CONFIG_AMIGA | ||
122 | if (MACH_IS_AMIGA) { | ||
123 | if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000) | ||
124 | && (cacheflag == IOMAP_NOCACHE_SER)) | ||
125 | return (void __iomem *)physaddr; | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | #ifdef DEBUG | ||
130 | printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag); | ||
131 | #endif | ||
132 | /* | ||
133 | * Mappings have to be aligned | ||
134 | */ | ||
135 | offset = physaddr & (IO_SIZE - 1); | ||
136 | physaddr &= -IO_SIZE; | ||
137 | size = (size + offset + IO_SIZE - 1) & -IO_SIZE; | ||
138 | |||
139 | /* | ||
140 | * Ok, go for it.. | ||
141 | */ | ||
142 | area = get_io_area(size); | ||
143 | if (!area) | ||
144 | return NULL; | ||
145 | |||
146 | virtaddr = (unsigned long)area->addr; | ||
147 | retaddr = virtaddr + offset; | ||
148 | #ifdef DEBUG | ||
149 | printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr); | ||
150 | #endif | ||
151 | |||
152 | /* | ||
153 | * add cache and table flags to physical address | ||
154 | */ | ||
155 | if (CPU_IS_040_OR_060) { | ||
156 | physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 | | ||
157 | _PAGE_ACCESSED | _PAGE_DIRTY); | ||
158 | switch (cacheflag) { | ||
159 | case IOMAP_FULL_CACHING: | ||
160 | physaddr |= _PAGE_CACHE040; | ||
161 | break; | ||
162 | case IOMAP_NOCACHE_SER: | ||
163 | default: | ||
164 | physaddr |= _PAGE_NOCACHE_S; | ||
165 | break; | ||
166 | case IOMAP_NOCACHE_NONSER: | ||
167 | physaddr |= _PAGE_NOCACHE; | ||
168 | break; | ||
169 | case IOMAP_WRITETHROUGH: | ||
170 | physaddr |= _PAGE_CACHE040W; | ||
171 | break; | ||
172 | } | ||
173 | } else { | ||
174 | physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); | ||
175 | switch (cacheflag) { | ||
176 | case IOMAP_NOCACHE_SER: | ||
177 | case IOMAP_NOCACHE_NONSER: | ||
178 | default: | ||
179 | physaddr |= _PAGE_NOCACHE030; | ||
180 | break; | ||
181 | case IOMAP_FULL_CACHING: | ||
182 | case IOMAP_WRITETHROUGH: | ||
183 | break; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | while ((long)size > 0) { | ||
188 | #ifdef DEBUG | ||
189 | if (!(virtaddr & (PTRTREESIZE-1))) | ||
190 | printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); | ||
191 | #endif | ||
192 | pgd_dir = pgd_offset_k(virtaddr); | ||
193 | pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); | ||
194 | if (!pmd_dir) { | ||
195 | printk("ioremap: no mem for pmd_dir\n"); | ||
196 | return NULL; | ||
197 | } | ||
198 | |||
199 | if (CPU_IS_020_OR_030) { | ||
200 | pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr; | ||
201 | physaddr += PTRTREESIZE; | ||
202 | virtaddr += PTRTREESIZE; | ||
203 | size -= PTRTREESIZE; | ||
204 | } else { | ||
205 | pte_dir = pte_alloc_kernel(pmd_dir, virtaddr); | ||
206 | if (!pte_dir) { | ||
207 | printk("ioremap: no mem for pte_dir\n"); | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
211 | pte_val(*pte_dir) = physaddr; | ||
212 | virtaddr += PAGE_SIZE; | ||
213 | physaddr += PAGE_SIZE; | ||
214 | size -= PAGE_SIZE; | ||
215 | } | ||
216 | } | ||
217 | #ifdef DEBUG | ||
218 | printk("\n"); | ||
219 | #endif | ||
220 | flush_tlb_all(); | ||
221 | |||
222 | return (void __iomem *)retaddr; | ||
223 | } | ||
224 | EXPORT_SYMBOL(__ioremap); | ||
225 | |||
226 | /* | ||
227 | * Unmap a ioremap()ed region again | ||
228 | */ | ||
229 | void iounmap(void __iomem *addr) | ||
230 | { | ||
231 | #ifdef CONFIG_AMIGA | ||
232 | if ((!MACH_IS_AMIGA) || | ||
233 | (((unsigned long)addr < 0x40000000) || | ||
234 | ((unsigned long)addr > 0x60000000))) | ||
235 | free_io_area((__force void *)addr); | ||
236 | #else | ||
237 | free_io_area((__force void *)addr); | ||
238 | #endif | ||
239 | } | ||
240 | EXPORT_SYMBOL(iounmap); | ||
241 | |||
242 | /* | ||
243 | * __iounmap unmaps nearly everything, so be careful | ||
244 | * it doesn't free currently pointer/page tables anymore but it | ||
245 | * wans't used anyway and might be added later. | ||
246 | */ | ||
247 | void __iounmap(void *addr, unsigned long size) | ||
248 | { | ||
249 | unsigned long virtaddr = (unsigned long)addr; | ||
250 | pgd_t *pgd_dir; | ||
251 | pmd_t *pmd_dir; | ||
252 | pte_t *pte_dir; | ||
253 | |||
254 | while ((long)size > 0) { | ||
255 | pgd_dir = pgd_offset_k(virtaddr); | ||
256 | if (pgd_bad(*pgd_dir)) { | ||
257 | printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); | ||
258 | pgd_clear(pgd_dir); | ||
259 | return; | ||
260 | } | ||
261 | pmd_dir = pmd_offset(pgd_dir, virtaddr); | ||
262 | |||
263 | if (CPU_IS_020_OR_030) { | ||
264 | int pmd_off = (virtaddr/PTRTREESIZE) & 15; | ||
265 | int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; | ||
266 | |||
267 | if (pmd_type == _PAGE_PRESENT) { | ||
268 | pmd_dir->pmd[pmd_off] = 0; | ||
269 | virtaddr += PTRTREESIZE; | ||
270 | size -= PTRTREESIZE; | ||
271 | continue; | ||
272 | } else if (pmd_type == 0) | ||
273 | continue; | ||
274 | } | ||
275 | |||
276 | if (pmd_bad(*pmd_dir)) { | ||
277 | printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); | ||
278 | pmd_clear(pmd_dir); | ||
279 | return; | ||
280 | } | ||
281 | pte_dir = pte_offset_kernel(pmd_dir, virtaddr); | ||
282 | |||
283 | pte_val(*pte_dir) = 0; | ||
284 | virtaddr += PAGE_SIZE; | ||
285 | size -= PAGE_SIZE; | ||
286 | } | ||
287 | |||
288 | flush_tlb_all(); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Set new cache mode for some kernel address space. | ||
293 | * The caller must push data for that range itself, if such data may already | ||
294 | * be in the cache. | ||
295 | */ | ||
296 | void kernel_set_cachemode(void *addr, unsigned long size, int cmode) | ||
297 | { | ||
298 | unsigned long virtaddr = (unsigned long)addr; | ||
299 | pgd_t *pgd_dir; | ||
300 | pmd_t *pmd_dir; | ||
301 | pte_t *pte_dir; | ||
302 | |||
303 | if (CPU_IS_040_OR_060) { | ||
304 | switch (cmode) { | ||
305 | case IOMAP_FULL_CACHING: | ||
306 | cmode = _PAGE_CACHE040; | ||
307 | break; | ||
308 | case IOMAP_NOCACHE_SER: | ||
309 | default: | ||
310 | cmode = _PAGE_NOCACHE_S; | ||
311 | break; | ||
312 | case IOMAP_NOCACHE_NONSER: | ||
313 | cmode = _PAGE_NOCACHE; | ||
314 | break; | ||
315 | case IOMAP_WRITETHROUGH: | ||
316 | cmode = _PAGE_CACHE040W; | ||
317 | break; | ||
318 | } | ||
319 | } else { | ||
320 | switch (cmode) { | ||
321 | case IOMAP_NOCACHE_SER: | ||
322 | case IOMAP_NOCACHE_NONSER: | ||
323 | default: | ||
324 | cmode = _PAGE_NOCACHE030; | ||
325 | break; | ||
326 | case IOMAP_FULL_CACHING: | ||
327 | case IOMAP_WRITETHROUGH: | ||
328 | cmode = 0; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | while ((long)size > 0) { | ||
333 | pgd_dir = pgd_offset_k(virtaddr); | ||
334 | if (pgd_bad(*pgd_dir)) { | ||
335 | printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); | ||
336 | pgd_clear(pgd_dir); | ||
337 | return; | ||
338 | } | ||
339 | pmd_dir = pmd_offset(pgd_dir, virtaddr); | ||
340 | |||
341 | if (CPU_IS_020_OR_030) { | ||
342 | int pmd_off = (virtaddr/PTRTREESIZE) & 15; | ||
343 | |||
344 | if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) { | ||
345 | pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] & | ||
346 | _CACHEMASK040) | cmode; | ||
347 | virtaddr += PTRTREESIZE; | ||
348 | size -= PTRTREESIZE; | ||
349 | continue; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | if (pmd_bad(*pmd_dir)) { | ||
354 | printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); | ||
355 | pmd_clear(pmd_dir); | ||
356 | return; | ||
357 | } | ||
358 | pte_dir = pte_offset_kernel(pmd_dir, virtaddr); | ||
359 | |||
360 | pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode; | ||
361 | virtaddr += PAGE_SIZE; | ||
362 | size -= PAGE_SIZE; | ||
363 | } | ||
364 | |||
365 | flush_tlb_all(); | ||
366 | } | ||
367 | EXPORT_SYMBOL(kernel_set_cachemode); | ||
diff --git a/arch/m68k/mm/kmap_mm.c b/arch/m68k/mm/kmap_mm.c new file mode 100644 index 000000000000..69345849454b --- /dev/null +++ b/arch/m68k/mm/kmap_mm.c | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/mm/kmap.c | ||
3 | * | ||
4 | * Copyright (C) 1997 Roman Hodek | ||
5 | * | ||
6 | * 10/01/99 cleaned up the code and changing to the same interface | ||
7 | * used by other architectures /Roman Zippel | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/vmalloc.h> | ||
17 | |||
18 | #include <asm/setup.h> | ||
19 | #include <asm/segment.h> | ||
20 | #include <asm/page.h> | ||
21 | #include <asm/pgalloc.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <asm/system.h> | ||
24 | |||
25 | #undef DEBUG | ||
26 | |||
27 | #define PTRTREESIZE (256*1024) | ||
28 | |||
29 | /* | ||
30 | * For 040/060 we can use the virtual memory area like other architectures, | ||
31 | * but for 020/030 we want to use early termination page descriptor and we | ||
32 | * can't mix this with normal page descriptors, so we have to copy that code | ||
33 | * (mm/vmalloc.c) and return appriorate aligned addresses. | ||
34 | */ | ||
35 | |||
36 | #ifdef CPU_M68040_OR_M68060_ONLY | ||
37 | |||
38 | #define IO_SIZE PAGE_SIZE | ||
39 | |||
40 | static inline struct vm_struct *get_io_area(unsigned long size) | ||
41 | { | ||
42 | return get_vm_area(size, VM_IOREMAP); | ||
43 | } | ||
44 | |||
45 | |||
46 | static inline void free_io_area(void *addr) | ||
47 | { | ||
48 | vfree((void *)(PAGE_MASK & (unsigned long)addr)); | ||
49 | } | ||
50 | |||
51 | #else | ||
52 | |||
53 | #define IO_SIZE (256*1024) | ||
54 | |||
55 | static struct vm_struct *iolist; | ||
56 | |||
57 | static struct vm_struct *get_io_area(unsigned long size) | ||
58 | { | ||
59 | unsigned long addr; | ||
60 | struct vm_struct **p, *tmp, *area; | ||
61 | |||
62 | area = kmalloc(sizeof(*area), GFP_KERNEL); | ||
63 | if (!area) | ||
64 | return NULL; | ||
65 | addr = KMAP_START; | ||
66 | for (p = &iolist; (tmp = *p) ; p = &tmp->next) { | ||
67 | if (size + addr < (unsigned long)tmp->addr) | ||
68 | break; | ||
69 | if (addr > KMAP_END-size) { | ||
70 | kfree(area); | ||
71 | return NULL; | ||
72 | } | ||
73 | addr = tmp->size + (unsigned long)tmp->addr; | ||
74 | } | ||
75 | area->addr = (void *)addr; | ||
76 | area->size = size + IO_SIZE; | ||
77 | area->next = *p; | ||
78 | *p = area; | ||
79 | return area; | ||
80 | } | ||
81 | |||
82 | static inline void free_io_area(void *addr) | ||
83 | { | ||
84 | struct vm_struct **p, *tmp; | ||
85 | |||
86 | if (!addr) | ||
87 | return; | ||
88 | addr = (void *)((unsigned long)addr & -IO_SIZE); | ||
89 | for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { | ||
90 | if (tmp->addr == addr) { | ||
91 | *p = tmp->next; | ||
92 | __iounmap(tmp->addr, tmp->size); | ||
93 | kfree(tmp); | ||
94 | return; | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
99 | #endif | ||
100 | |||
101 | /* | ||
102 | * Map some physical address range into the kernel address space. | ||
103 | */ | ||
104 | /* Rewritten by Andreas Schwab to remove all races. */ | ||
105 | |||
106 | void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) | ||
107 | { | ||
108 | struct vm_struct *area; | ||
109 | unsigned long virtaddr, retaddr; | ||
110 | long offset; | ||
111 | pgd_t *pgd_dir; | ||
112 | pmd_t *pmd_dir; | ||
113 | pte_t *pte_dir; | ||
114 | |||
115 | /* | ||
116 | * Don't allow mappings that wrap.. | ||
117 | */ | ||
118 | if (!size || physaddr > (unsigned long)(-size)) | ||
119 | return NULL; | ||
120 | |||
121 | #ifdef CONFIG_AMIGA | ||
122 | if (MACH_IS_AMIGA) { | ||
123 | if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000) | ||
124 | && (cacheflag == IOMAP_NOCACHE_SER)) | ||
125 | return (void __iomem *)physaddr; | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | #ifdef DEBUG | ||
130 | printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag); | ||
131 | #endif | ||
132 | /* | ||
133 | * Mappings have to be aligned | ||
134 | */ | ||
135 | offset = physaddr & (IO_SIZE - 1); | ||
136 | physaddr &= -IO_SIZE; | ||
137 | size = (size + offset + IO_SIZE - 1) & -IO_SIZE; | ||
138 | |||
139 | /* | ||
140 | * Ok, go for it.. | ||
141 | */ | ||
142 | area = get_io_area(size); | ||
143 | if (!area) | ||
144 | return NULL; | ||
145 | |||
146 | virtaddr = (unsigned long)area->addr; | ||
147 | retaddr = virtaddr + offset; | ||
148 | #ifdef DEBUG | ||
149 | printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr); | ||
150 | #endif | ||
151 | |||
152 | /* | ||
153 | * add cache and table flags to physical address | ||
154 | */ | ||
155 | if (CPU_IS_040_OR_060) { | ||
156 | physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 | | ||
157 | _PAGE_ACCESSED | _PAGE_DIRTY); | ||
158 | switch (cacheflag) { | ||
159 | case IOMAP_FULL_CACHING: | ||
160 | physaddr |= _PAGE_CACHE040; | ||
161 | break; | ||
162 | case IOMAP_NOCACHE_SER: | ||
163 | default: | ||
164 | physaddr |= _PAGE_NOCACHE_S; | ||
165 | break; | ||
166 | case IOMAP_NOCACHE_NONSER: | ||
167 | physaddr |= _PAGE_NOCACHE; | ||
168 | break; | ||
169 | case IOMAP_WRITETHROUGH: | ||
170 | physaddr |= _PAGE_CACHE040W; | ||
171 | break; | ||
172 | } | ||
173 | } else { | ||
174 | physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); | ||
175 | switch (cacheflag) { | ||
176 | case IOMAP_NOCACHE_SER: | ||
177 | case IOMAP_NOCACHE_NONSER: | ||
178 | default: | ||
179 | physaddr |= _PAGE_NOCACHE030; | ||
180 | break; | ||
181 | case IOMAP_FULL_CACHING: | ||
182 | case IOMAP_WRITETHROUGH: | ||
183 | break; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | while ((long)size > 0) { | ||
188 | #ifdef DEBUG | ||
189 | if (!(virtaddr & (PTRTREESIZE-1))) | ||
190 | printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); | ||
191 | #endif | ||
192 | pgd_dir = pgd_offset_k(virtaddr); | ||
193 | pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); | ||
194 | if (!pmd_dir) { | ||
195 | printk("ioremap: no mem for pmd_dir\n"); | ||
196 | return NULL; | ||
197 | } | ||
198 | |||
199 | if (CPU_IS_020_OR_030) { | ||
200 | pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr; | ||
201 | physaddr += PTRTREESIZE; | ||
202 | virtaddr += PTRTREESIZE; | ||
203 | size -= PTRTREESIZE; | ||
204 | } else { | ||
205 | pte_dir = pte_alloc_kernel(pmd_dir, virtaddr); | ||
206 | if (!pte_dir) { | ||
207 | printk("ioremap: no mem for pte_dir\n"); | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
211 | pte_val(*pte_dir) = physaddr; | ||
212 | virtaddr += PAGE_SIZE; | ||
213 | physaddr += PAGE_SIZE; | ||
214 | size -= PAGE_SIZE; | ||
215 | } | ||
216 | } | ||
217 | #ifdef DEBUG | ||
218 | printk("\n"); | ||
219 | #endif | ||
220 | flush_tlb_all(); | ||
221 | |||
222 | return (void __iomem *)retaddr; | ||
223 | } | ||
224 | EXPORT_SYMBOL(__ioremap); | ||
225 | |||
226 | /* | ||
227 | * Unmap a ioremap()ed region again | ||
228 | */ | ||
229 | void iounmap(void __iomem *addr) | ||
230 | { | ||
231 | #ifdef CONFIG_AMIGA | ||
232 | if ((!MACH_IS_AMIGA) || | ||
233 | (((unsigned long)addr < 0x40000000) || | ||
234 | ((unsigned long)addr > 0x60000000))) | ||
235 | free_io_area((__force void *)addr); | ||
236 | #else | ||
237 | free_io_area((__force void *)addr); | ||
238 | #endif | ||
239 | } | ||
240 | EXPORT_SYMBOL(iounmap); | ||
241 | |||
242 | /* | ||
243 | * __iounmap unmaps nearly everything, so be careful | ||
244 | * it doesn't free currently pointer/page tables anymore but it | ||
245 | * wans't used anyway and might be added later. | ||
246 | */ | ||
247 | void __iounmap(void *addr, unsigned long size) | ||
248 | { | ||
249 | unsigned long virtaddr = (unsigned long)addr; | ||
250 | pgd_t *pgd_dir; | ||
251 | pmd_t *pmd_dir; | ||
252 | pte_t *pte_dir; | ||
253 | |||
254 | while ((long)size > 0) { | ||
255 | pgd_dir = pgd_offset_k(virtaddr); | ||
256 | if (pgd_bad(*pgd_dir)) { | ||
257 | printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); | ||
258 | pgd_clear(pgd_dir); | ||
259 | return; | ||
260 | } | ||
261 | pmd_dir = pmd_offset(pgd_dir, virtaddr); | ||
262 | |||
263 | if (CPU_IS_020_OR_030) { | ||
264 | int pmd_off = (virtaddr/PTRTREESIZE) & 15; | ||
265 | int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; | ||
266 | |||
267 | if (pmd_type == _PAGE_PRESENT) { | ||
268 | pmd_dir->pmd[pmd_off] = 0; | ||
269 | virtaddr += PTRTREESIZE; | ||
270 | size -= PTRTREESIZE; | ||
271 | continue; | ||
272 | } else if (pmd_type == 0) | ||
273 | continue; | ||
274 | } | ||
275 | |||
276 | if (pmd_bad(*pmd_dir)) { | ||
277 | printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); | ||
278 | pmd_clear(pmd_dir); | ||
279 | return; | ||
280 | } | ||
281 | pte_dir = pte_offset_kernel(pmd_dir, virtaddr); | ||
282 | |||
283 | pte_val(*pte_dir) = 0; | ||
284 | virtaddr += PAGE_SIZE; | ||
285 | size -= PAGE_SIZE; | ||
286 | } | ||
287 | |||
288 | flush_tlb_all(); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Set new cache mode for some kernel address space. | ||
293 | * The caller must push data for that range itself, if such data may already | ||
294 | * be in the cache. | ||
295 | */ | ||
296 | void kernel_set_cachemode(void *addr, unsigned long size, int cmode) | ||
297 | { | ||
298 | unsigned long virtaddr = (unsigned long)addr; | ||
299 | pgd_t *pgd_dir; | ||
300 | pmd_t *pmd_dir; | ||
301 | pte_t *pte_dir; | ||
302 | |||
303 | if (CPU_IS_040_OR_060) { | ||
304 | switch (cmode) { | ||
305 | case IOMAP_FULL_CACHING: | ||
306 | cmode = _PAGE_CACHE040; | ||
307 | break; | ||
308 | case IOMAP_NOCACHE_SER: | ||
309 | default: | ||
310 | cmode = _PAGE_NOCACHE_S; | ||
311 | break; | ||
312 | case IOMAP_NOCACHE_NONSER: | ||
313 | cmode = _PAGE_NOCACHE; | ||
314 | break; | ||
315 | case IOMAP_WRITETHROUGH: | ||
316 | cmode = _PAGE_CACHE040W; | ||
317 | break; | ||
318 | } | ||
319 | } else { | ||
320 | switch (cmode) { | ||
321 | case IOMAP_NOCACHE_SER: | ||
322 | case IOMAP_NOCACHE_NONSER: | ||
323 | default: | ||
324 | cmode = _PAGE_NOCACHE030; | ||
325 | break; | ||
326 | case IOMAP_FULL_CACHING: | ||
327 | case IOMAP_WRITETHROUGH: | ||
328 | cmode = 0; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | while ((long)size > 0) { | ||
333 | pgd_dir = pgd_offset_k(virtaddr); | ||
334 | if (pgd_bad(*pgd_dir)) { | ||
335 | printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); | ||
336 | pgd_clear(pgd_dir); | ||
337 | return; | ||
338 | } | ||
339 | pmd_dir = pmd_offset(pgd_dir, virtaddr); | ||
340 | |||
341 | if (CPU_IS_020_OR_030) { | ||
342 | int pmd_off = (virtaddr/PTRTREESIZE) & 15; | ||
343 | |||
344 | if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) { | ||
345 | pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] & | ||
346 | _CACHEMASK040) | cmode; | ||
347 | virtaddr += PTRTREESIZE; | ||
348 | size -= PTRTREESIZE; | ||
349 | continue; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | if (pmd_bad(*pmd_dir)) { | ||
354 | printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); | ||
355 | pmd_clear(pmd_dir); | ||
356 | return; | ||
357 | } | ||
358 | pte_dir = pte_offset_kernel(pmd_dir, virtaddr); | ||
359 | |||
360 | pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode; | ||
361 | virtaddr += PAGE_SIZE; | ||
362 | size -= PAGE_SIZE; | ||
363 | } | ||
364 | |||
365 | flush_tlb_all(); | ||
366 | } | ||
367 | EXPORT_SYMBOL(kernel_set_cachemode); | ||
diff --git a/arch/m68knommu/mm/kmap.c b/arch/m68k/mm/kmap_no.c index ece8d5ad4e6c..ece8d5ad4e6c 100644 --- a/arch/m68knommu/mm/kmap.c +++ b/arch/m68k/mm/kmap_no.c | |||
diff --git a/arch/m68knommu/platform/5206/Makefile b/arch/m68k/platform/5206/Makefile index b5db05625cfa..b5db05625cfa 100644 --- a/arch/m68knommu/platform/5206/Makefile +++ b/arch/m68k/platform/5206/Makefile | |||
diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68k/platform/5206/config.c index 9c335465e66d..9c335465e66d 100644 --- a/arch/m68knommu/platform/5206/config.c +++ b/arch/m68k/platform/5206/config.c | |||
diff --git a/arch/m68knommu/platform/5206/gpio.c b/arch/m68k/platform/5206/gpio.c index b9ab4a120f28..b9ab4a120f28 100644 --- a/arch/m68knommu/platform/5206/gpio.c +++ b/arch/m68k/platform/5206/gpio.c | |||
diff --git a/arch/m68knommu/platform/5206e/Makefile b/arch/m68k/platform/5206e/Makefile index b5db05625cfa..b5db05625cfa 100644 --- a/arch/m68knommu/platform/5206e/Makefile +++ b/arch/m68k/platform/5206e/Makefile | |||
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68k/platform/5206e/config.c index 942397984c66..942397984c66 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68k/platform/5206e/config.c | |||
diff --git a/arch/m68knommu/platform/5206e/gpio.c b/arch/m68k/platform/5206e/gpio.c index b9ab4a120f28..b9ab4a120f28 100644 --- a/arch/m68knommu/platform/5206e/gpio.c +++ b/arch/m68k/platform/5206e/gpio.c | |||
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68k/platform/520x/Makefile index ad3f4e5a57ce..ad3f4e5a57ce 100644 --- a/arch/m68knommu/platform/520x/Makefile +++ b/arch/m68k/platform/520x/Makefile | |||
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68k/platform/520x/config.c index 621238f1a219..621238f1a219 100644 --- a/arch/m68knommu/platform/520x/config.c +++ b/arch/m68k/platform/520x/config.c | |||
diff --git a/arch/m68knommu/platform/520x/gpio.c b/arch/m68k/platform/520x/gpio.c index d757328563d1..d757328563d1 100644 --- a/arch/m68knommu/platform/520x/gpio.c +++ b/arch/m68k/platform/520x/gpio.c | |||
diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68k/platform/523x/Makefile index c04b8f71c88c..c04b8f71c88c 100644 --- a/arch/m68knommu/platform/523x/Makefile +++ b/arch/m68k/platform/523x/Makefile | |||
diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68k/platform/523x/config.c index 418a76feb1e3..418a76feb1e3 100644 --- a/arch/m68knommu/platform/523x/config.c +++ b/arch/m68k/platform/523x/config.c | |||
diff --git a/arch/m68knommu/platform/523x/gpio.c b/arch/m68k/platform/523x/gpio.c index 327ebf142c8e..327ebf142c8e 100644 --- a/arch/m68knommu/platform/523x/gpio.c +++ b/arch/m68k/platform/523x/gpio.c | |||
diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68k/platform/5249/Makefile index 4bed30fd0073..4bed30fd0073 100644 --- a/arch/m68knommu/platform/5249/Makefile +++ b/arch/m68k/platform/5249/Makefile | |||
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68k/platform/5249/config.c index ceb31e5744a6..ceb31e5744a6 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68k/platform/5249/config.c | |||
diff --git a/arch/m68knommu/platform/5249/gpio.c b/arch/m68k/platform/5249/gpio.c index 2b56c6ef65bf..2b56c6ef65bf 100644 --- a/arch/m68knommu/platform/5249/gpio.c +++ b/arch/m68k/platform/5249/gpio.c | |||
diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68k/platform/5249/intc2.c index 8f4b63e17366..8f4b63e17366 100644 --- a/arch/m68knommu/platform/5249/intc2.c +++ b/arch/m68k/platform/5249/intc2.c | |||
diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68k/platform/5272/Makefile index 34110fc14301..34110fc14301 100644 --- a/arch/m68knommu/platform/5272/Makefile +++ b/arch/m68k/platform/5272/Makefile | |||
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68k/platform/5272/config.c index 65bb582734e1..65bb582734e1 100644 --- a/arch/m68knommu/platform/5272/config.c +++ b/arch/m68k/platform/5272/config.c | |||
diff --git a/arch/m68knommu/platform/5272/gpio.c b/arch/m68k/platform/5272/gpio.c index 57ac10a5d7f7..57ac10a5d7f7 100644 --- a/arch/m68knommu/platform/5272/gpio.c +++ b/arch/m68k/platform/5272/gpio.c | |||
diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68k/platform/5272/intc.c index 969ff0a467c6..969ff0a467c6 100644 --- a/arch/m68knommu/platform/5272/intc.c +++ b/arch/m68k/platform/5272/intc.c | |||
diff --git a/arch/m68knommu/platform/527x/Makefile b/arch/m68k/platform/527x/Makefile index 6ac4b57370ea..6ac4b57370ea 100644 --- a/arch/m68knommu/platform/527x/Makefile +++ b/arch/m68k/platform/527x/Makefile | |||
diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68k/platform/527x/config.c index fa359593b613..fa359593b613 100644 --- a/arch/m68knommu/platform/527x/config.c +++ b/arch/m68k/platform/527x/config.c | |||
diff --git a/arch/m68knommu/platform/527x/gpio.c b/arch/m68k/platform/527x/gpio.c index 205da0aa0f2d..205da0aa0f2d 100644 --- a/arch/m68knommu/platform/527x/gpio.c +++ b/arch/m68k/platform/527x/gpio.c | |||
diff --git a/arch/m68knommu/platform/528x/Makefile b/arch/m68k/platform/528x/Makefile index 6ac4b57370ea..6ac4b57370ea 100644 --- a/arch/m68knommu/platform/528x/Makefile +++ b/arch/m68k/platform/528x/Makefile | |||
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68k/platform/528x/config.c index ac39fc661219..ac39fc661219 100644 --- a/arch/m68knommu/platform/528x/config.c +++ b/arch/m68k/platform/528x/config.c | |||
diff --git a/arch/m68knommu/platform/528x/gpio.c b/arch/m68k/platform/528x/gpio.c index 526db665d87e..526db665d87e 100644 --- a/arch/m68knommu/platform/528x/gpio.c +++ b/arch/m68k/platform/528x/gpio.c | |||
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68k/platform/5307/Makefile index d4293b791f2e..d4293b791f2e 100644 --- a/arch/m68knommu/platform/5307/Makefile +++ b/arch/m68k/platform/5307/Makefile | |||
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68k/platform/5307/config.c index 00900ac06a9c..00900ac06a9c 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68k/platform/5307/config.c | |||
diff --git a/arch/m68knommu/platform/5307/gpio.c b/arch/m68k/platform/5307/gpio.c index 5850612b4a38..5850612b4a38 100644 --- a/arch/m68knommu/platform/5307/gpio.c +++ b/arch/m68k/platform/5307/gpio.c | |||
diff --git a/arch/m68knommu/platform/5307/nettel.c b/arch/m68k/platform/5307/nettel.c index e925ea4602f8..e925ea4602f8 100644 --- a/arch/m68knommu/platform/5307/nettel.c +++ b/arch/m68k/platform/5307/nettel.c | |||
diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68k/platform/532x/Makefile index ce01669399c6..ce01669399c6 100644 --- a/arch/m68knommu/platform/532x/Makefile +++ b/arch/m68k/platform/532x/Makefile | |||
diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68k/platform/532x/config.c index ca51323f957b..ca51323f957b 100644 --- a/arch/m68knommu/platform/532x/config.c +++ b/arch/m68k/platform/532x/config.c | |||
diff --git a/arch/m68knommu/platform/532x/gpio.c b/arch/m68k/platform/532x/gpio.c index 212a85deac90..212a85deac90 100644 --- a/arch/m68knommu/platform/532x/gpio.c +++ b/arch/m68k/platform/532x/gpio.c | |||
diff --git a/arch/m68knommu/platform/5407/Makefile b/arch/m68k/platform/5407/Makefile index e83fe148eddc..e83fe148eddc 100644 --- a/arch/m68knommu/platform/5407/Makefile +++ b/arch/m68k/platform/5407/Makefile | |||
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68k/platform/5407/config.c index 70ea789a400c..70ea789a400c 100644 --- a/arch/m68knommu/platform/5407/config.c +++ b/arch/m68k/platform/5407/config.c | |||
diff --git a/arch/m68knommu/platform/5407/gpio.c b/arch/m68k/platform/5407/gpio.c index 5850612b4a38..5850612b4a38 100644 --- a/arch/m68knommu/platform/5407/gpio.c +++ b/arch/m68k/platform/5407/gpio.c | |||
diff --git a/arch/m68knommu/platform/54xx/Makefile b/arch/m68k/platform/54xx/Makefile index 6cfd090ec3cd..6cfd090ec3cd 100644 --- a/arch/m68knommu/platform/54xx/Makefile +++ b/arch/m68k/platform/54xx/Makefile | |||
diff --git a/arch/m68knommu/platform/54xx/config.c b/arch/m68k/platform/54xx/config.c index 78130984db95..78130984db95 100644 --- a/arch/m68knommu/platform/54xx/config.c +++ b/arch/m68k/platform/54xx/config.c | |||
diff --git a/arch/m68knommu/platform/54xx/firebee.c b/arch/m68k/platform/54xx/firebee.c index 46d50534f981..46d50534f981 100644 --- a/arch/m68knommu/platform/54xx/firebee.c +++ b/arch/m68k/platform/54xx/firebee.c | |||
diff --git a/arch/m68knommu/platform/68328/Makefile b/arch/m68k/platform/68328/Makefile index 5e5435552d56..5e5435552d56 100644 --- a/arch/m68knommu/platform/68328/Makefile +++ b/arch/m68k/platform/68328/Makefile | |||
diff --git a/arch/m68knommu/platform/68328/bootlogo.h b/arch/m68k/platform/68328/bootlogo.h index 67bc2c17386e..67bc2c17386e 100644 --- a/arch/m68knommu/platform/68328/bootlogo.h +++ b/arch/m68k/platform/68328/bootlogo.h | |||
diff --git a/arch/m68knommu/platform/68328/bootlogo.pl b/arch/m68k/platform/68328/bootlogo.pl index b04ae3f50da5..b04ae3f50da5 100644 --- a/arch/m68knommu/platform/68328/bootlogo.pl +++ b/arch/m68k/platform/68328/bootlogo.pl | |||
diff --git a/arch/m68knommu/platform/68328/config.c b/arch/m68k/platform/68328/config.c index a7bd21deb00f..a7bd21deb00f 100644 --- a/arch/m68knommu/platform/68328/config.c +++ b/arch/m68k/platform/68328/config.c | |||
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68k/platform/68328/entry.S index 676960cf022a..676960cf022a 100644 --- a/arch/m68knommu/platform/68328/entry.S +++ b/arch/m68k/platform/68328/entry.S | |||
diff --git a/arch/m68knommu/platform/68328/head-de2.S b/arch/m68k/platform/68328/head-de2.S index f632fdcb93e9..f632fdcb93e9 100644 --- a/arch/m68knommu/platform/68328/head-de2.S +++ b/arch/m68k/platform/68328/head-de2.S | |||
diff --git a/arch/m68knommu/platform/68328/head-pilot.S b/arch/m68k/platform/68328/head-pilot.S index aecff532b343..aecff532b343 100644 --- a/arch/m68knommu/platform/68328/head-pilot.S +++ b/arch/m68k/platform/68328/head-pilot.S | |||
diff --git a/arch/m68knommu/platform/68328/head-ram.S b/arch/m68k/platform/68328/head-ram.S index 7f1aeeacb219..7f1aeeacb219 100644 --- a/arch/m68knommu/platform/68328/head-ram.S +++ b/arch/m68k/platform/68328/head-ram.S | |||
diff --git a/arch/m68knommu/platform/68328/head-rom.S b/arch/m68k/platform/68328/head-rom.S index 6ec77d3ea0b3..6ec77d3ea0b3 100644 --- a/arch/m68knommu/platform/68328/head-rom.S +++ b/arch/m68k/platform/68328/head-rom.S | |||
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68k/platform/68328/ints.c index e5631831a200..e5631831a200 100644 --- a/arch/m68knommu/platform/68328/ints.c +++ b/arch/m68k/platform/68328/ints.c | |||
diff --git a/arch/m68knommu/platform/68328/romvec.S b/arch/m68k/platform/68328/romvec.S index 31084466eae8..31084466eae8 100644 --- a/arch/m68knommu/platform/68328/romvec.S +++ b/arch/m68k/platform/68328/romvec.S | |||
diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68k/platform/68328/timers.c index 309f725995bf..309f725995bf 100644 --- a/arch/m68knommu/platform/68328/timers.c +++ b/arch/m68k/platform/68328/timers.c | |||
diff --git a/arch/m68knommu/platform/68360/Makefile b/arch/m68k/platform/68360/Makefile index cf5af73a5789..cf5af73a5789 100644 --- a/arch/m68knommu/platform/68360/Makefile +++ b/arch/m68k/platform/68360/Makefile | |||
diff --git a/arch/m68knommu/platform/68360/commproc.c b/arch/m68k/platform/68360/commproc.c index 8e4e10cc0080..8e4e10cc0080 100644 --- a/arch/m68knommu/platform/68360/commproc.c +++ b/arch/m68k/platform/68360/commproc.c | |||
diff --git a/arch/m68knommu/platform/68360/config.c b/arch/m68k/platform/68360/config.c index 9dd5bca38749..9dd5bca38749 100644 --- a/arch/m68knommu/platform/68360/config.c +++ b/arch/m68k/platform/68360/config.c | |||
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68k/platform/68360/entry.S index 46c1b18c9dcb..46c1b18c9dcb 100644 --- a/arch/m68knommu/platform/68360/entry.S +++ b/arch/m68k/platform/68360/entry.S | |||
diff --git a/arch/m68knommu/platform/68360/head-ram.S b/arch/m68k/platform/68360/head-ram.S index 8eb94fb6b971..8eb94fb6b971 100644 --- a/arch/m68knommu/platform/68360/head-ram.S +++ b/arch/m68k/platform/68360/head-ram.S | |||
diff --git a/arch/m68knommu/platform/68360/head-rom.S b/arch/m68k/platform/68360/head-rom.S index 97510e55b802..97510e55b802 100644 --- a/arch/m68knommu/platform/68360/head-rom.S +++ b/arch/m68k/platform/68360/head-rom.S | |||
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68k/platform/68360/ints.c index 8de3feb568c6..8de3feb568c6 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68k/platform/68360/ints.c | |||
diff --git a/arch/m68knommu/platform/68EZ328/Makefile b/arch/m68k/platform/68EZ328/Makefile index ee97735a242c..ee97735a242c 100644 --- a/arch/m68knommu/platform/68EZ328/Makefile +++ b/arch/m68k/platform/68EZ328/Makefile | |||
diff --git a/arch/m68knommu/platform/68EZ328/bootlogo.h b/arch/m68k/platform/68EZ328/bootlogo.h index e842bdae5839..e842bdae5839 100644 --- a/arch/m68knommu/platform/68EZ328/bootlogo.h +++ b/arch/m68k/platform/68EZ328/bootlogo.h | |||
diff --git a/arch/m68knommu/platform/68EZ328/config.c b/arch/m68k/platform/68EZ328/config.c index 1be1a16f6896..1be1a16f6896 100644 --- a/arch/m68knommu/platform/68EZ328/config.c +++ b/arch/m68k/platform/68EZ328/config.c | |||
diff --git a/arch/m68knommu/platform/68VZ328/Makefile b/arch/m68k/platform/68VZ328/Makefile index 447ffa0fd7c7..447ffa0fd7c7 100644 --- a/arch/m68knommu/platform/68VZ328/Makefile +++ b/arch/m68k/platform/68VZ328/Makefile | |||
diff --git a/arch/m68knommu/platform/68VZ328/config.c b/arch/m68k/platform/68VZ328/config.c index eabaabe8af36..eabaabe8af36 100644 --- a/arch/m68knommu/platform/68VZ328/config.c +++ b/arch/m68k/platform/68VZ328/config.c | |||
diff --git a/arch/m68knommu/platform/Makefile b/arch/m68k/platform/Makefile index fc932bf65d34..fc932bf65d34 100644 --- a/arch/m68knommu/platform/Makefile +++ b/arch/m68k/platform/Makefile | |||
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68k/platform/coldfire/Makefile index a8967baabd72..a8967baabd72 100644 --- a/arch/m68knommu/platform/coldfire/Makefile +++ b/arch/m68k/platform/coldfire/Makefile | |||
diff --git a/arch/m68knommu/platform/coldfire/cache.c b/arch/m68k/platform/coldfire/cache.c index 235d3c4f4f0f..235d3c4f4f0f 100644 --- a/arch/m68knommu/platform/coldfire/cache.c +++ b/arch/m68k/platform/coldfire/cache.c | |||
diff --git a/arch/m68knommu/platform/coldfire/clk.c b/arch/m68k/platform/coldfire/clk.c index 9f1260c5e2ad..9f1260c5e2ad 100644 --- a/arch/m68knommu/platform/coldfire/clk.c +++ b/arch/m68k/platform/coldfire/clk.c | |||
diff --git a/arch/m68knommu/platform/coldfire/dma.c b/arch/m68k/platform/coldfire/dma.c index e88b95e2cc62..e88b95e2cc62 100644 --- a/arch/m68knommu/platform/coldfire/dma.c +++ b/arch/m68k/platform/coldfire/dma.c | |||
diff --git a/arch/m68knommu/platform/coldfire/dma_timer.c b/arch/m68k/platform/coldfire/dma_timer.c index a5f562823d7a..a5f562823d7a 100644 --- a/arch/m68knommu/platform/coldfire/dma_timer.c +++ b/arch/m68k/platform/coldfire/dma_timer.c | |||
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S index 5837cf080b6d..5837cf080b6d 100644 --- a/arch/m68knommu/platform/coldfire/entry.S +++ b/arch/m68k/platform/coldfire/entry.S | |||
diff --git a/arch/m68knommu/platform/coldfire/gpio.c b/arch/m68k/platform/coldfire/gpio.c index ff0045793450..ff0045793450 100644 --- a/arch/m68knommu/platform/coldfire/gpio.c +++ b/arch/m68k/platform/coldfire/gpio.c | |||
diff --git a/arch/m68knommu/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index 129bff4956b5..129bff4956b5 100644 --- a/arch/m68knommu/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S | |||
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68k/platform/coldfire/intc-2.c index 2cbfbf035db9..2cbfbf035db9 100644 --- a/arch/m68knommu/platform/coldfire/intc-2.c +++ b/arch/m68k/platform/coldfire/intc-2.c | |||
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68k/platform/coldfire/intc-simr.c index e642b24ab729..e642b24ab729 100644 --- a/arch/m68knommu/platform/coldfire/intc-simr.c +++ b/arch/m68k/platform/coldfire/intc-simr.c | |||
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68k/platform/coldfire/intc.c index d648081a63f6..d648081a63f6 100644 --- a/arch/m68knommu/platform/coldfire/intc.c +++ b/arch/m68k/platform/coldfire/intc.c | |||
diff --git a/arch/m68knommu/platform/coldfire/pinmux.c b/arch/m68k/platform/coldfire/pinmux.c index 8c62b825939f..8c62b825939f 100644 --- a/arch/m68knommu/platform/coldfire/pinmux.c +++ b/arch/m68k/platform/coldfire/pinmux.c | |||
diff --git a/arch/m68knommu/platform/coldfire/pit.c b/arch/m68k/platform/coldfire/pit.c index c2b980926bec..c2b980926bec 100644 --- a/arch/m68knommu/platform/coldfire/pit.c +++ b/arch/m68k/platform/coldfire/pit.c | |||
diff --git a/arch/m68knommu/platform/coldfire/sltimers.c b/arch/m68k/platform/coldfire/sltimers.c index 0a1b937c3e18..0a1b937c3e18 100644 --- a/arch/m68knommu/platform/coldfire/sltimers.c +++ b/arch/m68k/platform/coldfire/sltimers.c | |||
diff --git a/arch/m68knommu/platform/coldfire/timers.c b/arch/m68k/platform/coldfire/timers.c index 60242f65fea9..60242f65fea9 100644 --- a/arch/m68knommu/platform/coldfire/timers.c +++ b/arch/m68k/platform/coldfire/timers.c | |||
diff --git a/arch/m68knommu/platform/coldfire/vectors.c b/arch/m68k/platform/coldfire/vectors.c index a21d3f870b7a..a21d3f870b7a 100644 --- a/arch/m68knommu/platform/coldfire/vectors.c +++ b/arch/m68k/platform/coldfire/vectors.c | |||
diff --git a/arch/m68knommu/Kconfig.debug b/arch/m68knommu/Kconfig.debug deleted file mode 100644 index ed6d9a83bfdb..000000000000 --- a/arch/m68knommu/Kconfig.debug +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | menu "Kernel hacking" | ||
2 | |||
3 | source "lib/Kconfig.debug" | ||
4 | |||
5 | config FULLDEBUG | ||
6 | bool "Full Symbolic/Source Debugging support" | ||
7 | help | ||
8 | Enable debugging symbols on kernel build. | ||
9 | |||
10 | config HIGHPROFILE | ||
11 | bool "Use fast second timer for profiling" | ||
12 | depends on COLDFIRE | ||
13 | help | ||
14 | Use a fast secondary clock to produce profiling information. | ||
15 | |||
16 | config BOOTPARAM | ||
17 | bool 'Compiled-in Kernel Boot Parameter' | ||
18 | |||
19 | config BOOTPARAM_STRING | ||
20 | string 'Kernel Boot Parameter' | ||
21 | default 'console=ttyS0,19200' | ||
22 | depends on BOOTPARAM | ||
23 | |||
24 | config NO_KERNEL_MSG | ||
25 | bool "Suppress Kernel BUG Messages" | ||
26 | help | ||
27 | Do not output any debug BUG messages within the kernel. | ||
28 | |||
29 | config BDM_DISABLE | ||
30 | bool "Disable BDM signals" | ||
31 | depends on (EXPERIMENTAL && COLDFIRE) | ||
32 | help | ||
33 | Disable the ColdFire CPU's BDM signals. | ||
34 | |||
35 | endmenu | ||
diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig deleted file mode 100644 index 2f5655c577af..000000000000 --- a/arch/m68knommu/defconfig +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_LOG_BUF_SHIFT=14 | ||
3 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
4 | CONFIG_EXPERT=y | ||
5 | # CONFIG_KALLSYMS is not set | ||
6 | # CONFIG_HOTPLUG is not set | ||
7 | # CONFIG_FUTEX is not set | ||
8 | # CONFIG_EPOLL is not set | ||
9 | # CONFIG_SIGNALFD is not set | ||
10 | # CONFIG_TIMERFD is not set | ||
11 | # CONFIG_EVENTFD is not set | ||
12 | # CONFIG_AIO is not set | ||
13 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
14 | # CONFIG_COMPAT_BRK is not set | ||
15 | # CONFIG_BLK_DEV_BSG is not set | ||
16 | # CONFIG_IOSCHED_DEADLINE is not set | ||
17 | # CONFIG_IOSCHED_CFQ is not set | ||
18 | CONFIG_M520x=y | ||
19 | CONFIG_CLOCK_SET=y | ||
20 | CONFIG_CLOCK_FREQ=166666666 | ||
21 | CONFIG_CLOCK_DIV=2 | ||
22 | CONFIG_M5208EVB=y | ||
23 | # CONFIG_4KSTACKS is not set | ||
24 | CONFIG_RAMBASE=0x40000000 | ||
25 | CONFIG_RAMSIZE=0x2000000 | ||
26 | CONFIG_VECTORBASE=0x40000000 | ||
27 | CONFIG_KERNELBASE=0x40020000 | ||
28 | CONFIG_RAM16BIT=y | ||
29 | CONFIG_BINFMT_FLAT=y | ||
30 | CONFIG_NET=y | ||
31 | CONFIG_PACKET=y | ||
32 | CONFIG_UNIX=y | ||
33 | CONFIG_INET=y | ||
34 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
35 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
36 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
37 | # CONFIG_INET_LRO is not set | ||
38 | # CONFIG_INET_DIAG is not set | ||
39 | # CONFIG_IPV6 is not set | ||
40 | CONFIG_MTD=y | ||
41 | CONFIG_MTD_PARTITIONS=y | ||
42 | CONFIG_MTD_CHAR=y | ||
43 | CONFIG_MTD_BLOCK=y | ||
44 | CONFIG_MTD_RAM=y | ||
45 | CONFIG_MTD_UCLINUX=y | ||
46 | CONFIG_BLK_DEV_RAM=y | ||
47 | # CONFIG_MISC_DEVICES is not set | ||
48 | CONFIG_NETDEVICES=y | ||
49 | CONFIG_NET_ETHERNET=y | ||
50 | CONFIG_FEC=y | ||
51 | # CONFIG_NETDEV_1000 is not set | ||
52 | # CONFIG_NETDEV_10000 is not set | ||
53 | # CONFIG_INPUT is not set | ||
54 | # CONFIG_SERIO is not set | ||
55 | # CONFIG_VT is not set | ||
56 | CONFIG_SERIAL_MCF=y | ||
57 | CONFIG_SERIAL_MCF_BAUDRATE=115200 | ||
58 | CONFIG_SERIAL_MCF_CONSOLE=y | ||
59 | # CONFIG_UNIX98_PTYS is not set | ||
60 | # CONFIG_HW_RANDOM is not set | ||
61 | # CONFIG_HWMON is not set | ||
62 | # CONFIG_USB_SUPPORT is not set | ||
63 | CONFIG_EXT2_FS=y | ||
64 | # CONFIG_FILE_LOCKING is not set | ||
65 | # CONFIG_DNOTIFY is not set | ||
66 | # CONFIG_SYSFS is not set | ||
67 | CONFIG_ROMFS_FS=y | ||
68 | CONFIG_ROMFS_BACKED_BY_MTD=y | ||
69 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
70 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
71 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
72 | CONFIG_FULLDEBUG=y | ||
73 | CONFIG_BOOTPARAM=y | ||
74 | CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" | ||
diff --git a/arch/m68knommu/kernel/.gitignore b/arch/m68knommu/kernel/.gitignore deleted file mode 100644 index c5f676c3c224..000000000000 --- a/arch/m68knommu/kernel/.gitignore +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | vmlinux.lds | ||
diff --git a/arch/m68knommu/lib/ashldi3.c b/arch/m68knommu/lib/ashldi3.c deleted file mode 100644 index 008403eb8ce2..000000000000 --- a/arch/m68knommu/lib/ashldi3.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */ | ||
2 | /* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. | ||
3 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2, or (at your option) | ||
9 | any later version. | ||
10 | |||
11 | GNU CC is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with GNU CC; see the file COPYING. If not, write to | ||
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
19 | Boston, MA 02111-1307, USA. */ | ||
20 | |||
21 | #define BITS_PER_UNIT 8 | ||
22 | |||
23 | typedef int SItype __attribute__ ((mode (SI))); | ||
24 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
25 | typedef int DItype __attribute__ ((mode (DI))); | ||
26 | typedef int word_type __attribute__ ((mode (__word__))); | ||
27 | |||
28 | struct DIstruct {SItype high, low;}; | ||
29 | |||
30 | typedef union | ||
31 | { | ||
32 | struct DIstruct s; | ||
33 | DItype ll; | ||
34 | } DIunion; | ||
35 | |||
36 | DItype | ||
37 | __ashldi3 (DItype u, word_type b) | ||
38 | { | ||
39 | DIunion w; | ||
40 | word_type bm; | ||
41 | DIunion uu; | ||
42 | |||
43 | if (b == 0) | ||
44 | return u; | ||
45 | |||
46 | uu.ll = u; | ||
47 | |||
48 | bm = (sizeof (SItype) * BITS_PER_UNIT) - b; | ||
49 | if (bm <= 0) | ||
50 | { | ||
51 | w.s.low = 0; | ||
52 | w.s.high = (USItype)uu.s.low << -bm; | ||
53 | } | ||
54 | else | ||
55 | { | ||
56 | USItype carries = (USItype)uu.s.low >> bm; | ||
57 | w.s.low = (USItype)uu.s.low << b; | ||
58 | w.s.high = ((USItype)uu.s.high << b) | carries; | ||
59 | } | ||
60 | |||
61 | return w.ll; | ||
62 | } | ||
diff --git a/arch/m68knommu/lib/lshrdi3.c b/arch/m68knommu/lib/lshrdi3.c deleted file mode 100644 index 93b1cb6fdee8..000000000000 --- a/arch/m68knommu/lib/lshrdi3.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ | ||
2 | /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | ||
3 | |||
4 | This file is part of GNU CC. | ||
5 | |||
6 | GNU CC is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2, or (at your option) | ||
9 | any later version. | ||
10 | |||
11 | GNU CC is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with GNU CC; see the file COPYING. If not, write to | ||
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | ||
19 | Boston, MA 02111-1307, USA. */ | ||
20 | |||
21 | #define BITS_PER_UNIT 8 | ||
22 | |||
23 | typedef int SItype __attribute__ ((mode (SI))); | ||
24 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
25 | typedef int DItype __attribute__ ((mode (DI))); | ||
26 | typedef int word_type __attribute__ ((mode (__word__))); | ||
27 | |||
28 | struct DIstruct {SItype high, low;}; | ||
29 | |||
30 | typedef union | ||
31 | { | ||
32 | struct DIstruct s; | ||
33 | DItype ll; | ||
34 | } DIunion; | ||
35 | |||
36 | DItype | ||
37 | __lshrdi3 (DItype u, word_type b) | ||
38 | { | ||
39 | DIunion w; | ||
40 | word_type bm; | ||
41 | DIunion uu; | ||
42 | |||
43 | if (b == 0) | ||
44 | return u; | ||
45 | |||
46 | uu.ll = u; | ||
47 | |||
48 | bm = (sizeof (SItype) * BITS_PER_UNIT) - b; | ||
49 | if (bm <= 0) | ||
50 | { | ||
51 | w.s.high = 0; | ||
52 | w.s.low = (USItype)uu.s.high >> -bm; | ||
53 | } | ||
54 | else | ||
55 | { | ||
56 | USItype carries = (USItype)uu.s.high << bm; | ||
57 | w.s.high = (USItype)uu.s.high >> b; | ||
58 | w.s.low = ((USItype)uu.s.low >> b) | carries; | ||
59 | } | ||
60 | |||
61 | return w.ll; | ||
62 | } | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9905e2e85de4..83aa5fb8e8f1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -22,6 +22,7 @@ config MIPS | |||
22 | select HAVE_DMA_API_DEBUG | 22 | select HAVE_DMA_API_DEBUG |
23 | select HAVE_GENERIC_HARDIRQS | 23 | select HAVE_GENERIC_HARDIRQS |
24 | select GENERIC_IRQ_PROBE | 24 | select GENERIC_IRQ_PROBE |
25 | select GENERIC_IRQ_SHOW | ||
25 | select HAVE_ARCH_JUMP_LABEL | 26 | select HAVE_ARCH_JUMP_LABEL |
26 | 27 | ||
27 | menu "Machine selection" | 28 | menu "Machine selection" |
@@ -862,6 +863,9 @@ config GPIO_TXX9 | |||
862 | config CFE | 863 | config CFE |
863 | bool | 864 | bool |
864 | 865 | ||
866 | config ARCH_DMA_ADDR_T_64BIT | ||
867 | def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT | ||
868 | |||
865 | config DMA_COHERENT | 869 | config DMA_COHERENT |
866 | bool | 870 | bool |
867 | 871 | ||
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 9f78ada83b3c..55dd7c888517 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/mach-pb1x00/pb1000.h> | 39 | #include <asm/mach-pb1x00/pb1000.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); | 42 | static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type); |
43 | 43 | ||
44 | /* NOTE on interrupt priorities: The original writers of this code said: | 44 | /* NOTE on interrupt priorities: The original writers of this code said: |
45 | * | 45 | * |
@@ -218,17 +218,17 @@ struct au1xxx_irqmap au1200_irqmap[] __initdata = { | |||
218 | }; | 218 | }; |
219 | 219 | ||
220 | 220 | ||
221 | static void au1x_ic0_unmask(unsigned int irq_nr) | 221 | static void au1x_ic0_unmask(struct irq_data *d) |
222 | { | 222 | { |
223 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 223 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
224 | au_writel(1 << bit, IC0_MASKSET); | 224 | au_writel(1 << bit, IC0_MASKSET); |
225 | au_writel(1 << bit, IC0_WAKESET); | 225 | au_writel(1 << bit, IC0_WAKESET); |
226 | au_sync(); | 226 | au_sync(); |
227 | } | 227 | } |
228 | 228 | ||
229 | static void au1x_ic1_unmask(unsigned int irq_nr) | 229 | static void au1x_ic1_unmask(struct irq_data *d) |
230 | { | 230 | { |
231 | unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; | 231 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
232 | au_writel(1 << bit, IC1_MASKSET); | 232 | au_writel(1 << bit, IC1_MASKSET); |
233 | au_writel(1 << bit, IC1_WAKESET); | 233 | au_writel(1 << bit, IC1_WAKESET); |
234 | 234 | ||
@@ -236,31 +236,31 @@ static void au1x_ic1_unmask(unsigned int irq_nr) | |||
236 | * nowhere in the current kernel sources is it disabled. --mlau | 236 | * nowhere in the current kernel sources is it disabled. --mlau |
237 | */ | 237 | */ |
238 | #if defined(CONFIG_MIPS_PB1000) | 238 | #if defined(CONFIG_MIPS_PB1000) |
239 | if (irq_nr == AU1000_GPIO15_INT) | 239 | if (d->irq == AU1000_GPIO15_INT) |
240 | au_writel(0x4000, PB1000_MDR); /* enable int */ | 240 | au_writel(0x4000, PB1000_MDR); /* enable int */ |
241 | #endif | 241 | #endif |
242 | au_sync(); | 242 | au_sync(); |
243 | } | 243 | } |
244 | 244 | ||
245 | static void au1x_ic0_mask(unsigned int irq_nr) | 245 | static void au1x_ic0_mask(struct irq_data *d) |
246 | { | 246 | { |
247 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 247 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
248 | au_writel(1 << bit, IC0_MASKCLR); | 248 | au_writel(1 << bit, IC0_MASKCLR); |
249 | au_writel(1 << bit, IC0_WAKECLR); | 249 | au_writel(1 << bit, IC0_WAKECLR); |
250 | au_sync(); | 250 | au_sync(); |
251 | } | 251 | } |
252 | 252 | ||
253 | static void au1x_ic1_mask(unsigned int irq_nr) | 253 | static void au1x_ic1_mask(struct irq_data *d) |
254 | { | 254 | { |
255 | unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; | 255 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
256 | au_writel(1 << bit, IC1_MASKCLR); | 256 | au_writel(1 << bit, IC1_MASKCLR); |
257 | au_writel(1 << bit, IC1_WAKECLR); | 257 | au_writel(1 << bit, IC1_WAKECLR); |
258 | au_sync(); | 258 | au_sync(); |
259 | } | 259 | } |
260 | 260 | ||
261 | static void au1x_ic0_ack(unsigned int irq_nr) | 261 | static void au1x_ic0_ack(struct irq_data *d) |
262 | { | 262 | { |
263 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 263 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
264 | 264 | ||
265 | /* | 265 | /* |
266 | * This may assume that we don't get interrupts from | 266 | * This may assume that we don't get interrupts from |
@@ -271,9 +271,9 @@ static void au1x_ic0_ack(unsigned int irq_nr) | |||
271 | au_sync(); | 271 | au_sync(); |
272 | } | 272 | } |
273 | 273 | ||
274 | static void au1x_ic1_ack(unsigned int irq_nr) | 274 | static void au1x_ic1_ack(struct irq_data *d) |
275 | { | 275 | { |
276 | unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; | 276 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
277 | 277 | ||
278 | /* | 278 | /* |
279 | * This may assume that we don't get interrupts from | 279 | * This may assume that we don't get interrupts from |
@@ -284,9 +284,9 @@ static void au1x_ic1_ack(unsigned int irq_nr) | |||
284 | au_sync(); | 284 | au_sync(); |
285 | } | 285 | } |
286 | 286 | ||
287 | static void au1x_ic0_maskack(unsigned int irq_nr) | 287 | static void au1x_ic0_maskack(struct irq_data *d) |
288 | { | 288 | { |
289 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 289 | unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; |
290 | 290 | ||
291 | au_writel(1 << bit, IC0_WAKECLR); | 291 | au_writel(1 << bit, IC0_WAKECLR); |
292 | au_writel(1 << bit, IC0_MASKCLR); | 292 | au_writel(1 << bit, IC0_MASKCLR); |
@@ -295,9 +295,9 @@ static void au1x_ic0_maskack(unsigned int irq_nr) | |||
295 | au_sync(); | 295 | au_sync(); |
296 | } | 296 | } |
297 | 297 | ||
298 | static void au1x_ic1_maskack(unsigned int irq_nr) | 298 | static void au1x_ic1_maskack(struct irq_data *d) |
299 | { | 299 | { |
300 | unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; | 300 | unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; |
301 | 301 | ||
302 | au_writel(1 << bit, IC1_WAKECLR); | 302 | au_writel(1 << bit, IC1_WAKECLR); |
303 | au_writel(1 << bit, IC1_MASKCLR); | 303 | au_writel(1 << bit, IC1_MASKCLR); |
@@ -306,9 +306,9 @@ static void au1x_ic1_maskack(unsigned int irq_nr) | |||
306 | au_sync(); | 306 | au_sync(); |
307 | } | 307 | } |
308 | 308 | ||
309 | static int au1x_ic1_setwake(unsigned int irq, unsigned int on) | 309 | static int au1x_ic1_setwake(struct irq_data *d, unsigned int on) |
310 | { | 310 | { |
311 | int bit = irq - AU1000_INTC1_INT_BASE; | 311 | int bit = d->irq - AU1000_INTC1_INT_BASE; |
312 | unsigned long wakemsk, flags; | 312 | unsigned long wakemsk, flags; |
313 | 313 | ||
314 | /* only GPIO 0-7 can act as wakeup source. Fortunately these | 314 | /* only GPIO 0-7 can act as wakeup source. Fortunately these |
@@ -336,28 +336,30 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on) | |||
336 | */ | 336 | */ |
337 | static struct irq_chip au1x_ic0_chip = { | 337 | static struct irq_chip au1x_ic0_chip = { |
338 | .name = "Alchemy-IC0", | 338 | .name = "Alchemy-IC0", |
339 | .ack = au1x_ic0_ack, | 339 | .irq_ack = au1x_ic0_ack, |
340 | .mask = au1x_ic0_mask, | 340 | .irq_mask = au1x_ic0_mask, |
341 | .mask_ack = au1x_ic0_maskack, | 341 | .irq_mask_ack = au1x_ic0_maskack, |
342 | .unmask = au1x_ic0_unmask, | 342 | .irq_unmask = au1x_ic0_unmask, |
343 | .set_type = au1x_ic_settype, | 343 | .irq_set_type = au1x_ic_settype, |
344 | }; | 344 | }; |
345 | 345 | ||
346 | static struct irq_chip au1x_ic1_chip = { | 346 | static struct irq_chip au1x_ic1_chip = { |
347 | .name = "Alchemy-IC1", | 347 | .name = "Alchemy-IC1", |
348 | .ack = au1x_ic1_ack, | 348 | .irq_ack = au1x_ic1_ack, |
349 | .mask = au1x_ic1_mask, | 349 | .irq_mask = au1x_ic1_mask, |
350 | .mask_ack = au1x_ic1_maskack, | 350 | .irq_mask_ack = au1x_ic1_maskack, |
351 | .unmask = au1x_ic1_unmask, | 351 | .irq_unmask = au1x_ic1_unmask, |
352 | .set_type = au1x_ic_settype, | 352 | .irq_set_type = au1x_ic_settype, |
353 | .set_wake = au1x_ic1_setwake, | 353 | .irq_set_wake = au1x_ic1_setwake, |
354 | }; | 354 | }; |
355 | 355 | ||
356 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) | 356 | static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type) |
357 | { | 357 | { |
358 | struct irq_chip *chip; | 358 | struct irq_chip *chip; |
359 | unsigned long icr[6]; | 359 | unsigned long icr[6]; |
360 | unsigned int bit, ic; | 360 | unsigned int bit, ic, irq = d->irq; |
361 | irq_flow_handler_t handler = NULL; | ||
362 | unsigned char *name = NULL; | ||
361 | int ret; | 363 | int ret; |
362 | 364 | ||
363 | if (irq >= AU1000_INTC1_INT_BASE) { | 365 | if (irq >= AU1000_INTC1_INT_BASE) { |
@@ -387,47 +389,47 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) | |||
387 | au_writel(1 << bit, icr[5]); | 389 | au_writel(1 << bit, icr[5]); |
388 | au_writel(1 << bit, icr[4]); | 390 | au_writel(1 << bit, icr[4]); |
389 | au_writel(1 << bit, icr[0]); | 391 | au_writel(1 << bit, icr[0]); |
390 | set_irq_chip_and_handler_name(irq, chip, | 392 | handler = handle_edge_irq; |
391 | handle_edge_irq, "riseedge"); | 393 | name = "riseedge"; |
392 | break; | 394 | break; |
393 | case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */ | 395 | case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */ |
394 | au_writel(1 << bit, icr[5]); | 396 | au_writel(1 << bit, icr[5]); |
395 | au_writel(1 << bit, icr[1]); | 397 | au_writel(1 << bit, icr[1]); |
396 | au_writel(1 << bit, icr[3]); | 398 | au_writel(1 << bit, icr[3]); |
397 | set_irq_chip_and_handler_name(irq, chip, | 399 | handler = handle_edge_irq; |
398 | handle_edge_irq, "falledge"); | 400 | name = "falledge"; |
399 | break; | 401 | break; |
400 | case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */ | 402 | case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */ |
401 | au_writel(1 << bit, icr[5]); | 403 | au_writel(1 << bit, icr[5]); |
402 | au_writel(1 << bit, icr[1]); | 404 | au_writel(1 << bit, icr[1]); |
403 | au_writel(1 << bit, icr[0]); | 405 | au_writel(1 << bit, icr[0]); |
404 | set_irq_chip_and_handler_name(irq, chip, | 406 | handler = handle_edge_irq; |
405 | handle_edge_irq, "bothedge"); | 407 | name = "bothedge"; |
406 | break; | 408 | break; |
407 | case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */ | 409 | case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */ |
408 | au_writel(1 << bit, icr[2]); | 410 | au_writel(1 << bit, icr[2]); |
409 | au_writel(1 << bit, icr[4]); | 411 | au_writel(1 << bit, icr[4]); |
410 | au_writel(1 << bit, icr[0]); | 412 | au_writel(1 << bit, icr[0]); |
411 | set_irq_chip_and_handler_name(irq, chip, | 413 | handler = handle_level_irq; |
412 | handle_level_irq, "hilevel"); | 414 | name = "hilevel"; |
413 | break; | 415 | break; |
414 | case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */ | 416 | case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */ |
415 | au_writel(1 << bit, icr[2]); | 417 | au_writel(1 << bit, icr[2]); |
416 | au_writel(1 << bit, icr[1]); | 418 | au_writel(1 << bit, icr[1]); |
417 | au_writel(1 << bit, icr[3]); | 419 | au_writel(1 << bit, icr[3]); |
418 | set_irq_chip_and_handler_name(irq, chip, | 420 | handler = handle_level_irq; |
419 | handle_level_irq, "lowlevel"); | 421 | name = "lowlevel"; |
420 | break; | 422 | break; |
421 | case IRQ_TYPE_NONE: /* 0:0:0 */ | 423 | case IRQ_TYPE_NONE: /* 0:0:0 */ |
422 | au_writel(1 << bit, icr[5]); | 424 | au_writel(1 << bit, icr[5]); |
423 | au_writel(1 << bit, icr[4]); | 425 | au_writel(1 << bit, icr[4]); |
424 | au_writel(1 << bit, icr[3]); | 426 | au_writel(1 << bit, icr[3]); |
425 | /* set at least chip so we can call set_irq_type() on it */ | ||
426 | set_irq_chip(irq, chip); | ||
427 | break; | 427 | break; |
428 | default: | 428 | default: |
429 | ret = -EINVAL; | 429 | ret = -EINVAL; |
430 | } | 430 | } |
431 | __irq_set_chip_handler_name_locked(d->irq, chip, handler, name); | ||
432 | |||
431 | au_sync(); | 433 | au_sync(); |
432 | 434 | ||
433 | return ret; | 435 | return ret; |
@@ -504,11 +506,11 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map) | |||
504 | */ | 506 | */ |
505 | for (i = AU1000_INTC0_INT_BASE; | 507 | for (i = AU1000_INTC0_INT_BASE; |
506 | (i < AU1000_INTC0_INT_BASE + 32); i++) | 508 | (i < AU1000_INTC0_INT_BASE + 32); i++) |
507 | au1x_ic_settype(i, IRQ_TYPE_NONE); | 509 | au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE); |
508 | 510 | ||
509 | for (i = AU1000_INTC1_INT_BASE; | 511 | for (i = AU1000_INTC1_INT_BASE; |
510 | (i < AU1000_INTC1_INT_BASE + 32); i++) | 512 | (i < AU1000_INTC1_INT_BASE + 32); i++) |
511 | au1x_ic_settype(i, IRQ_TYPE_NONE); | 513 | au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE); |
512 | 514 | ||
513 | /* | 515 | /* |
514 | * Initialize IC0, which is fixed per processor. | 516 | * Initialize IC0, which is fixed per processor. |
@@ -526,7 +528,7 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map) | |||
526 | au_writel(1 << bit, IC0_ASSIGNSET); | 528 | au_writel(1 << bit, IC0_ASSIGNSET); |
527 | } | 529 | } |
528 | 530 | ||
529 | au1x_ic_settype(irq_nr, map->im_type); | 531 | au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type); |
530 | ++map; | 532 | ++map; |
531 | } | 533 | } |
532 | 534 | ||
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c index c52af8821da0..f91c43a7d5dc 100644 --- a/arch/mips/alchemy/devboards/bcsr.c +++ b/arch/mips/alchemy/devboards/bcsr.c | |||
@@ -97,26 +97,26 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d) | |||
97 | * CPLD generates tons of spurious interrupts (at least on my DB1200). | 97 | * CPLD generates tons of spurious interrupts (at least on my DB1200). |
98 | * -- mlau | 98 | * -- mlau |
99 | */ | 99 | */ |
100 | static void bcsr_irq_mask(unsigned int irq_nr) | 100 | static void bcsr_irq_mask(struct irq_data *d) |
101 | { | 101 | { |
102 | unsigned short v = 1 << (irq_nr - bcsr_csc_base); | 102 | unsigned short v = 1 << (d->irq - bcsr_csc_base); |
103 | __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); | 103 | __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); |
104 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); | 104 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); |
105 | wmb(); | 105 | wmb(); |
106 | } | 106 | } |
107 | 107 | ||
108 | static void bcsr_irq_maskack(unsigned int irq_nr) | 108 | static void bcsr_irq_maskack(struct irq_data *d) |
109 | { | 109 | { |
110 | unsigned short v = 1 << (irq_nr - bcsr_csc_base); | 110 | unsigned short v = 1 << (d->irq - bcsr_csc_base); |
111 | __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); | 111 | __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); |
112 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); | 112 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); |
113 | __raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */ | 113 | __raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */ |
114 | wmb(); | 114 | wmb(); |
115 | } | 115 | } |
116 | 116 | ||
117 | static void bcsr_irq_unmask(unsigned int irq_nr) | 117 | static void bcsr_irq_unmask(struct irq_data *d) |
118 | { | 118 | { |
119 | unsigned short v = 1 << (irq_nr - bcsr_csc_base); | 119 | unsigned short v = 1 << (d->irq - bcsr_csc_base); |
120 | __raw_writew(v, bcsr_virt + BCSR_REG_INTSET); | 120 | __raw_writew(v, bcsr_virt + BCSR_REG_INTSET); |
121 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKSET); | 121 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKSET); |
122 | wmb(); | 122 | wmb(); |
@@ -124,9 +124,9 @@ static void bcsr_irq_unmask(unsigned int irq_nr) | |||
124 | 124 | ||
125 | static struct irq_chip bcsr_irq_type = { | 125 | static struct irq_chip bcsr_irq_type = { |
126 | .name = "CPLD", | 126 | .name = "CPLD", |
127 | .mask = bcsr_irq_mask, | 127 | .irq_mask = bcsr_irq_mask, |
128 | .mask_ack = bcsr_irq_maskack, | 128 | .irq_mask_ack = bcsr_irq_maskack, |
129 | .unmask = bcsr_irq_unmask, | 129 | .irq_unmask = bcsr_irq_unmask, |
130 | }; | 130 | }; |
131 | 131 | ||
132 | void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq) | 132 | void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq) |
diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c index 4ec2642c568f..a6484b60642f 100644 --- a/arch/mips/ar7/irq.c +++ b/arch/mips/ar7/irq.c | |||
@@ -49,51 +49,51 @@ | |||
49 | 49 | ||
50 | static int ar7_irq_base; | 50 | static int ar7_irq_base; |
51 | 51 | ||
52 | static void ar7_unmask_irq(unsigned int irq) | 52 | static void ar7_unmask_irq(struct irq_data *d) |
53 | { | 53 | { |
54 | writel(1 << ((irq - ar7_irq_base) % 32), | 54 | writel(1 << ((d->irq - ar7_irq_base) % 32), |
55 | REG(ESR_OFFSET(irq - ar7_irq_base))); | 55 | REG(ESR_OFFSET(d->irq - ar7_irq_base))); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void ar7_mask_irq(unsigned int irq) | 58 | static void ar7_mask_irq(struct irq_data *d) |
59 | { | 59 | { |
60 | writel(1 << ((irq - ar7_irq_base) % 32), | 60 | writel(1 << ((d->irq - ar7_irq_base) % 32), |
61 | REG(ECR_OFFSET(irq - ar7_irq_base))); | 61 | REG(ECR_OFFSET(d->irq - ar7_irq_base))); |
62 | } | 62 | } |
63 | 63 | ||
64 | static void ar7_ack_irq(unsigned int irq) | 64 | static void ar7_ack_irq(struct irq_data *d) |
65 | { | 65 | { |
66 | writel(1 << ((irq - ar7_irq_base) % 32), | 66 | writel(1 << ((d->irq - ar7_irq_base) % 32), |
67 | REG(CR_OFFSET(irq - ar7_irq_base))); | 67 | REG(CR_OFFSET(d->irq - ar7_irq_base))); |
68 | } | 68 | } |
69 | 69 | ||
70 | static void ar7_unmask_sec_irq(unsigned int irq) | 70 | static void ar7_unmask_sec_irq(struct irq_data *d) |
71 | { | 71 | { |
72 | writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET)); | 72 | writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET)); |
73 | } | 73 | } |
74 | 74 | ||
75 | static void ar7_mask_sec_irq(unsigned int irq) | 75 | static void ar7_mask_sec_irq(struct irq_data *d) |
76 | { | 76 | { |
77 | writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET)); | 77 | writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET)); |
78 | } | 78 | } |
79 | 79 | ||
80 | static void ar7_ack_sec_irq(unsigned int irq) | 80 | static void ar7_ack_sec_irq(struct irq_data *d) |
81 | { | 81 | { |
82 | writel(1 << (irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET)); | 82 | writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET)); |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct irq_chip ar7_irq_type = { | 85 | static struct irq_chip ar7_irq_type = { |
86 | .name = "AR7", | 86 | .name = "AR7", |
87 | .unmask = ar7_unmask_irq, | 87 | .irq_unmask = ar7_unmask_irq, |
88 | .mask = ar7_mask_irq, | 88 | .irq_mask = ar7_mask_irq, |
89 | .ack = ar7_ack_irq | 89 | .irq_ack = ar7_ack_irq |
90 | }; | 90 | }; |
91 | 91 | ||
92 | static struct irq_chip ar7_sec_irq_type = { | 92 | static struct irq_chip ar7_sec_irq_type = { |
93 | .name = "AR7", | 93 | .name = "AR7", |
94 | .unmask = ar7_unmask_sec_irq, | 94 | .irq_unmask = ar7_unmask_sec_irq, |
95 | .mask = ar7_mask_sec_irq, | 95 | .irq_mask = ar7_mask_sec_irq, |
96 | .ack = ar7_ack_sec_irq, | 96 | .irq_ack = ar7_ack_sec_irq, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static struct irqaction ar7_cascade_action = { | 99 | static struct irqaction ar7_cascade_action = { |
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 1bf7f719ba53..7c02bc948a31 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
@@ -62,13 +62,12 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
62 | spurious_interrupt(); | 62 | spurious_interrupt(); |
63 | } | 63 | } |
64 | 64 | ||
65 | static void ar71xx_misc_irq_unmask(unsigned int irq) | 65 | static void ar71xx_misc_irq_unmask(struct irq_data *d) |
66 | { | 66 | { |
67 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | ||
67 | void __iomem *base = ath79_reset_base; | 68 | void __iomem *base = ath79_reset_base; |
68 | u32 t; | 69 | u32 t; |
69 | 70 | ||
70 | irq -= ATH79_MISC_IRQ_BASE; | ||
71 | |||
72 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 71 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
73 | __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 72 | __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
74 | 73 | ||
@@ -76,13 +75,12 @@ static void ar71xx_misc_irq_unmask(unsigned int irq) | |||
76 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 75 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
77 | } | 76 | } |
78 | 77 | ||
79 | static void ar71xx_misc_irq_mask(unsigned int irq) | 78 | static void ar71xx_misc_irq_mask(struct irq_data *d) |
80 | { | 79 | { |
80 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | ||
81 | void __iomem *base = ath79_reset_base; | 81 | void __iomem *base = ath79_reset_base; |
82 | u32 t; | 82 | u32 t; |
83 | 83 | ||
84 | irq -= ATH79_MISC_IRQ_BASE; | ||
85 | |||
86 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 84 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
87 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 85 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
88 | 86 | ||
@@ -90,13 +88,12 @@ static void ar71xx_misc_irq_mask(unsigned int irq) | |||
90 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 88 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
91 | } | 89 | } |
92 | 90 | ||
93 | static void ar724x_misc_irq_ack(unsigned int irq) | 91 | static void ar724x_misc_irq_ack(struct irq_data *d) |
94 | { | 92 | { |
93 | unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; | ||
95 | void __iomem *base = ath79_reset_base; | 94 | void __iomem *base = ath79_reset_base; |
96 | u32 t; | 95 | u32 t; |
97 | 96 | ||
98 | irq -= ATH79_MISC_IRQ_BASE; | ||
99 | |||
100 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); | 97 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); |
101 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); | 98 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); |
102 | 99 | ||
@@ -106,8 +103,8 @@ static void ar724x_misc_irq_ack(unsigned int irq) | |||
106 | 103 | ||
107 | static struct irq_chip ath79_misc_irq_chip = { | 104 | static struct irq_chip ath79_misc_irq_chip = { |
108 | .name = "MISC", | 105 | .name = "MISC", |
109 | .unmask = ar71xx_misc_irq_unmask, | 106 | .irq_unmask = ar71xx_misc_irq_unmask, |
110 | .mask = ar71xx_misc_irq_mask, | 107 | .irq_mask = ar71xx_misc_irq_mask, |
111 | }; | 108 | }; |
112 | 109 | ||
113 | static void __init ath79_misc_irq_init(void) | 110 | static void __init ath79_misc_irq_init(void) |
@@ -119,15 +116,14 @@ static void __init ath79_misc_irq_init(void) | |||
119 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); | 116 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); |
120 | 117 | ||
121 | if (soc_is_ar71xx() || soc_is_ar913x()) | 118 | if (soc_is_ar71xx() || soc_is_ar913x()) |
122 | ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask; | 119 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; |
123 | else if (soc_is_ar724x()) | 120 | else if (soc_is_ar724x()) |
124 | ath79_misc_irq_chip.ack = ar724x_misc_irq_ack; | 121 | ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; |
125 | else | 122 | else |
126 | BUG(); | 123 | BUG(); |
127 | 124 | ||
128 | for (i = ATH79_MISC_IRQ_BASE; | 125 | for (i = ATH79_MISC_IRQ_BASE; |
129 | i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) { | 126 | i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) { |
130 | irq_desc[i].status = IRQ_DISABLED; | ||
131 | set_irq_chip_and_handler(i, &ath79_misc_irq_chip, | 127 | set_irq_chip_and_handler(i, &ath79_misc_irq_chip, |
132 | handle_level_irq); | 128 | handle_level_irq); |
133 | } | 129 | } |
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index 3be87f2422f0..1691531aa34d 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c | |||
@@ -76,88 +76,80 @@ asmlinkage void plat_irq_dispatch(void) | |||
76 | * internal IRQs operations: only mask/unmask on PERF irq mask | 76 | * internal IRQs operations: only mask/unmask on PERF irq mask |
77 | * register. | 77 | * register. |
78 | */ | 78 | */ |
79 | static inline void bcm63xx_internal_irq_mask(unsigned int irq) | 79 | static inline void bcm63xx_internal_irq_mask(struct irq_data *d) |
80 | { | 80 | { |
81 | unsigned int irq = d->irq - IRQ_INTERNAL_BASE; | ||
81 | u32 mask; | 82 | u32 mask; |
82 | 83 | ||
83 | irq -= IRQ_INTERNAL_BASE; | ||
84 | mask = bcm_perf_readl(PERF_IRQMASK_REG); | 84 | mask = bcm_perf_readl(PERF_IRQMASK_REG); |
85 | mask &= ~(1 << irq); | 85 | mask &= ~(1 << irq); |
86 | bcm_perf_writel(mask, PERF_IRQMASK_REG); | 86 | bcm_perf_writel(mask, PERF_IRQMASK_REG); |
87 | } | 87 | } |
88 | 88 | ||
89 | static void bcm63xx_internal_irq_unmask(unsigned int irq) | 89 | static void bcm63xx_internal_irq_unmask(struct irq_data *d) |
90 | { | 90 | { |
91 | unsigned int irq = d->irq - IRQ_INTERNAL_BASE; | ||
91 | u32 mask; | 92 | u32 mask; |
92 | 93 | ||
93 | irq -= IRQ_INTERNAL_BASE; | ||
94 | mask = bcm_perf_readl(PERF_IRQMASK_REG); | 94 | mask = bcm_perf_readl(PERF_IRQMASK_REG); |
95 | mask |= (1 << irq); | 95 | mask |= (1 << irq); |
96 | bcm_perf_writel(mask, PERF_IRQMASK_REG); | 96 | bcm_perf_writel(mask, PERF_IRQMASK_REG); |
97 | } | 97 | } |
98 | 98 | ||
99 | static unsigned int bcm63xx_internal_irq_startup(unsigned int irq) | ||
100 | { | ||
101 | bcm63xx_internal_irq_unmask(irq); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /* | 99 | /* |
106 | * external IRQs operations: mask/unmask and clear on PERF external | 100 | * external IRQs operations: mask/unmask and clear on PERF external |
107 | * irq control register. | 101 | * irq control register. |
108 | */ | 102 | */ |
109 | static void bcm63xx_external_irq_mask(unsigned int irq) | 103 | static void bcm63xx_external_irq_mask(struct irq_data *d) |
110 | { | 104 | { |
105 | unsigned int irq = d->irq - IRQ_EXT_BASE; | ||
111 | u32 reg; | 106 | u32 reg; |
112 | 107 | ||
113 | irq -= IRQ_EXT_BASE; | ||
114 | reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); | 108 | reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); |
115 | reg &= ~EXTIRQ_CFG_MASK(irq); | 109 | reg &= ~EXTIRQ_CFG_MASK(irq); |
116 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); | 110 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); |
117 | } | 111 | } |
118 | 112 | ||
119 | static void bcm63xx_external_irq_unmask(unsigned int irq) | 113 | static void bcm63xx_external_irq_unmask(struct irq_data *d) |
120 | { | 114 | { |
115 | unsigned int irq = d->irq - IRQ_EXT_BASE; | ||
121 | u32 reg; | 116 | u32 reg; |
122 | 117 | ||
123 | irq -= IRQ_EXT_BASE; | ||
124 | reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); | 118 | reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); |
125 | reg |= EXTIRQ_CFG_MASK(irq); | 119 | reg |= EXTIRQ_CFG_MASK(irq); |
126 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); | 120 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); |
127 | } | 121 | } |
128 | 122 | ||
129 | static void bcm63xx_external_irq_clear(unsigned int irq) | 123 | static void bcm63xx_external_irq_clear(struct irq_data *d) |
130 | { | 124 | { |
125 | unsigned int irq = d->irq - IRQ_EXT_BASE; | ||
131 | u32 reg; | 126 | u32 reg; |
132 | 127 | ||
133 | irq -= IRQ_EXT_BASE; | ||
134 | reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); | 128 | reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); |
135 | reg |= EXTIRQ_CFG_CLEAR(irq); | 129 | reg |= EXTIRQ_CFG_CLEAR(irq); |
136 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); | 130 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); |
137 | } | 131 | } |
138 | 132 | ||
139 | static unsigned int bcm63xx_external_irq_startup(unsigned int irq) | 133 | static unsigned int bcm63xx_external_irq_startup(struct irq_data *d) |
140 | { | 134 | { |
141 | set_c0_status(0x100 << (irq - IRQ_MIPS_BASE)); | 135 | set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE)); |
142 | irq_enable_hazard(); | 136 | irq_enable_hazard(); |
143 | bcm63xx_external_irq_unmask(irq); | 137 | bcm63xx_external_irq_unmask(d); |
144 | return 0; | 138 | return 0; |
145 | } | 139 | } |
146 | 140 | ||
147 | static void bcm63xx_external_irq_shutdown(unsigned int irq) | 141 | static void bcm63xx_external_irq_shutdown(struct irq_data *d) |
148 | { | 142 | { |
149 | bcm63xx_external_irq_mask(irq); | 143 | bcm63xx_external_irq_mask(d); |
150 | clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE)); | 144 | clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE)); |
151 | irq_disable_hazard(); | 145 | irq_disable_hazard(); |
152 | } | 146 | } |
153 | 147 | ||
154 | static int bcm63xx_external_irq_set_type(unsigned int irq, | 148 | static int bcm63xx_external_irq_set_type(struct irq_data *d, |
155 | unsigned int flow_type) | 149 | unsigned int flow_type) |
156 | { | 150 | { |
151 | unsigned int irq = d->irq - IRQ_EXT_BASE; | ||
157 | u32 reg; | 152 | u32 reg; |
158 | struct irq_desc *desc = irq_desc + irq; | ||
159 | |||
160 | irq -= IRQ_EXT_BASE; | ||
161 | 153 | ||
162 | flow_type &= IRQ_TYPE_SENSE_MASK; | 154 | flow_type &= IRQ_TYPE_SENSE_MASK; |
163 | 155 | ||
@@ -199,37 +191,32 @@ static int bcm63xx_external_irq_set_type(unsigned int irq, | |||
199 | } | 191 | } |
200 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); | 192 | bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); |
201 | 193 | ||
202 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { | 194 | irqd_set_trigger_type(d, flow_type); |
203 | desc->status |= IRQ_LEVEL; | 195 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
204 | desc->handle_irq = handle_level_irq; | 196 | __irq_set_handler_locked(d->irq, handle_level_irq); |
205 | } else { | 197 | else |
206 | desc->handle_irq = handle_edge_irq; | 198 | __irq_set_handler_locked(d->irq, handle_edge_irq); |
207 | } | ||
208 | 199 | ||
209 | return 0; | 200 | return IRQ_SET_MASK_OK_NOCOPY; |
210 | } | 201 | } |
211 | 202 | ||
212 | static struct irq_chip bcm63xx_internal_irq_chip = { | 203 | static struct irq_chip bcm63xx_internal_irq_chip = { |
213 | .name = "bcm63xx_ipic", | 204 | .name = "bcm63xx_ipic", |
214 | .startup = bcm63xx_internal_irq_startup, | 205 | .irq_mask = bcm63xx_internal_irq_mask, |
215 | .shutdown = bcm63xx_internal_irq_mask, | 206 | .irq_unmask = bcm63xx_internal_irq_unmask, |
216 | |||
217 | .mask = bcm63xx_internal_irq_mask, | ||
218 | .mask_ack = bcm63xx_internal_irq_mask, | ||
219 | .unmask = bcm63xx_internal_irq_unmask, | ||
220 | }; | 207 | }; |
221 | 208 | ||
222 | static struct irq_chip bcm63xx_external_irq_chip = { | 209 | static struct irq_chip bcm63xx_external_irq_chip = { |
223 | .name = "bcm63xx_epic", | 210 | .name = "bcm63xx_epic", |
224 | .startup = bcm63xx_external_irq_startup, | 211 | .irq_startup = bcm63xx_external_irq_startup, |
225 | .shutdown = bcm63xx_external_irq_shutdown, | 212 | .irq_shutdown = bcm63xx_external_irq_shutdown, |
226 | 213 | ||
227 | .ack = bcm63xx_external_irq_clear, | 214 | .irq_ack = bcm63xx_external_irq_clear, |
228 | 215 | ||
229 | .mask = bcm63xx_external_irq_mask, | 216 | .irq_mask = bcm63xx_external_irq_mask, |
230 | .unmask = bcm63xx_external_irq_unmask, | 217 | .irq_unmask = bcm63xx_external_irq_unmask, |
231 | 218 | ||
232 | .set_type = bcm63xx_external_irq_set_type, | 219 | .irq_set_type = bcm63xx_external_irq_set_type, |
233 | }; | 220 | }; |
234 | 221 | ||
235 | static struct irqaction cpu_ip2_cascade_action = { | 222 | static struct irqaction cpu_ip2_cascade_action = { |
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index cb41954fc321..8d9a5fc607e4 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c | |||
@@ -17,80 +17,48 @@ | |||
17 | #include <asm/dec/ioasic_addrs.h> | 17 | #include <asm/dec/ioasic_addrs.h> |
18 | #include <asm/dec/ioasic_ints.h> | 18 | #include <asm/dec/ioasic_ints.h> |
19 | 19 | ||
20 | |||
21 | static int ioasic_irq_base; | 20 | static int ioasic_irq_base; |
22 | 21 | ||
23 | 22 | static void unmask_ioasic_irq(struct irq_data *d) | |
24 | static inline void unmask_ioasic_irq(unsigned int irq) | ||
25 | { | 23 | { |
26 | u32 simr; | 24 | u32 simr; |
27 | 25 | ||
28 | simr = ioasic_read(IO_REG_SIMR); | 26 | simr = ioasic_read(IO_REG_SIMR); |
29 | simr |= (1 << (irq - ioasic_irq_base)); | 27 | simr |= (1 << (d->irq - ioasic_irq_base)); |
30 | ioasic_write(IO_REG_SIMR, simr); | 28 | ioasic_write(IO_REG_SIMR, simr); |
31 | } | 29 | } |
32 | 30 | ||
33 | static inline void mask_ioasic_irq(unsigned int irq) | 31 | static void mask_ioasic_irq(struct irq_data *d) |
34 | { | 32 | { |
35 | u32 simr; | 33 | u32 simr; |
36 | 34 | ||
37 | simr = ioasic_read(IO_REG_SIMR); | 35 | simr = ioasic_read(IO_REG_SIMR); |
38 | simr &= ~(1 << (irq - ioasic_irq_base)); | 36 | simr &= ~(1 << (d->irq - ioasic_irq_base)); |
39 | ioasic_write(IO_REG_SIMR, simr); | 37 | ioasic_write(IO_REG_SIMR, simr); |
40 | } | 38 | } |
41 | 39 | ||
42 | static inline void clear_ioasic_irq(unsigned int irq) | 40 | static void ack_ioasic_irq(struct irq_data *d) |
43 | { | 41 | { |
44 | u32 sir; | 42 | mask_ioasic_irq(d); |
45 | |||
46 | sir = ~(1 << (irq - ioasic_irq_base)); | ||
47 | ioasic_write(IO_REG_SIR, sir); | ||
48 | } | ||
49 | |||
50 | static inline void ack_ioasic_irq(unsigned int irq) | ||
51 | { | ||
52 | mask_ioasic_irq(irq); | ||
53 | fast_iob(); | 43 | fast_iob(); |
54 | } | 44 | } |
55 | 45 | ||
56 | static inline void end_ioasic_irq(unsigned int irq) | ||
57 | { | ||
58 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
59 | unmask_ioasic_irq(irq); | ||
60 | } | ||
61 | |||
62 | static struct irq_chip ioasic_irq_type = { | 46 | static struct irq_chip ioasic_irq_type = { |
63 | .name = "IO-ASIC", | 47 | .name = "IO-ASIC", |
64 | .ack = ack_ioasic_irq, | 48 | .irq_ack = ack_ioasic_irq, |
65 | .mask = mask_ioasic_irq, | 49 | .irq_mask = mask_ioasic_irq, |
66 | .mask_ack = ack_ioasic_irq, | 50 | .irq_mask_ack = ack_ioasic_irq, |
67 | .unmask = unmask_ioasic_irq, | 51 | .irq_unmask = unmask_ioasic_irq, |
68 | }; | 52 | }; |
69 | 53 | ||
70 | |||
71 | #define unmask_ioasic_dma_irq unmask_ioasic_irq | ||
72 | |||
73 | #define mask_ioasic_dma_irq mask_ioasic_irq | ||
74 | |||
75 | #define ack_ioasic_dma_irq ack_ioasic_irq | ||
76 | |||
77 | static inline void end_ioasic_dma_irq(unsigned int irq) | ||
78 | { | ||
79 | clear_ioasic_irq(irq); | ||
80 | fast_iob(); | ||
81 | end_ioasic_irq(irq); | ||
82 | } | ||
83 | |||
84 | static struct irq_chip ioasic_dma_irq_type = { | 54 | static struct irq_chip ioasic_dma_irq_type = { |
85 | .name = "IO-ASIC-DMA", | 55 | .name = "IO-ASIC-DMA", |
86 | .ack = ack_ioasic_dma_irq, | 56 | .irq_ack = ack_ioasic_irq, |
87 | .mask = mask_ioasic_dma_irq, | 57 | .irq_mask = mask_ioasic_irq, |
88 | .mask_ack = ack_ioasic_dma_irq, | 58 | .irq_mask_ack = ack_ioasic_irq, |
89 | .unmask = unmask_ioasic_dma_irq, | 59 | .irq_unmask = unmask_ioasic_irq, |
90 | .end = end_ioasic_dma_irq, | ||
91 | }; | 60 | }; |
92 | 61 | ||
93 | |||
94 | void __init init_ioasic_irqs(int base) | 62 | void __init init_ioasic_irqs(int base) |
95 | { | 63 | { |
96 | int i; | 64 | int i; |
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index ed90a8deabcc..ef31d98c4fb8 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c | |||
@@ -27,43 +27,40 @@ | |||
27 | */ | 27 | */ |
28 | u32 cached_kn02_csr; | 28 | u32 cached_kn02_csr; |
29 | 29 | ||
30 | |||
31 | static int kn02_irq_base; | 30 | static int kn02_irq_base; |
32 | 31 | ||
33 | 32 | static void unmask_kn02_irq(struct irq_data *d) | |
34 | static inline void unmask_kn02_irq(unsigned int irq) | ||
35 | { | 33 | { |
36 | volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + | 34 | volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + |
37 | KN02_CSR); | 35 | KN02_CSR); |
38 | 36 | ||
39 | cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16)); | 37 | cached_kn02_csr |= (1 << (d->irq - kn02_irq_base + 16)); |
40 | *csr = cached_kn02_csr; | 38 | *csr = cached_kn02_csr; |
41 | } | 39 | } |
42 | 40 | ||
43 | static inline void mask_kn02_irq(unsigned int irq) | 41 | static void mask_kn02_irq(struct irq_data *d) |
44 | { | 42 | { |
45 | volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + | 43 | volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + |
46 | KN02_CSR); | 44 | KN02_CSR); |
47 | 45 | ||
48 | cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16)); | 46 | cached_kn02_csr &= ~(1 << (d->irq - kn02_irq_base + 16)); |
49 | *csr = cached_kn02_csr; | 47 | *csr = cached_kn02_csr; |
50 | } | 48 | } |
51 | 49 | ||
52 | static void ack_kn02_irq(unsigned int irq) | 50 | static void ack_kn02_irq(struct irq_data *d) |
53 | { | 51 | { |
54 | mask_kn02_irq(irq); | 52 | mask_kn02_irq(d); |
55 | iob(); | 53 | iob(); |
56 | } | 54 | } |
57 | 55 | ||
58 | static struct irq_chip kn02_irq_type = { | 56 | static struct irq_chip kn02_irq_type = { |
59 | .name = "KN02-CSR", | 57 | .name = "KN02-CSR", |
60 | .ack = ack_kn02_irq, | 58 | .irq_ack = ack_kn02_irq, |
61 | .mask = mask_kn02_irq, | 59 | .irq_mask = mask_kn02_irq, |
62 | .mask_ack = ack_kn02_irq, | 60 | .irq_mask_ack = ack_kn02_irq, |
63 | .unmask = unmask_kn02_irq, | 61 | .irq_unmask = unmask_kn02_irq, |
64 | }; | 62 | }; |
65 | 63 | ||
66 | |||
67 | void __init init_kn02_irqs(int base) | 64 | void __init init_kn02_irqs(int base) |
68 | { | 65 | { |
69 | volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + | 66 | volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + |
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c index 3a96799eb65f..9b1207ae2256 100644 --- a/arch/mips/emma/markeins/irq.c +++ b/arch/mips/emma/markeins/irq.c | |||
@@ -34,13 +34,10 @@ | |||
34 | 34 | ||
35 | #include <asm/emma/emma2rh.h> | 35 | #include <asm/emma/emma2rh.h> |
36 | 36 | ||
37 | static void emma2rh_irq_enable(unsigned int irq) | 37 | static void emma2rh_irq_enable(struct irq_data *d) |
38 | { | 38 | { |
39 | u32 reg_value; | 39 | unsigned int irq = d->irq - EMMA2RH_IRQ_BASE; |
40 | u32 reg_bitmask; | 40 | u32 reg_value, reg_bitmask, reg_index; |
41 | u32 reg_index; | ||
42 | |||
43 | irq -= EMMA2RH_IRQ_BASE; | ||
44 | 41 | ||
45 | reg_index = EMMA2RH_BHIF_INT_EN_0 + | 42 | reg_index = EMMA2RH_BHIF_INT_EN_0 + |
46 | (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); | 43 | (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); |
@@ -49,13 +46,10 @@ static void emma2rh_irq_enable(unsigned int irq) | |||
49 | emma2rh_out32(reg_index, reg_value | reg_bitmask); | 46 | emma2rh_out32(reg_index, reg_value | reg_bitmask); |
50 | } | 47 | } |
51 | 48 | ||
52 | static void emma2rh_irq_disable(unsigned int irq) | 49 | static void emma2rh_irq_disable(struct irq_data *d) |
53 | { | 50 | { |
54 | u32 reg_value; | 51 | unsigned int irq = d->irq - EMMA2RH_IRQ_BASE; |
55 | u32 reg_bitmask; | 52 | u32 reg_value, reg_bitmask, reg_index; |
56 | u32 reg_index; | ||
57 | |||
58 | irq -= EMMA2RH_IRQ_BASE; | ||
59 | 53 | ||
60 | reg_index = EMMA2RH_BHIF_INT_EN_0 + | 54 | reg_index = EMMA2RH_BHIF_INT_EN_0 + |
61 | (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); | 55 | (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); |
@@ -66,10 +60,8 @@ static void emma2rh_irq_disable(unsigned int irq) | |||
66 | 60 | ||
67 | struct irq_chip emma2rh_irq_controller = { | 61 | struct irq_chip emma2rh_irq_controller = { |
68 | .name = "emma2rh_irq", | 62 | .name = "emma2rh_irq", |
69 | .ack = emma2rh_irq_disable, | 63 | .irq_mask = emma2rh_irq_disable, |
70 | .mask = emma2rh_irq_disable, | 64 | .irq_unmask = emma2rh_irq_enable, |
71 | .mask_ack = emma2rh_irq_disable, | ||
72 | .unmask = emma2rh_irq_enable, | ||
73 | }; | 65 | }; |
74 | 66 | ||
75 | void emma2rh_irq_init(void) | 67 | void emma2rh_irq_init(void) |
@@ -82,23 +74,21 @@ void emma2rh_irq_init(void) | |||
82 | handle_level_irq, "level"); | 74 | handle_level_irq, "level"); |
83 | } | 75 | } |
84 | 76 | ||
85 | static void emma2rh_sw_irq_enable(unsigned int irq) | 77 | static void emma2rh_sw_irq_enable(struct irq_data *d) |
86 | { | 78 | { |
79 | unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE; | ||
87 | u32 reg; | 80 | u32 reg; |
88 | 81 | ||
89 | irq -= EMMA2RH_SW_IRQ_BASE; | ||
90 | |||
91 | reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); | 82 | reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); |
92 | reg |= 1 << irq; | 83 | reg |= 1 << irq; |
93 | emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); | 84 | emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); |
94 | } | 85 | } |
95 | 86 | ||
96 | static void emma2rh_sw_irq_disable(unsigned int irq) | 87 | static void emma2rh_sw_irq_disable(struct irq_data *d) |
97 | { | 88 | { |
89 | unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE; | ||
98 | u32 reg; | 90 | u32 reg; |
99 | 91 | ||
100 | irq -= EMMA2RH_SW_IRQ_BASE; | ||
101 | |||
102 | reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); | 92 | reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); |
103 | reg &= ~(1 << irq); | 93 | reg &= ~(1 << irq); |
104 | emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); | 94 | emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); |
@@ -106,10 +96,8 @@ static void emma2rh_sw_irq_disable(unsigned int irq) | |||
106 | 96 | ||
107 | struct irq_chip emma2rh_sw_irq_controller = { | 97 | struct irq_chip emma2rh_sw_irq_controller = { |
108 | .name = "emma2rh_sw_irq", | 98 | .name = "emma2rh_sw_irq", |
109 | .ack = emma2rh_sw_irq_disable, | 99 | .irq_mask = emma2rh_sw_irq_disable, |
110 | .mask = emma2rh_sw_irq_disable, | 100 | .irq_unmask = emma2rh_sw_irq_enable, |
111 | .mask_ack = emma2rh_sw_irq_disable, | ||
112 | .unmask = emma2rh_sw_irq_enable, | ||
113 | }; | 101 | }; |
114 | 102 | ||
115 | void emma2rh_sw_irq_init(void) | 103 | void emma2rh_sw_irq_init(void) |
@@ -122,39 +110,38 @@ void emma2rh_sw_irq_init(void) | |||
122 | handle_level_irq, "level"); | 110 | handle_level_irq, "level"); |
123 | } | 111 | } |
124 | 112 | ||
125 | static void emma2rh_gpio_irq_enable(unsigned int irq) | 113 | static void emma2rh_gpio_irq_enable(struct irq_data *d) |
126 | { | 114 | { |
115 | unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; | ||
127 | u32 reg; | 116 | u32 reg; |
128 | 117 | ||
129 | irq -= EMMA2RH_GPIO_IRQ_BASE; | ||
130 | |||
131 | reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); | 118 | reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); |
132 | reg |= 1 << irq; | 119 | reg |= 1 << irq; |
133 | emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); | 120 | emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); |
134 | } | 121 | } |
135 | 122 | ||
136 | static void emma2rh_gpio_irq_disable(unsigned int irq) | 123 | static void emma2rh_gpio_irq_disable(struct irq_data *d) |
137 | { | 124 | { |
125 | unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; | ||
138 | u32 reg; | 126 | u32 reg; |
139 | 127 | ||
140 | irq -= EMMA2RH_GPIO_IRQ_BASE; | ||
141 | |||
142 | reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); | 128 | reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); |
143 | reg &= ~(1 << irq); | 129 | reg &= ~(1 << irq); |
144 | emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); | 130 | emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); |
145 | } | 131 | } |
146 | 132 | ||
147 | static void emma2rh_gpio_irq_ack(unsigned int irq) | 133 | static void emma2rh_gpio_irq_ack(struct irq_data *d) |
148 | { | 134 | { |
149 | irq -= EMMA2RH_GPIO_IRQ_BASE; | 135 | unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; |
136 | |||
150 | emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); | 137 | emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); |
151 | } | 138 | } |
152 | 139 | ||
153 | static void emma2rh_gpio_irq_mask_ack(unsigned int irq) | 140 | static void emma2rh_gpio_irq_mask_ack(struct irq_data *d) |
154 | { | 141 | { |
142 | unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; | ||
155 | u32 reg; | 143 | u32 reg; |
156 | 144 | ||
157 | irq -= EMMA2RH_GPIO_IRQ_BASE; | ||
158 | emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); | 145 | emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); |
159 | 146 | ||
160 | reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); | 147 | reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); |
@@ -164,10 +151,10 @@ static void emma2rh_gpio_irq_mask_ack(unsigned int irq) | |||
164 | 151 | ||
165 | struct irq_chip emma2rh_gpio_irq_controller = { | 152 | struct irq_chip emma2rh_gpio_irq_controller = { |
166 | .name = "emma2rh_gpio_irq", | 153 | .name = "emma2rh_gpio_irq", |
167 | .ack = emma2rh_gpio_irq_ack, | 154 | .irq_ack = emma2rh_gpio_irq_ack, |
168 | .mask = emma2rh_gpio_irq_disable, | 155 | .irq_mask = emma2rh_gpio_irq_disable, |
169 | .mask_ack = emma2rh_gpio_irq_mask_ack, | 156 | .irq_mask_ack = emma2rh_gpio_irq_mask_ack, |
170 | .unmask = emma2rh_gpio_irq_enable, | 157 | .irq_unmask = emma2rh_gpio_irq_enable, |
171 | }; | 158 | }; |
172 | 159 | ||
173 | void emma2rh_gpio_irq_init(void) | 160 | void emma2rh_gpio_irq_init(void) |
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index b003ed52ed17..0ec01294b063 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h | |||
@@ -55,9 +55,9 @@ static inline void smtc_im_ack_irq(unsigned int irq) | |||
55 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF | 55 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF |
56 | #include <linux/cpumask.h> | 56 | #include <linux/cpumask.h> |
57 | 57 | ||
58 | extern int plat_set_irq_affinity(unsigned int irq, | 58 | extern int plat_set_irq_affinity(struct irq_data *d, |
59 | const struct cpumask *affinity); | 59 | const struct cpumask *affinity, bool force); |
60 | extern void smtc_forward_irq(unsigned int irq); | 60 | extern void smtc_forward_irq(struct irq_data *d); |
61 | 61 | ||
62 | /* | 62 | /* |
63 | * IRQ affinity hook invoked at the beginning of interrupt dispatch | 63 | * IRQ affinity hook invoked at the beginning of interrupt dispatch |
@@ -70,51 +70,53 @@ extern void smtc_forward_irq(unsigned int irq); | |||
70 | * cpumask implementations, this version is optimistically assuming | 70 | * cpumask implementations, this version is optimistically assuming |
71 | * that cpumask.h macro overhead is reasonable during interrupt dispatch. | 71 | * that cpumask.h macro overhead is reasonable during interrupt dispatch. |
72 | */ | 72 | */ |
73 | #define IRQ_AFFINITY_HOOK(irq) \ | 73 | static inline int handle_on_other_cpu(unsigned int irq) |
74 | do { \ | 74 | { |
75 | if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity)) {\ | 75 | struct irq_data *d = irq_get_irq_data(irq); |
76 | smtc_forward_irq(irq); \ | 76 | |
77 | irq_exit(); \ | 77 | if (cpumask_test_cpu(smp_processor_id(), d->affinity)) |
78 | return; \ | 78 | return 0; |
79 | } \ | 79 | smtc_forward_irq(d); |
80 | } while (0) | 80 | return 1; |
81 | } | ||
81 | 82 | ||
82 | #else /* Not doing SMTC affinity */ | 83 | #else /* Not doing SMTC affinity */ |
83 | 84 | ||
84 | #define IRQ_AFFINITY_HOOK(irq) do { } while (0) | 85 | static inline int handle_on_other_cpu(unsigned int irq) { return 0; } |
85 | 86 | ||
86 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | 87 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ |
87 | 88 | ||
88 | #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP | 89 | #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP |
89 | 90 | ||
91 | static inline void smtc_im_backstop(unsigned int irq) | ||
92 | { | ||
93 | if (irq_hwmask[irq] & 0x0000ff00) | ||
94 | write_c0_tccontext(read_c0_tccontext() & | ||
95 | ~(irq_hwmask[irq] & 0x0000ff00)); | ||
96 | } | ||
97 | |||
90 | /* | 98 | /* |
91 | * Clear interrupt mask handling "backstop" if irq_hwmask | 99 | * Clear interrupt mask handling "backstop" if irq_hwmask |
92 | * entry so indicates. This implies that the ack() or end() | 100 | * entry so indicates. This implies that the ack() or end() |
93 | * functions will take over re-enabling the low-level mask. | 101 | * functions will take over re-enabling the low-level mask. |
94 | * Otherwise it will be done on return from exception. | 102 | * Otherwise it will be done on return from exception. |
95 | */ | 103 | */ |
96 | #define __DO_IRQ_SMTC_HOOK(irq) \ | 104 | static inline int smtc_handle_on_other_cpu(unsigned int irq) |
97 | do { \ | 105 | { |
98 | IRQ_AFFINITY_HOOK(irq); \ | 106 | int ret = handle_on_other_cpu(irq); |
99 | if (irq_hwmask[irq] & 0x0000ff00) \ | 107 | |
100 | write_c0_tccontext(read_c0_tccontext() & \ | 108 | if (!ret) |
101 | ~(irq_hwmask[irq] & 0x0000ff00)); \ | 109 | smtc_im_backstop(irq); |
102 | } while (0) | 110 | return ret; |
103 | 111 | } | |
104 | #define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) \ | ||
105 | do { \ | ||
106 | if (irq_hwmask[irq] & 0x0000ff00) \ | ||
107 | write_c0_tccontext(read_c0_tccontext() & \ | ||
108 | ~(irq_hwmask[irq] & 0x0000ff00)); \ | ||
109 | } while (0) | ||
110 | 112 | ||
111 | #else | 113 | #else |
112 | 114 | ||
113 | #define __DO_IRQ_SMTC_HOOK(irq) \ | 115 | static inline void smtc_im_backstop(unsigned int irq) { } |
114 | do { \ | 116 | static inline int smtc_handle_on_other_cpu(unsigned int irq) |
115 | IRQ_AFFINITY_HOOK(irq); \ | 117 | { |
116 | } while (0) | 118 | return handle_on_other_cpu(irq); |
117 | #define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) do { } while (0) | 119 | } |
118 | 120 | ||
119 | #endif | 121 | #endif |
120 | 122 | ||
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h new file mode 100644 index 000000000000..a80801b094bd --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h | |||
@@ -0,0 +1,21 @@ | |||
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) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org) | ||
7 | */ | ||
8 | #ifndef __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H | ||
9 | #define __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H | ||
10 | |||
11 | #define cpu_has_mips16 1 | ||
12 | #define cpu_has_dsp 1 | ||
13 | #define cpu_has_mipsmt 1 | ||
14 | #define cpu_has_fpu 0 | ||
15 | |||
16 | #define cpu_has_mips32r1 0 | ||
17 | #define cpu_has_mips32r2 1 | ||
18 | #define cpu_has_mips64r1 0 | ||
19 | #define cpu_has_mips64r2 0 | ||
20 | |||
21 | #endif /* __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h new file mode 100644 index 000000000000..156f320c69e7 --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h | |||
@@ -0,0 +1,343 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Macros for external SMP-safe access to the PMC MSP71xx reference | ||
4 | * board GPIO pins | ||
5 | * | ||
6 | * Copyright 2010 PMC-Sierra, Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #ifndef __MSP_GPIO_MACROS_H__ | ||
30 | #define __MSP_GPIO_MACROS_H__ | ||
31 | |||
32 | #include <msp_regops.h> | ||
33 | #include <msp_regs.h> | ||
34 | |||
35 | #ifdef CONFIG_PMC_MSP7120_GW | ||
36 | #define MSP_NUM_GPIOS 20 | ||
37 | #else | ||
38 | #define MSP_NUM_GPIOS 28 | ||
39 | #endif | ||
40 | |||
41 | /* -- GPIO Enumerations -- */ | ||
42 | enum msp_gpio_data { | ||
43 | MSP_GPIO_LO = 0, | ||
44 | MSP_GPIO_HI = 1, | ||
45 | MSP_GPIO_NONE, /* Special - Means pin is out of range */ | ||
46 | MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */ | ||
47 | }; | ||
48 | |||
49 | enum msp_gpio_mode { | ||
50 | MSP_GPIO_INPUT = 0x0, | ||
51 | /* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */ | ||
52 | MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */ | ||
53 | MSP_GPIO_OUTPUT = 0x8, | ||
54 | MSP_GPIO_UART_OUTPUT = 0x9, /* Only GPIO 2 or 3 */ | ||
55 | MSP_GPIO_PERIF_TIMERA = 0x9, /* Only GPIO 0 or 1 */ | ||
56 | MSP_GPIO_PERIF_TIMERB = 0xa, /* Only GPIO 0 or 1 */ | ||
57 | MSP_GPIO_UNKNOWN = 0xb, /* No such GPIO or mode */ | ||
58 | }; | ||
59 | |||
60 | /* -- Static Tables -- */ | ||
61 | |||
62 | /* Maps pins to data register */ | ||
63 | static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = { | ||
64 | /* GPIO 0 and 1 on the first register */ | ||
65 | GPIO_DATA1_REG, GPIO_DATA1_REG, | ||
66 | /* GPIO 2, 3, 4, and 5 on the second register */ | ||
67 | GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, | ||
68 | /* GPIO 6, 7, 8, and 9 on the third register */ | ||
69 | GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, | ||
70 | /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */ | ||
71 | GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, | ||
72 | GPIO_DATA4_REG, GPIO_DATA4_REG, | ||
73 | /* GPIO 16 - 23 on the first strange EXTENDED register */ | ||
74 | EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, | ||
75 | EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, | ||
76 | EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, | ||
77 | /* GPIO 24 - 27 on the second strange EXTENDED register */ | ||
78 | EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, | ||
79 | EXTENDED_GPIO2_REG, | ||
80 | }; | ||
81 | |||
82 | /* Maps pins to mode register */ | ||
83 | static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = { | ||
84 | /* GPIO 0 and 1 on the first register */ | ||
85 | GPIO_CFG1_REG, GPIO_CFG1_REG, | ||
86 | /* GPIO 2, 3, 4, and 5 on the second register */ | ||
87 | GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, | ||
88 | /* GPIO 6, 7, 8, and 9 on the third register */ | ||
89 | GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, | ||
90 | /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */ | ||
91 | GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, | ||
92 | GPIO_CFG4_REG, GPIO_CFG4_REG, | ||
93 | /* GPIO 16 - 23 on the first strange EXTENDED register */ | ||
94 | EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, | ||
95 | EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, | ||
96 | EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, | ||
97 | /* GPIO 24 - 27 on the second strange EXTENDED register */ | ||
98 | EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, | ||
99 | EXTENDED_GPIO2_REG, | ||
100 | }; | ||
101 | |||
102 | /* Maps 'basic' pins to relative offset from 0 per register */ | ||
103 | static int MSP_GPIO_OFFSET[] = { | ||
104 | /* GPIO 0 and 1 on the first register */ | ||
105 | 0, 0, | ||
106 | /* GPIO 2, 3, 4, and 5 on the second register */ | ||
107 | 2, 2, 2, 2, | ||
108 | /* GPIO 6, 7, 8, and 9 on the third register */ | ||
109 | 6, 6, 6, 6, | ||
110 | /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */ | ||
111 | 10, 10, 10, 10, 10, 10, | ||
112 | }; | ||
113 | |||
114 | /* Maps MODE to allowed pin mask */ | ||
115 | static unsigned int MSP_GPIO_MODE_ALLOWED[] = { | ||
116 | 0xffffffff, /* Mode 0 - INPUT */ | ||
117 | 0x00000, /* Mode 1 - INTERRUPT */ | ||
118 | 0x00030, /* Mode 2 - UART_INPUT (GPIO 4, 5)*/ | ||
119 | 0, 0, 0, 0, 0, /* Modes 3, 4, 5, 6, and 7 are reserved */ | ||
120 | 0xffffffff, /* Mode 8 - OUTPUT */ | ||
121 | 0x0000f, /* Mode 9 - UART_OUTPUT/ | ||
122 | PERF_TIMERA (GPIO 0, 1, 2, 3) */ | ||
123 | 0x00003, /* Mode a - PERF_TIMERB (GPIO 0, 1) */ | ||
124 | 0x00000, /* Mode b - Not really a mode! */ | ||
125 | }; | ||
126 | |||
127 | /* -- Bit masks -- */ | ||
128 | |||
129 | /* This gives you the 'register relative offset gpio' number */ | ||
130 | #define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio]) | ||
131 | |||
132 | /* These take the 'register relative offset gpio' number */ | ||
133 | #define BASIC_DATA_REG_MASK(ogpio) (1 << ogpio) | ||
134 | #define BASIC_MODE_REG_VALUE(mode, ogpio) \ | ||
135 | (mode << BASIC_MODE_REG_SHIFT(ogpio)) | ||
136 | #define BASIC_MODE_REG_MASK(ogpio) \ | ||
137 | BASIC_MODE_REG_VALUE(0xf, ogpio) | ||
138 | #define BASIC_MODE_REG_SHIFT(ogpio) (ogpio * 4) | ||
139 | #define BASIC_MODE_REG_FROM_REG(data, ogpio) \ | ||
140 | ((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio)) | ||
141 | |||
142 | /* These take the actual GPIO number (0 through 15) */ | ||
143 | #define BASIC_DATA_MASK(gpio) \ | ||
144 | BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio)) | ||
145 | #define BASIC_MODE_MASK(gpio) \ | ||
146 | BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio)) | ||
147 | #define BASIC_MODE(mode, gpio) \ | ||
148 | BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio)) | ||
149 | #define BASIC_MODE_SHIFT(gpio) \ | ||
150 | BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio)) | ||
151 | #define BASIC_MODE_FROM_REG(data, gpio) \ | ||
152 | BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio)) | ||
153 | |||
154 | /* | ||
155 | * Each extended GPIO register is 32 bits long and is responsible for up to | ||
156 | * eight GPIOs. The least significant 16 bits contain the set and clear bit | ||
157 | * pair for each of the GPIOs. The most significant 16 bits contain the | ||
158 | * disable and enable bit pair for each of the GPIOs. For example, the | ||
159 | * extended GPIO reg for GPIOs 16-23 is as follows: | ||
160 | * | ||
161 | * 31: GPIO23_DISABLE | ||
162 | * ... | ||
163 | * 19: GPIO17_DISABLE | ||
164 | * 18: GPIO17_ENABLE | ||
165 | * 17: GPIO16_DISABLE | ||
166 | * 16: GPIO16_ENABLE | ||
167 | * ... | ||
168 | * 3: GPIO17_SET | ||
169 | * 2: GPIO17_CLEAR | ||
170 | * 1: GPIO16_SET | ||
171 | * 0: GPIO16_CLEAR | ||
172 | */ | ||
173 | |||
174 | /* This gives the 'register relative offset gpio' number */ | ||
175 | #define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24) | ||
176 | |||
177 | /* These take the 'register relative offset gpio' number */ | ||
178 | #define EXTENDED_REG_DISABLE(ogpio) (0x2 << ((ogpio * 2) + 16)) | ||
179 | #define EXTENDED_REG_ENABLE(ogpio) (0x1 << ((ogpio * 2) + 16)) | ||
180 | #define EXTENDED_REG_SET(ogpio) (0x2 << (ogpio * 2)) | ||
181 | #define EXTENDED_REG_CLR(ogpio) (0x1 << (ogpio * 2)) | ||
182 | |||
183 | /* These take the actual GPIO number (16 through 27) */ | ||
184 | #define EXTENDED_DISABLE(gpio) \ | ||
185 | EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio)) | ||
186 | #define EXTENDED_ENABLE(gpio) \ | ||
187 | EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio)) | ||
188 | #define EXTENDED_SET(gpio) \ | ||
189 | EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio)) | ||
190 | #define EXTENDED_CLR(gpio) \ | ||
191 | EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio)) | ||
192 | |||
193 | #define EXTENDED_FULL_MASK (0xffffffff) | ||
194 | |||
195 | /* -- API inline-functions -- */ | ||
196 | |||
197 | /* | ||
198 | * Gets the current value of the specified pin | ||
199 | */ | ||
200 | static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio) | ||
201 | { | ||
202 | u32 pinhi_mask = 0, pinhi_mask2 = 0; | ||
203 | |||
204 | if (gpio >= MSP_NUM_GPIOS) | ||
205 | return MSP_GPIO_NONE; | ||
206 | |||
207 | if (gpio < 16) { | ||
208 | pinhi_mask = BASIC_DATA_MASK(gpio); | ||
209 | } else { | ||
210 | /* | ||
211 | * Two cases are possible with the EXTENDED register: | ||
212 | * - In output mode (ENABLED flag set), check the CLR bit | ||
213 | * - In input mode (ENABLED flag not set), check the SET bit | ||
214 | */ | ||
215 | pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio); | ||
216 | pinhi_mask2 = EXTENDED_SET(gpio); | ||
217 | } | ||
218 | if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) || | ||
219 | (*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2)) | ||
220 | return MSP_GPIO_HI; | ||
221 | else | ||
222 | return MSP_GPIO_LO; | ||
223 | } | ||
224 | |||
225 | /* Sets the specified pin to the specified value */ | ||
226 | static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio) | ||
227 | { | ||
228 | if (gpio >= MSP_NUM_GPIOS) | ||
229 | return; | ||
230 | |||
231 | if (gpio < 16) { | ||
232 | if (data == MSP_GPIO_TOGGLE) | ||
233 | toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio], | ||
234 | BASIC_DATA_MASK(gpio)); | ||
235 | else if (data == MSP_GPIO_HI) | ||
236 | set_reg32(MSP_GPIO_DATA_REGISTER[gpio], | ||
237 | BASIC_DATA_MASK(gpio)); | ||
238 | else | ||
239 | clear_reg32(MSP_GPIO_DATA_REGISTER[gpio], | ||
240 | BASIC_DATA_MASK(gpio)); | ||
241 | } else { | ||
242 | if (data == MSP_GPIO_TOGGLE) { | ||
243 | /* Special ugly case: | ||
244 | * We have to read the CLR bit. | ||
245 | * If set, we write the CLR bit. | ||
246 | * If not, we write the SET bit. | ||
247 | */ | ||
248 | u32 tmpdata; | ||
249 | |||
250 | custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio], | ||
251 | tmpdata); | ||
252 | if (tmpdata & EXTENDED_CLR(gpio)) | ||
253 | tmpdata = EXTENDED_CLR(gpio); | ||
254 | else | ||
255 | tmpdata = EXTENDED_SET(gpio); | ||
256 | custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio], | ||
257 | tmpdata); | ||
258 | } else { | ||
259 | u32 newdata; | ||
260 | |||
261 | if (data == MSP_GPIO_HI) | ||
262 | newdata = EXTENDED_SET(gpio); | ||
263 | else | ||
264 | newdata = EXTENDED_CLR(gpio); | ||
265 | set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio], | ||
266 | EXTENDED_FULL_MASK, newdata); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | /* Sets the specified pin to the specified value */ | ||
272 | static inline void msp_gpio_pin_hi(unsigned int gpio) | ||
273 | { | ||
274 | msp_gpio_pin_set(MSP_GPIO_HI, gpio); | ||
275 | } | ||
276 | |||
277 | /* Sets the specified pin to the specified value */ | ||
278 | static inline void msp_gpio_pin_lo(unsigned int gpio) | ||
279 | { | ||
280 | msp_gpio_pin_set(MSP_GPIO_LO, gpio); | ||
281 | } | ||
282 | |||
283 | /* Sets the specified pin to the opposite value */ | ||
284 | static inline void msp_gpio_pin_toggle(unsigned int gpio) | ||
285 | { | ||
286 | msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio); | ||
287 | } | ||
288 | |||
289 | /* Gets the mode of the specified pin */ | ||
290 | static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio) | ||
291 | { | ||
292 | enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN; | ||
293 | uint32_t data; | ||
294 | |||
295 | if (gpio >= MSP_NUM_GPIOS) | ||
296 | return retval; | ||
297 | |||
298 | data = *MSP_GPIO_MODE_REGISTER[gpio]; | ||
299 | |||
300 | if (gpio < 16) { | ||
301 | retval = BASIC_MODE_FROM_REG(data, gpio); | ||
302 | } else { | ||
303 | /* Extended pins can only be either INPUT or OUTPUT */ | ||
304 | if (data & EXTENDED_ENABLE(gpio)) | ||
305 | retval = MSP_GPIO_OUTPUT; | ||
306 | else | ||
307 | retval = MSP_GPIO_INPUT; | ||
308 | } | ||
309 | |||
310 | return retval; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Sets the specified mode on the requested pin | ||
315 | * Returns 0 on success, or -1 if that mode is not allowed on this pin | ||
316 | */ | ||
317 | static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio) | ||
318 | { | ||
319 | u32 modemask, newmode; | ||
320 | |||
321 | if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode]) | ||
322 | return -1; | ||
323 | |||
324 | if (gpio >= MSP_NUM_GPIOS) | ||
325 | return -1; | ||
326 | |||
327 | if (gpio < 16) { | ||
328 | modemask = BASIC_MODE_MASK(gpio); | ||
329 | newmode = BASIC_MODE(mode, gpio); | ||
330 | } else { | ||
331 | modemask = EXTENDED_FULL_MASK; | ||
332 | if (mode == MSP_GPIO_INPUT) | ||
333 | newmode = EXTENDED_DISABLE(gpio); | ||
334 | else | ||
335 | newmode = EXTENDED_ENABLE(gpio); | ||
336 | } | ||
337 | /* Do the set atomically */ | ||
338 | set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | #endif /* __MSP_GPIO_MACROS_H__ */ | ||
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h index 603eb737b4a8..692c1b658b92 100644 --- a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h | |||
@@ -91,12 +91,10 @@ | |||
91 | /* MAC C device registers */ | 91 | /* MAC C device registers */ |
92 | #define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000) | 92 | #define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000) |
93 | /* ADSL2 device registers */ | 93 | /* ADSL2 device registers */ |
94 | #define MSP_USB_BASE (MSP_MSB_BASE + 0xB40000) | 94 | #define MSP_USB0_BASE (MSP_MSB_BASE + 0xB00000) |
95 | /* USB device registers */ | 95 | /* USB0 device registers */ |
96 | #define MSP_USB_BASE_START (MSP_MSB_BASE + 0xB40100) | 96 | #define MSP_USB1_BASE (MSP_MSB_BASE + 0x300000) |
97 | /* USB device registers */ | 97 | /* USB1 device registers */ |
98 | #define MSP_USB_BASE_END (MSP_MSB_BASE + 0xB401FF) | ||
99 | /* USB device registers */ | ||
100 | #define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000) | 98 | #define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000) |
101 | /* CPU interface registers */ | 99 | /* CPU interface registers */ |
102 | 100 | ||
@@ -319,8 +317,11 @@ | |||
319 | #define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184) | 317 | #define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184) |
320 | /* CPU/SLP Error status 1 */ | 318 | /* CPU/SLP Error status 1 */ |
321 | 319 | ||
322 | #define EXTENDED_GPIO_REG regptr(MSP_SLP_BASE + 0x188) | 320 | /* Extended GPIO registers */ |
323 | /* Extended GPIO register */ | 321 | #define EXTENDED_GPIO1_REG regptr(MSP_SLP_BASE + 0x188) |
322 | #define EXTENDED_GPIO2_REG regptr(MSP_SLP_BASE + 0x18c) | ||
323 | #define EXTENDED_GPIO_REG EXTENDED_GPIO1_REG | ||
324 | /* Backward-compatibility */ | ||
324 | 325 | ||
325 | /* System Error registers */ | 326 | /* System Error registers */ |
326 | #define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190) | 327 | #define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190) |
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h new file mode 100644 index 000000000000..4c9348df9df2 --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h | |||
@@ -0,0 +1,144 @@ | |||
1 | /****************************************************************** | ||
2 | * Copyright (c) 2000-2007 PMC-Sierra INC. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it | ||
5 | * and/or modify it under the terms of the GNU General | ||
6 | * Public License as published by the Free Software | ||
7 | * Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * This program 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 | ||
13 | * PURPOSE. See the GNU General Public License for more | ||
14 | * details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public | ||
17 | * License along with this program; if not, write to the Free | ||
18 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA | ||
19 | * 02139, USA. | ||
20 | * | ||
21 | * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND | ||
22 | * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS | ||
23 | * SOFTWARE. | ||
24 | */ | ||
25 | #ifndef MSP_USB_H_ | ||
26 | #define MSP_USB_H_ | ||
27 | |||
28 | #ifdef CONFIG_MSP_HAS_DUAL_USB | ||
29 | #define NUM_USB_DEVS 2 | ||
30 | #else | ||
31 | #define NUM_USB_DEVS 1 | ||
32 | #endif | ||
33 | |||
34 | /* Register spaces for USB host 0 */ | ||
35 | #define MSP_USB0_MAB_START (MSP_USB0_BASE + 0x0) | ||
36 | #define MSP_USB0_MAB_END (MSP_USB0_BASE + 0x17) | ||
37 | #define MSP_USB0_ID_START (MSP_USB0_BASE + 0x40000) | ||
38 | #define MSP_USB0_ID_END (MSP_USB0_BASE + 0x4008f) | ||
39 | #define MSP_USB0_HS_START (MSP_USB0_BASE + 0x40100) | ||
40 | #define MSP_USB0_HS_END (MSP_USB0_BASE + 0x401FF) | ||
41 | |||
42 | /* Register spaces for USB host 1 */ | ||
43 | #define MSP_USB1_MAB_START (MSP_USB1_BASE + 0x0) | ||
44 | #define MSP_USB1_MAB_END (MSP_USB1_BASE + 0x17) | ||
45 | #define MSP_USB1_ID_START (MSP_USB1_BASE + 0x40000) | ||
46 | #define MSP_USB1_ID_END (MSP_USB1_BASE + 0x4008f) | ||
47 | #define MSP_USB1_HS_START (MSP_USB1_BASE + 0x40100) | ||
48 | #define MSP_USB1_HS_END (MSP_USB1_BASE + 0x401ff) | ||
49 | |||
50 | /* USB Identification registers */ | ||
51 | struct msp_usbid_regs { | ||
52 | u32 id; /* 0x0: Identification register */ | ||
53 | u32 hwgen; /* 0x4: General HW params */ | ||
54 | u32 hwhost; /* 0x8: Host HW params */ | ||
55 | u32 hwdev; /* 0xc: Device HW params */ | ||
56 | u32 hwtxbuf; /* 0x10: Tx buffer HW params */ | ||
57 | u32 hwrxbuf; /* 0x14: Rx buffer HW params */ | ||
58 | u32 reserved[26]; | ||
59 | u32 timer0_load; /* 0x80: General-purpose timer 0 load*/ | ||
60 | u32 timer0_ctrl; /* 0x84: General-purpose timer 0 control */ | ||
61 | u32 timer1_load; /* 0x88: General-purpose timer 1 load*/ | ||
62 | u32 timer1_ctrl; /* 0x8c: General-purpose timer 1 control */ | ||
63 | }; | ||
64 | |||
65 | /* MSBus to AMBA registers */ | ||
66 | struct msp_mab_regs { | ||
67 | u32 isr; /* 0x0: Interrupt status */ | ||
68 | u32 imr; /* 0x4: Interrupt mask */ | ||
69 | u32 thcr0; /* 0x8: Transaction header capture 0 */ | ||
70 | u32 thcr1; /* 0xc: Transaction header capture 1 */ | ||
71 | u32 int_stat; /* 0x10: Interrupt status summary */ | ||
72 | u32 phy_cfg; /* 0x14: USB phy config */ | ||
73 | }; | ||
74 | |||
75 | /* EHCI registers */ | ||
76 | struct msp_usbhs_regs { | ||
77 | u32 hciver; /* 0x0: Version and offset to operational regs */ | ||
78 | u32 hcsparams; /* 0x4: Host control structural parameters */ | ||
79 | u32 hccparams; /* 0x8: Host control capability parameters */ | ||
80 | u32 reserved0[5]; | ||
81 | u32 dciver; /* 0x20: Device interface version */ | ||
82 | u32 dccparams; /* 0x24: Device control capability parameters */ | ||
83 | u32 reserved1[6]; | ||
84 | u32 cmd; /* 0x40: USB command */ | ||
85 | u32 sts; /* 0x44: USB status */ | ||
86 | u32 int_ena; /* 0x48: USB interrupt enable */ | ||
87 | u32 frindex; /* 0x4c: Frame index */ | ||
88 | u32 reserved3; | ||
89 | union { | ||
90 | struct { | ||
91 | u32 flb_addr; /* 0x54: Frame list base address */ | ||
92 | u32 next_async_addr; /* 0x58: next asynchronous addr */ | ||
93 | u32 ttctrl; /* 0x5c: embedded transaction translator | ||
94 | async buffer status */ | ||
95 | u32 burst_size; /* 0x60: Controller burst size */ | ||
96 | u32 tx_fifo_ctrl; /* 0x64: Tx latency FIFO tuning */ | ||
97 | u32 reserved0[4]; | ||
98 | u32 endpt_nak; /* 0x78: Endpoint NAK */ | ||
99 | u32 endpt_nak_ena; /* 0x7c: Endpoint NAK enable */ | ||
100 | u32 cfg_flag; /* 0x80: Config flag */ | ||
101 | u32 port_sc1; /* 0x84: Port status & control 1 */ | ||
102 | u32 reserved1[7]; | ||
103 | u32 otgsc; /* 0xa4: OTG status & control */ | ||
104 | u32 mode; /* 0xa8: USB controller mode */ | ||
105 | } host; | ||
106 | |||
107 | struct { | ||
108 | u32 dev_addr; /* 0x54: Device address */ | ||
109 | u32 endpt_list_addr; /* 0x58: Endpoint list address */ | ||
110 | u32 reserved0[7]; | ||
111 | u32 endpt_nak; /* 0x74 */ | ||
112 | u32 endpt_nak_ctrl; /* 0x78 */ | ||
113 | u32 cfg_flag; /* 0x80 */ | ||
114 | u32 port_sc1; /* 0x84: Port status & control 1 */ | ||
115 | u32 reserved[7]; | ||
116 | u32 otgsc; /* 0xa4: OTG status & control */ | ||
117 | u32 mode; /* 0xa8: USB controller mode */ | ||
118 | u32 endpt_setup_stat; /* 0xac */ | ||
119 | u32 endpt_prime; /* 0xb0 */ | ||
120 | u32 endpt_flush; /* 0xb4 */ | ||
121 | u32 endpt_stat; /* 0xb8 */ | ||
122 | u32 endpt_complete; /* 0xbc */ | ||
123 | u32 endpt_ctrl0; /* 0xc0 */ | ||
124 | u32 endpt_ctrl1; /* 0xc4 */ | ||
125 | u32 endpt_ctrl2; /* 0xc8 */ | ||
126 | u32 endpt_ctrl3; /* 0xcc */ | ||
127 | } device; | ||
128 | } u; | ||
129 | }; | ||
130 | /* | ||
131 | * Container for the more-generic platform_device. | ||
132 | * This exists mainly as a way to map the non-standard register | ||
133 | * spaces and make them accessible to the USB ISR. | ||
134 | */ | ||
135 | struct mspusb_device { | ||
136 | struct msp_mab_regs __iomem *mab_regs; | ||
137 | struct msp_usbid_regs __iomem *usbid_regs; | ||
138 | struct msp_usbhs_regs __iomem *usbhs_regs; | ||
139 | struct platform_device dev; | ||
140 | }; | ||
141 | |||
142 | #define to_mspusb_device(x) container_of((x), struct mspusb_device, dev) | ||
143 | #define TO_HOST_ID(x) ((x) & 0x3) | ||
144 | #endif /*MSP_USB_H_*/ | ||
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 396e402fbe2c..ca61e846ab0f 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h | |||
@@ -245,16 +245,16 @@ static inline void arch_read_lock(arch_rwlock_t *rw) | |||
245 | __asm__ __volatile__( | 245 | __asm__ __volatile__( |
246 | " .set noreorder # arch_read_lock \n" | 246 | " .set noreorder # arch_read_lock \n" |
247 | "1: ll %1, %2 \n" | 247 | "1: ll %1, %2 \n" |
248 | " bltz %1, 2f \n" | 248 | " bltz %1, 3f \n" |
249 | " addu %1, 1 \n" | 249 | " addu %1, 1 \n" |
250 | " sc %1, %0 \n" | 250 | "2: sc %1, %0 \n" |
251 | " beqz %1, 1b \n" | 251 | " beqz %1, 1b \n" |
252 | " nop \n" | 252 | " nop \n" |
253 | " .subsection 2 \n" | 253 | " .subsection 2 \n" |
254 | "2: ll %1, %2 \n" | 254 | "3: ll %1, %2 \n" |
255 | " bltz %1, 2b \n" | 255 | " bltz %1, 3b \n" |
256 | " addu %1, 1 \n" | 256 | " addu %1, 1 \n" |
257 | " b 1b \n" | 257 | " b 2b \n" |
258 | " nop \n" | 258 | " nop \n" |
259 | " .previous \n" | 259 | " .previous \n" |
260 | " .set reorder \n" | 260 | " .set reorder \n" |
@@ -324,16 +324,16 @@ static inline void arch_write_lock(arch_rwlock_t *rw) | |||
324 | __asm__ __volatile__( | 324 | __asm__ __volatile__( |
325 | " .set noreorder # arch_write_lock \n" | 325 | " .set noreorder # arch_write_lock \n" |
326 | "1: ll %1, %2 \n" | 326 | "1: ll %1, %2 \n" |
327 | " bnez %1, 2f \n" | 327 | " bnez %1, 3f \n" |
328 | " lui %1, 0x8000 \n" | 328 | " lui %1, 0x8000 \n" |
329 | " sc %1, %0 \n" | 329 | "2: sc %1, %0 \n" |
330 | " beqz %1, 2f \n" | 330 | " beqz %1, 3f \n" |
331 | " nop \n" | 331 | " nop \n" |
332 | " .subsection 2 \n" | 332 | " .subsection 2 \n" |
333 | "2: ll %1, %2 \n" | 333 | "3: ll %1, %2 \n" |
334 | " bnez %1, 2b \n" | 334 | " bnez %1, 3b \n" |
335 | " lui %1, 0x8000 \n" | 335 | " lui %1, 0x8000 \n" |
336 | " b 1b \n" | 336 | " b 2b \n" |
337 | " nop \n" | 337 | " nop \n" |
338 | " .previous \n" | 338 | " .previous \n" |
339 | " .set reorder \n" | 339 | " .set reorder \n" |
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 550725b881d5..dae22c1d2c82 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h | |||
@@ -359,16 +359,20 @@ | |||
359 | #define __NR_fanotify_init (__NR_Linux + 336) | 359 | #define __NR_fanotify_init (__NR_Linux + 336) |
360 | #define __NR_fanotify_mark (__NR_Linux + 337) | 360 | #define __NR_fanotify_mark (__NR_Linux + 337) |
361 | #define __NR_prlimit64 (__NR_Linux + 338) | 361 | #define __NR_prlimit64 (__NR_Linux + 338) |
362 | #define __NR_name_to_handle_at (__NR_Linux + 339) | ||
363 | #define __NR_open_by_handle_at (__NR_Linux + 340) | ||
364 | #define __NR_clock_adjtime (__NR_Linux + 341) | ||
365 | #define __NR_syncfs (__NR_Linux + 342) | ||
362 | 366 | ||
363 | /* | 367 | /* |
364 | * Offset of the last Linux o32 flavoured syscall | 368 | * Offset of the last Linux o32 flavoured syscall |
365 | */ | 369 | */ |
366 | #define __NR_Linux_syscalls 338 | 370 | #define __NR_Linux_syscalls 342 |
367 | 371 | ||
368 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 372 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
369 | 373 | ||
370 | #define __NR_O32_Linux 4000 | 374 | #define __NR_O32_Linux 4000 |
371 | #define __NR_O32_Linux_syscalls 338 | 375 | #define __NR_O32_Linux_syscalls 342 |
372 | 376 | ||
373 | #if _MIPS_SIM == _MIPS_SIM_ABI64 | 377 | #if _MIPS_SIM == _MIPS_SIM_ABI64 |
374 | 378 | ||
@@ -674,16 +678,20 @@ | |||
674 | #define __NR_fanotify_init (__NR_Linux + 295) | 678 | #define __NR_fanotify_init (__NR_Linux + 295) |
675 | #define __NR_fanotify_mark (__NR_Linux + 296) | 679 | #define __NR_fanotify_mark (__NR_Linux + 296) |
676 | #define __NR_prlimit64 (__NR_Linux + 297) | 680 | #define __NR_prlimit64 (__NR_Linux + 297) |
681 | #define __NR_name_to_handle_at (__NR_Linux + 298) | ||
682 | #define __NR_open_by_handle_at (__NR_Linux + 299) | ||
683 | #define __NR_clock_adjtime (__NR_Linux + 300) | ||
684 | #define __NR_syncfs (__NR_Linux + 301) | ||
677 | 685 | ||
678 | /* | 686 | /* |
679 | * Offset of the last Linux 64-bit flavoured syscall | 687 | * Offset of the last Linux 64-bit flavoured syscall |
680 | */ | 688 | */ |
681 | #define __NR_Linux_syscalls 297 | 689 | #define __NR_Linux_syscalls 301 |
682 | 690 | ||
683 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 691 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
684 | 692 | ||
685 | #define __NR_64_Linux 5000 | 693 | #define __NR_64_Linux 5000 |
686 | #define __NR_64_Linux_syscalls 297 | 694 | #define __NR_64_Linux_syscalls 301 |
687 | 695 | ||
688 | #if _MIPS_SIM == _MIPS_SIM_NABI32 | 696 | #if _MIPS_SIM == _MIPS_SIM_NABI32 |
689 | 697 | ||
@@ -994,16 +1002,20 @@ | |||
994 | #define __NR_fanotify_init (__NR_Linux + 300) | 1002 | #define __NR_fanotify_init (__NR_Linux + 300) |
995 | #define __NR_fanotify_mark (__NR_Linux + 301) | 1003 | #define __NR_fanotify_mark (__NR_Linux + 301) |
996 | #define __NR_prlimit64 (__NR_Linux + 302) | 1004 | #define __NR_prlimit64 (__NR_Linux + 302) |
1005 | #define __NR_name_to_handle_at (__NR_Linux + 303) | ||
1006 | #define __NR_open_by_handle_at (__NR_Linux + 304) | ||
1007 | #define __NR_clock_adjtime (__NR_Linux + 305) | ||
1008 | #define __NR_clock_adjtime (__NR_Linux + 306) | ||
997 | 1009 | ||
998 | /* | 1010 | /* |
999 | * Offset of the last N32 flavoured syscall | 1011 | * Offset of the last N32 flavoured syscall |
1000 | */ | 1012 | */ |
1001 | #define __NR_Linux_syscalls 302 | 1013 | #define __NR_Linux_syscalls 306 |
1002 | 1014 | ||
1003 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 1015 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
1004 | 1016 | ||
1005 | #define __NR_N32_Linux 6000 | 1017 | #define __NR_N32_Linux 6000 |
1006 | #define __NR_N32_Linux_syscalls 302 | 1018 | #define __NR_N32_Linux_syscalls 306 |
1007 | 1019 | ||
1008 | #ifdef __KERNEL__ | 1020 | #ifdef __KERNEL__ |
1009 | 1021 | ||
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index 35b3e2f0af04..40f7c6b1e260 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c | |||
@@ -23,9 +23,9 @@ | |||
23 | 23 | ||
24 | static DEFINE_RAW_SPINLOCK(r4030_lock); | 24 | static DEFINE_RAW_SPINLOCK(r4030_lock); |
25 | 25 | ||
26 | static void enable_r4030_irq(unsigned int irq) | 26 | static void enable_r4030_irq(struct irq_data *d) |
27 | { | 27 | { |
28 | unsigned int mask = 1 << (irq - JAZZ_IRQ_START); | 28 | unsigned int mask = 1 << (d->irq - JAZZ_IRQ_START); |
29 | unsigned long flags; | 29 | unsigned long flags; |
30 | 30 | ||
31 | raw_spin_lock_irqsave(&r4030_lock, flags); | 31 | raw_spin_lock_irqsave(&r4030_lock, flags); |
@@ -34,9 +34,9 @@ static void enable_r4030_irq(unsigned int irq) | |||
34 | raw_spin_unlock_irqrestore(&r4030_lock, flags); | 34 | raw_spin_unlock_irqrestore(&r4030_lock, flags); |
35 | } | 35 | } |
36 | 36 | ||
37 | void disable_r4030_irq(unsigned int irq) | 37 | void disable_r4030_irq(struct irq_data *d) |
38 | { | 38 | { |
39 | unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START)); | 39 | unsigned int mask = ~(1 << (d->irq - JAZZ_IRQ_START)); |
40 | unsigned long flags; | 40 | unsigned long flags; |
41 | 41 | ||
42 | raw_spin_lock_irqsave(&r4030_lock, flags); | 42 | raw_spin_lock_irqsave(&r4030_lock, flags); |
@@ -47,10 +47,8 @@ void disable_r4030_irq(unsigned int irq) | |||
47 | 47 | ||
48 | static struct irq_chip r4030_irq_type = { | 48 | static struct irq_chip r4030_irq_type = { |
49 | .name = "R4030", | 49 | .name = "R4030", |
50 | .ack = disable_r4030_irq, | 50 | .irq_mask = disable_r4030_irq, |
51 | .mask = disable_r4030_irq, | 51 | .irq_unmask = enable_r4030_irq, |
52 | .mask_ack = disable_r4030_irq, | ||
53 | .unmask = enable_r4030_irq, | ||
54 | }; | 52 | }; |
55 | 53 | ||
56 | void __init init_r4030_ints(void) | 54 | void __init init_r4030_ints(void) |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 2c0e107966ad..bc18daaa8f84 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/spi/spi_gpio.h> | 23 | #include <linux/spi/spi_gpio.h> |
24 | #include <linux/power_supply.h> | 24 | #include <linux/power_supply.h> |
25 | #include <linux/power/jz4740-battery.h> | 25 | #include <linux/power/jz4740-battery.h> |
26 | #include <linux/power/gpio-charger.h> | ||
26 | 27 | ||
27 | #include <asm/mach-jz4740/jz4740_fb.h> | 28 | #include <asm/mach-jz4740/jz4740_fb.h> |
28 | #include <asm/mach-jz4740/jz4740_mmc.h> | 29 | #include <asm/mach-jz4740/jz4740_mmc.h> |
@@ -49,14 +50,14 @@ static bool is_avt2; | |||
49 | 50 | ||
50 | /* NAND */ | 51 | /* NAND */ |
51 | static struct nand_ecclayout qi_lb60_ecclayout_1gb = { | 52 | static struct nand_ecclayout qi_lb60_ecclayout_1gb = { |
52 | /* .eccbytes = 36, | 53 | .eccbytes = 36, |
53 | .eccpos = { | 54 | .eccpos = { |
54 | 6, 7, 8, 9, 10, 11, 12, 13, | 55 | 6, 7, 8, 9, 10, 11, 12, 13, |
55 | 14, 15, 16, 17, 18, 19, 20, 21, | 56 | 14, 15, 16, 17, 18, 19, 20, 21, |
56 | 22, 23, 24, 25, 26, 27, 28, 29, | 57 | 22, 23, 24, 25, 26, 27, 28, 29, |
57 | 30, 31, 32, 33, 34, 35, 36, 37, | 58 | 30, 31, 32, 33, 34, 35, 36, 37, |
58 | 38, 39, 40, 41 | 59 | 38, 39, 40, 41 |
59 | },*/ | 60 | }, |
60 | .oobfree = { | 61 | .oobfree = { |
61 | { .offset = 2, .length = 4 }, | 62 | { .offset = 2, .length = 4 }, |
62 | { .offset = 42, .length = 22 } | 63 | { .offset = 42, .length = 22 } |
@@ -85,7 +86,7 @@ static struct mtd_partition qi_lb60_partitions_1gb[] = { | |||
85 | }; | 86 | }; |
86 | 87 | ||
87 | static struct nand_ecclayout qi_lb60_ecclayout_2gb = { | 88 | static struct nand_ecclayout qi_lb60_ecclayout_2gb = { |
88 | /* .eccbytes = 72, | 89 | .eccbytes = 72, |
89 | .eccpos = { | 90 | .eccpos = { |
90 | 12, 13, 14, 15, 16, 17, 18, 19, | 91 | 12, 13, 14, 15, 16, 17, 18, 19, |
91 | 20, 21, 22, 23, 24, 25, 26, 27, | 92 | 20, 21, 22, 23, 24, 25, 26, 27, |
@@ -96,7 +97,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_2gb = { | |||
96 | 60, 61, 62, 63, 64, 65, 66, 67, | 97 | 60, 61, 62, 63, 64, 65, 66, 67, |
97 | 68, 69, 70, 71, 72, 73, 74, 75, | 98 | 68, 69, 70, 71, 72, 73, 74, 75, |
98 | 76, 77, 78, 79, 80, 81, 82, 83 | 99 | 76, 77, 78, 79, 80, 81, 82, 83 |
99 | },*/ | 100 | }, |
100 | .oobfree = { | 101 | .oobfree = { |
101 | { .offset = 2, .length = 10 }, | 102 | { .offset = 2, .length = 10 }, |
102 | { .offset = 84, .length = 44 }, | 103 | { .offset = 84, .length = 44 }, |
@@ -396,6 +397,28 @@ static struct platform_device qi_lb60_pwm_beeper = { | |||
396 | }, | 397 | }, |
397 | }; | 398 | }; |
398 | 399 | ||
400 | /* charger */ | ||
401 | static char *qi_lb60_batteries[] = { | ||
402 | "battery", | ||
403 | }; | ||
404 | |||
405 | static struct gpio_charger_platform_data qi_lb60_charger_pdata = { | ||
406 | .name = "usb", | ||
407 | .type = POWER_SUPPLY_TYPE_USB, | ||
408 | .gpio = JZ_GPIO_PORTD(28), | ||
409 | .gpio_active_low = 1, | ||
410 | .supplied_to = qi_lb60_batteries, | ||
411 | .num_supplicants = ARRAY_SIZE(qi_lb60_batteries), | ||
412 | }; | ||
413 | |||
414 | static struct platform_device qi_lb60_charger_device = { | ||
415 | .name = "gpio-charger", | ||
416 | .dev = { | ||
417 | .platform_data = &qi_lb60_charger_pdata, | ||
418 | }, | ||
419 | }; | ||
420 | |||
421 | |||
399 | static struct platform_device *jz_platform_devices[] __initdata = { | 422 | static struct platform_device *jz_platform_devices[] __initdata = { |
400 | &jz4740_udc_device, | 423 | &jz4740_udc_device, |
401 | &jz4740_mmc_device, | 424 | &jz4740_mmc_device, |
@@ -410,6 +433,7 @@ static struct platform_device *jz_platform_devices[] __initdata = { | |||
410 | &jz4740_adc_device, | 433 | &jz4740_adc_device, |
411 | &qi_lb60_gpio_keys, | 434 | &qi_lb60_gpio_keys, |
412 | &qi_lb60_pwm_beeper, | 435 | &qi_lb60_pwm_beeper, |
436 | &qi_lb60_charger_device, | ||
413 | }; | 437 | }; |
414 | 438 | ||
415 | static void __init board_gpio_setup(void) | 439 | static void __init board_gpio_setup(void) |
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 88e6aeda5bf1..bd2fc29b95e0 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c | |||
@@ -86,7 +86,6 @@ struct jz_gpio_chip { | |||
86 | spinlock_t lock; | 86 | spinlock_t lock; |
87 | 87 | ||
88 | struct gpio_chip gpio_chip; | 88 | struct gpio_chip gpio_chip; |
89 | struct irq_chip irq_chip; | ||
90 | struct sys_device sysdev; | 89 | struct sys_device sysdev; |
91 | }; | 90 | }; |
92 | 91 | ||
@@ -102,9 +101,9 @@ static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *g | |||
102 | return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip); | 101 | return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip); |
103 | } | 102 | } |
104 | 103 | ||
105 | static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq) | 104 | static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) |
106 | { | 105 | { |
107 | return get_irq_chip_data(irq); | 106 | return irq_data_get_irq_chip_data(data); |
108 | } | 107 | } |
109 | 108 | ||
110 | static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) | 109 | static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) |
@@ -325,62 +324,52 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
325 | generic_handle_irq(gpio_irq); | 324 | generic_handle_irq(gpio_irq); |
326 | }; | 325 | }; |
327 | 326 | ||
328 | static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg) | 327 | static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg) |
329 | { | 328 | { |
330 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | 329 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); |
331 | writel(IRQ_TO_BIT(irq), chip->base + reg); | 330 | writel(IRQ_TO_BIT(data->irq), chip->base + reg); |
332 | } | 331 | } |
333 | 332 | ||
334 | static void jz_gpio_irq_mask(unsigned int irq) | 333 | static void jz_gpio_irq_mask(struct irq_data *data) |
335 | { | 334 | { |
336 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET); | 335 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET); |
337 | }; | 336 | }; |
338 | 337 | ||
339 | static void jz_gpio_irq_unmask(unsigned int irq) | 338 | static void jz_gpio_irq_unmask(struct irq_data *data) |
340 | { | 339 | { |
341 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | 340 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); |
342 | 341 | ||
343 | jz_gpio_check_trigger_both(chip, irq); | 342 | jz_gpio_check_trigger_both(chip, data->irq); |
344 | 343 | ||
345 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR); | 344 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR); |
346 | }; | 345 | }; |
347 | 346 | ||
348 | /* TODO: Check if function is gpio */ | 347 | /* TODO: Check if function is gpio */ |
349 | static unsigned int jz_gpio_irq_startup(unsigned int irq) | 348 | static unsigned int jz_gpio_irq_startup(struct irq_data *data) |
350 | { | 349 | { |
351 | struct irq_desc *desc = irq_to_desc(irq); | 350 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET); |
352 | 351 | jz_gpio_irq_unmask(data); | |
353 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET); | ||
354 | |||
355 | desc->status &= ~IRQ_MASKED; | ||
356 | jz_gpio_irq_unmask(irq); | ||
357 | |||
358 | return 0; | 352 | return 0; |
359 | } | 353 | } |
360 | 354 | ||
361 | static void jz_gpio_irq_shutdown(unsigned int irq) | 355 | static void jz_gpio_irq_shutdown(struct irq_data *data) |
362 | { | 356 | { |
363 | struct irq_desc *desc = irq_to_desc(irq); | 357 | jz_gpio_irq_mask(data); |
364 | |||
365 | jz_gpio_irq_mask(irq); | ||
366 | desc->status |= IRQ_MASKED; | ||
367 | 358 | ||
368 | /* Set direction to input */ | 359 | /* Set direction to input */ |
369 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); | 360 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); |
370 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR); | 361 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR); |
371 | } | 362 | } |
372 | 363 | ||
373 | static void jz_gpio_irq_ack(unsigned int irq) | 364 | static void jz_gpio_irq_ack(struct irq_data *data) |
374 | { | 365 | { |
375 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR); | 366 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR); |
376 | }; | 367 | }; |
377 | 368 | ||
378 | static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) | 369 | static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) |
379 | { | 370 | { |
380 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | 371 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); |
381 | struct irq_desc *desc = irq_to_desc(irq); | 372 | unsigned int irq = data->irq; |
382 | |||
383 | jz_gpio_irq_mask(irq); | ||
384 | 373 | ||
385 | if (flow_type == IRQ_TYPE_EDGE_BOTH) { | 374 | if (flow_type == IRQ_TYPE_EDGE_BOTH) { |
386 | uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN); | 375 | uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN); |
@@ -395,45 +384,54 @@ static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) | |||
395 | 384 | ||
396 | switch (flow_type) { | 385 | switch (flow_type) { |
397 | case IRQ_TYPE_EDGE_RISING: | 386 | case IRQ_TYPE_EDGE_RISING: |
398 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET); | 387 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET); |
399 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET); | 388 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET); |
400 | break; | 389 | break; |
401 | case IRQ_TYPE_EDGE_FALLING: | 390 | case IRQ_TYPE_EDGE_FALLING: |
402 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); | 391 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); |
403 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET); | 392 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET); |
404 | break; | 393 | break; |
405 | case IRQ_TYPE_LEVEL_HIGH: | 394 | case IRQ_TYPE_LEVEL_HIGH: |
406 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET); | 395 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET); |
407 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR); | 396 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR); |
408 | break; | 397 | break; |
409 | case IRQ_TYPE_LEVEL_LOW: | 398 | case IRQ_TYPE_LEVEL_LOW: |
410 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); | 399 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); |
411 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR); | 400 | jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR); |
412 | break; | 401 | break; |
413 | default: | 402 | default: |
414 | return -EINVAL; | 403 | return -EINVAL; |
415 | } | 404 | } |
416 | 405 | ||
417 | if (!(desc->status & IRQ_MASKED)) | ||
418 | jz_gpio_irq_unmask(irq); | ||
419 | |||
420 | return 0; | 406 | return 0; |
421 | } | 407 | } |
422 | 408 | ||
423 | static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on) | 409 | static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) |
424 | { | 410 | { |
425 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | 411 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); |
426 | spin_lock(&chip->lock); | 412 | spin_lock(&chip->lock); |
427 | if (on) | 413 | if (on) |
428 | chip->wakeup |= IRQ_TO_BIT(irq); | 414 | chip->wakeup |= IRQ_TO_BIT(data->irq); |
429 | else | 415 | else |
430 | chip->wakeup &= ~IRQ_TO_BIT(irq); | 416 | chip->wakeup &= ~IRQ_TO_BIT(data->irq); |
431 | spin_unlock(&chip->lock); | 417 | spin_unlock(&chip->lock); |
432 | 418 | ||
433 | set_irq_wake(chip->irq, on); | 419 | set_irq_wake(chip->irq, on); |
434 | return 0; | 420 | return 0; |
435 | } | 421 | } |
436 | 422 | ||
423 | static struct irq_chip jz_gpio_irq_chip = { | ||
424 | .name = "GPIO", | ||
425 | .irq_mask = jz_gpio_irq_mask, | ||
426 | .irq_unmask = jz_gpio_irq_unmask, | ||
427 | .irq_ack = jz_gpio_irq_ack, | ||
428 | .irq_startup = jz_gpio_irq_startup, | ||
429 | .irq_shutdown = jz_gpio_irq_shutdown, | ||
430 | .irq_set_type = jz_gpio_irq_set_type, | ||
431 | .irq_set_wake = jz_gpio_irq_set_wake, | ||
432 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
433 | }; | ||
434 | |||
437 | /* | 435 | /* |
438 | * This lock class tells lockdep that GPIO irqs are in a different | 436 | * This lock class tells lockdep that GPIO irqs are in a different |
439 | * category than their parents, so it won't report false recursion. | 437 | * category than their parents, so it won't report false recursion. |
@@ -452,16 +450,6 @@ static struct lock_class_key gpio_lock_class; | |||
452 | .base = JZ4740_GPIO_BASE_ ## _bank, \ | 450 | .base = JZ4740_GPIO_BASE_ ## _bank, \ |
453 | .ngpio = JZ4740_GPIO_NUM_ ## _bank, \ | 451 | .ngpio = JZ4740_GPIO_NUM_ ## _bank, \ |
454 | }, \ | 452 | }, \ |
455 | .irq_chip = { \ | ||
456 | .name = "GPIO Bank " # _bank, \ | ||
457 | .mask = jz_gpio_irq_mask, \ | ||
458 | .unmask = jz_gpio_irq_unmask, \ | ||
459 | .ack = jz_gpio_irq_ack, \ | ||
460 | .startup = jz_gpio_irq_startup, \ | ||
461 | .shutdown = jz_gpio_irq_shutdown, \ | ||
462 | .set_type = jz_gpio_irq_set_type, \ | ||
463 | .set_wake = jz_gpio_irq_set_wake, \ | ||
464 | }, \ | ||
465 | } | 453 | } |
466 | 454 | ||
467 | static struct jz_gpio_chip jz4740_gpio_chips[] = { | 455 | static struct jz_gpio_chip jz4740_gpio_chips[] = { |
@@ -526,9 +514,10 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) | |||
526 | set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler); | 514 | set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler); |
527 | 515 | ||
528 | for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) { | 516 | for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) { |
529 | lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class); | 517 | irq_set_lockdep_class(irq, &gpio_lock_class); |
530 | set_irq_chip_data(irq, chip); | 518 | set_irq_chip_data(irq, chip); |
531 | set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq); | 519 | set_irq_chip_and_handler(irq, &jz_gpio_irq_chip, |
520 | handle_level_irq); | ||
532 | } | 521 | } |
533 | 522 | ||
534 | return 0; | 523 | return 0; |
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c index 7d33ff83580f..dcc5593a9389 100644 --- a/arch/mips/jz4740/irq.c +++ b/arch/mips/jz4740/irq.c | |||
@@ -43,32 +43,37 @@ static uint32_t jz_intc_saved; | |||
43 | 43 | ||
44 | #define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE) | 44 | #define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE) |
45 | 45 | ||
46 | static void intc_irq_unmask(unsigned int irq) | 46 | static inline unsigned long intc_irq_bit(struct irq_data *data) |
47 | { | 47 | { |
48 | writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK); | 48 | return (unsigned long)irq_data_get_irq_chip_data(data); |
49 | } | 49 | } |
50 | 50 | ||
51 | static void intc_irq_mask(unsigned int irq) | 51 | static void intc_irq_unmask(struct irq_data *data) |
52 | { | 52 | { |
53 | writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK); | 53 | writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK); |
54 | } | 54 | } |
55 | 55 | ||
56 | static int intc_irq_set_wake(unsigned int irq, unsigned int on) | 56 | static void intc_irq_mask(struct irq_data *data) |
57 | { | ||
58 | writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK); | ||
59 | } | ||
60 | |||
61 | static int intc_irq_set_wake(struct irq_data *data, unsigned int on) | ||
57 | { | 62 | { |
58 | if (on) | 63 | if (on) |
59 | jz_intc_wakeup |= IRQ_BIT(irq); | 64 | jz_intc_wakeup |= intc_irq_bit(data); |
60 | else | 65 | else |
61 | jz_intc_wakeup &= ~IRQ_BIT(irq); | 66 | jz_intc_wakeup &= ~intc_irq_bit(data); |
62 | 67 | ||
63 | return 0; | 68 | return 0; |
64 | } | 69 | } |
65 | 70 | ||
66 | static struct irq_chip intc_irq_type = { | 71 | static struct irq_chip intc_irq_type = { |
67 | .name = "INTC", | 72 | .name = "INTC", |
68 | .mask = intc_irq_mask, | 73 | .irq_mask = intc_irq_mask, |
69 | .mask_ack = intc_irq_mask, | 74 | .irq_mask_ack = intc_irq_mask, |
70 | .unmask = intc_irq_unmask, | 75 | .irq_unmask = intc_irq_unmask, |
71 | .set_wake = intc_irq_set_wake, | 76 | .irq_set_wake = intc_irq_set_wake, |
72 | }; | 77 | }; |
73 | 78 | ||
74 | static irqreturn_t jz4740_cascade(int irq, void *data) | 79 | static irqreturn_t jz4740_cascade(int irq, void *data) |
@@ -95,8 +100,11 @@ void __init arch_init_irq(void) | |||
95 | 100 | ||
96 | jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14); | 101 | jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14); |
97 | 102 | ||
103 | /* Mask all irqs */ | ||
104 | writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK); | ||
105 | |||
98 | for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) { | 106 | for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) { |
99 | intc_irq_mask(i); | 107 | set_irq_chip_data(i, (void *)IRQ_BIT(i)); |
100 | set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); | 108 | set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); |
101 | } | 109 | } |
102 | 110 | ||
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index c58176cc796b..e221662bb80c 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
@@ -31,19 +31,19 @@ | |||
31 | 31 | ||
32 | static int i8259A_auto_eoi = -1; | 32 | static int i8259A_auto_eoi = -1; |
33 | DEFINE_RAW_SPINLOCK(i8259A_lock); | 33 | DEFINE_RAW_SPINLOCK(i8259A_lock); |
34 | static void disable_8259A_irq(unsigned int irq); | 34 | static void disable_8259A_irq(struct irq_data *d); |
35 | static void enable_8259A_irq(unsigned int irq); | 35 | static void enable_8259A_irq(struct irq_data *d); |
36 | static void mask_and_ack_8259A(unsigned int irq); | 36 | static void mask_and_ack_8259A(struct irq_data *d); |
37 | static void init_8259A(int auto_eoi); | 37 | static void init_8259A(int auto_eoi); |
38 | 38 | ||
39 | static struct irq_chip i8259A_chip = { | 39 | static struct irq_chip i8259A_chip = { |
40 | .name = "XT-PIC", | 40 | .name = "XT-PIC", |
41 | .mask = disable_8259A_irq, | 41 | .irq_mask = disable_8259A_irq, |
42 | .disable = disable_8259A_irq, | 42 | .irq_disable = disable_8259A_irq, |
43 | .unmask = enable_8259A_irq, | 43 | .irq_unmask = enable_8259A_irq, |
44 | .mask_ack = mask_and_ack_8259A, | 44 | .irq_mask_ack = mask_and_ack_8259A, |
45 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF | 45 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF |
46 | .set_affinity = plat_set_irq_affinity, | 46 | .irq_set_affinity = plat_set_irq_affinity, |
47 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | 47 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ |
48 | }; | 48 | }; |
49 | 49 | ||
@@ -59,12 +59,11 @@ static unsigned int cached_irq_mask = 0xffff; | |||
59 | #define cached_master_mask (cached_irq_mask) | 59 | #define cached_master_mask (cached_irq_mask) |
60 | #define cached_slave_mask (cached_irq_mask >> 8) | 60 | #define cached_slave_mask (cached_irq_mask >> 8) |
61 | 61 | ||
62 | static void disable_8259A_irq(unsigned int irq) | 62 | static void disable_8259A_irq(struct irq_data *d) |
63 | { | 63 | { |
64 | unsigned int mask; | 64 | unsigned int mask, irq = d->irq - I8259A_IRQ_BASE; |
65 | unsigned long flags; | 65 | unsigned long flags; |
66 | 66 | ||
67 | irq -= I8259A_IRQ_BASE; | ||
68 | mask = 1 << irq; | 67 | mask = 1 << irq; |
69 | raw_spin_lock_irqsave(&i8259A_lock, flags); | 68 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
70 | cached_irq_mask |= mask; | 69 | cached_irq_mask |= mask; |
@@ -75,12 +74,11 @@ static void disable_8259A_irq(unsigned int irq) | |||
75 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); | 74 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
76 | } | 75 | } |
77 | 76 | ||
78 | static void enable_8259A_irq(unsigned int irq) | 77 | static void enable_8259A_irq(struct irq_data *d) |
79 | { | 78 | { |
80 | unsigned int mask; | 79 | unsigned int mask, irq = d->irq - I8259A_IRQ_BASE; |
81 | unsigned long flags; | 80 | unsigned long flags; |
82 | 81 | ||
83 | irq -= I8259A_IRQ_BASE; | ||
84 | mask = ~(1 << irq); | 82 | mask = ~(1 << irq); |
85 | raw_spin_lock_irqsave(&i8259A_lock, flags); | 83 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
86 | cached_irq_mask &= mask; | 84 | cached_irq_mask &= mask; |
@@ -145,12 +143,11 @@ static inline int i8259A_irq_real(unsigned int irq) | |||
145 | * first, _then_ send the EOI, and the order of EOI | 143 | * first, _then_ send the EOI, and the order of EOI |
146 | * to the two 8259s is important! | 144 | * to the two 8259s is important! |
147 | */ | 145 | */ |
148 | static void mask_and_ack_8259A(unsigned int irq) | 146 | static void mask_and_ack_8259A(struct irq_data *d) |
149 | { | 147 | { |
150 | unsigned int irqmask; | 148 | unsigned int irqmask, irq = d->irq - I8259A_IRQ_BASE; |
151 | unsigned long flags; | 149 | unsigned long flags; |
152 | 150 | ||
153 | irq -= I8259A_IRQ_BASE; | ||
154 | irqmask = 1 << irq; | 151 | irqmask = 1 << irq; |
155 | raw_spin_lock_irqsave(&i8259A_lock, flags); | 152 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
156 | /* | 153 | /* |
@@ -290,9 +287,9 @@ static void init_8259A(int auto_eoi) | |||
290 | * In AEOI mode we just have to mask the interrupt | 287 | * In AEOI mode we just have to mask the interrupt |
291 | * when acking. | 288 | * when acking. |
292 | */ | 289 | */ |
293 | i8259A_chip.mask_ack = disable_8259A_irq; | 290 | i8259A_chip.irq_mask_ack = disable_8259A_irq; |
294 | else | 291 | else |
295 | i8259A_chip.mask_ack = mask_and_ack_8259A; | 292 | i8259A_chip.irq_mask_ack = mask_and_ack_8259A; |
296 | 293 | ||
297 | udelay(100); /* wait for 8259A to initialize */ | 294 | udelay(100); /* wait for 8259A to initialize */ |
298 | 295 | ||
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 1774271af848..43cd9628251a 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
@@ -87,17 +87,10 @@ unsigned int gic_get_int(void) | |||
87 | return i; | 87 | return i; |
88 | } | 88 | } |
89 | 89 | ||
90 | static unsigned int gic_irq_startup(unsigned int irq) | 90 | static void gic_irq_ack(struct irq_data *d) |
91 | { | 91 | { |
92 | irq -= _irqbase; | 92 | unsigned int irq = d->irq - _irqbase; |
93 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | ||
94 | GIC_SET_INTR_MASK(irq); | ||
95 | return 0; | ||
96 | } | ||
97 | 93 | ||
98 | static void gic_irq_ack(unsigned int irq) | ||
99 | { | ||
100 | irq -= _irqbase; | ||
101 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 94 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
102 | GIC_CLR_INTR_MASK(irq); | 95 | GIC_CLR_INTR_MASK(irq); |
103 | 96 | ||
@@ -105,16 +98,16 @@ static void gic_irq_ack(unsigned int irq) | |||
105 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); | 98 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); |
106 | } | 99 | } |
107 | 100 | ||
108 | static void gic_mask_irq(unsigned int irq) | 101 | static void gic_mask_irq(struct irq_data *d) |
109 | { | 102 | { |
110 | irq -= _irqbase; | 103 | unsigned int irq = d->irq - _irqbase; |
111 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 104 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
112 | GIC_CLR_INTR_MASK(irq); | 105 | GIC_CLR_INTR_MASK(irq); |
113 | } | 106 | } |
114 | 107 | ||
115 | static void gic_unmask_irq(unsigned int irq) | 108 | static void gic_unmask_irq(struct irq_data *d) |
116 | { | 109 | { |
117 | irq -= _irqbase; | 110 | unsigned int irq = d->irq - _irqbase; |
118 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 111 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
119 | GIC_SET_INTR_MASK(irq); | 112 | GIC_SET_INTR_MASK(irq); |
120 | } | 113 | } |
@@ -123,13 +116,14 @@ static void gic_unmask_irq(unsigned int irq) | |||
123 | 116 | ||
124 | static DEFINE_SPINLOCK(gic_lock); | 117 | static DEFINE_SPINLOCK(gic_lock); |
125 | 118 | ||
126 | static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | 119 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, |
120 | bool force) | ||
127 | { | 121 | { |
122 | unsigned int irq = d->irq - _irqbase; | ||
128 | cpumask_t tmp = CPU_MASK_NONE; | 123 | cpumask_t tmp = CPU_MASK_NONE; |
129 | unsigned long flags; | 124 | unsigned long flags; |
130 | int i; | 125 | int i; |
131 | 126 | ||
132 | irq -= _irqbase; | ||
133 | pr_debug("%s(%d) called\n", __func__, irq); | 127 | pr_debug("%s(%d) called\n", __func__, irq); |
134 | cpumask_and(&tmp, cpumask, cpu_online_mask); | 128 | cpumask_and(&tmp, cpumask, cpu_online_mask); |
135 | if (cpus_empty(tmp)) | 129 | if (cpus_empty(tmp)) |
@@ -147,23 +141,22 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
147 | set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); | 141 | set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); |
148 | 142 | ||
149 | } | 143 | } |
150 | cpumask_copy(irq_desc[irq].affinity, cpumask); | 144 | cpumask_copy(d->affinity, cpumask); |
151 | spin_unlock_irqrestore(&gic_lock, flags); | 145 | spin_unlock_irqrestore(&gic_lock, flags); |
152 | 146 | ||
153 | return 0; | 147 | return IRQ_SET_MASK_OK_NOCOPY; |
154 | } | 148 | } |
155 | #endif | 149 | #endif |
156 | 150 | ||
157 | static struct irq_chip gic_irq_controller = { | 151 | static struct irq_chip gic_irq_controller = { |
158 | .name = "MIPS GIC", | 152 | .name = "MIPS GIC", |
159 | .startup = gic_irq_startup, | 153 | .irq_ack = gic_irq_ack, |
160 | .ack = gic_irq_ack, | 154 | .irq_mask = gic_mask_irq, |
161 | .mask = gic_mask_irq, | 155 | .irq_mask_ack = gic_mask_irq, |
162 | .mask_ack = gic_mask_irq, | 156 | .irq_unmask = gic_unmask_irq, |
163 | .unmask = gic_unmask_irq, | 157 | .irq_eoi = gic_unmask_irq, |
164 | .eoi = gic_unmask_irq, | ||
165 | #ifdef CONFIG_SMP | 158 | #ifdef CONFIG_SMP |
166 | .set_affinity = gic_set_affinity, | 159 | .irq_set_affinity = gic_set_affinity, |
167 | #endif | 160 | #endif |
168 | }; | 161 | }; |
169 | 162 | ||
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c index 42ef81461bfc..7fd176fa367a 100644 --- a/arch/mips/kernel/irq-gt641xx.c +++ b/arch/mips/kernel/irq-gt641xx.c | |||
@@ -29,64 +29,64 @@ | |||
29 | 29 | ||
30 | static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock); | 30 | static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock); |
31 | 31 | ||
32 | static void ack_gt641xx_irq(unsigned int irq) | 32 | static void ack_gt641xx_irq(struct irq_data *d) |
33 | { | 33 | { |
34 | unsigned long flags; | 34 | unsigned long flags; |
35 | u32 cause; | 35 | u32 cause; |
36 | 36 | ||
37 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | 37 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); |
38 | cause = GT_READ(GT_INTRCAUSE_OFS); | 38 | cause = GT_READ(GT_INTRCAUSE_OFS); |
39 | cause &= ~GT641XX_IRQ_TO_BIT(irq); | 39 | cause &= ~GT641XX_IRQ_TO_BIT(d->irq); |
40 | GT_WRITE(GT_INTRCAUSE_OFS, cause); | 40 | GT_WRITE(GT_INTRCAUSE_OFS, cause); |
41 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | 41 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); |
42 | } | 42 | } |
43 | 43 | ||
44 | static void mask_gt641xx_irq(unsigned int irq) | 44 | static void mask_gt641xx_irq(struct irq_data *d) |
45 | { | 45 | { |
46 | unsigned long flags; | 46 | unsigned long flags; |
47 | u32 mask; | 47 | u32 mask; |
48 | 48 | ||
49 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | 49 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); |
50 | mask = GT_READ(GT_INTRMASK_OFS); | 50 | mask = GT_READ(GT_INTRMASK_OFS); |
51 | mask &= ~GT641XX_IRQ_TO_BIT(irq); | 51 | mask &= ~GT641XX_IRQ_TO_BIT(d->irq); |
52 | GT_WRITE(GT_INTRMASK_OFS, mask); | 52 | GT_WRITE(GT_INTRMASK_OFS, mask); |
53 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | 53 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); |
54 | } | 54 | } |
55 | 55 | ||
56 | static void mask_ack_gt641xx_irq(unsigned int irq) | 56 | static void mask_ack_gt641xx_irq(struct irq_data *d) |
57 | { | 57 | { |
58 | unsigned long flags; | 58 | unsigned long flags; |
59 | u32 cause, mask; | 59 | u32 cause, mask; |
60 | 60 | ||
61 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | 61 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); |
62 | mask = GT_READ(GT_INTRMASK_OFS); | 62 | mask = GT_READ(GT_INTRMASK_OFS); |
63 | mask &= ~GT641XX_IRQ_TO_BIT(irq); | 63 | mask &= ~GT641XX_IRQ_TO_BIT(d->irq); |
64 | GT_WRITE(GT_INTRMASK_OFS, mask); | 64 | GT_WRITE(GT_INTRMASK_OFS, mask); |
65 | 65 | ||
66 | cause = GT_READ(GT_INTRCAUSE_OFS); | 66 | cause = GT_READ(GT_INTRCAUSE_OFS); |
67 | cause &= ~GT641XX_IRQ_TO_BIT(irq); | 67 | cause &= ~GT641XX_IRQ_TO_BIT(d->irq); |
68 | GT_WRITE(GT_INTRCAUSE_OFS, cause); | 68 | GT_WRITE(GT_INTRCAUSE_OFS, cause); |
69 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | 69 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); |
70 | } | 70 | } |
71 | 71 | ||
72 | static void unmask_gt641xx_irq(unsigned int irq) | 72 | static void unmask_gt641xx_irq(struct irq_data *d) |
73 | { | 73 | { |
74 | unsigned long flags; | 74 | unsigned long flags; |
75 | u32 mask; | 75 | u32 mask; |
76 | 76 | ||
77 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); | 77 | raw_spin_lock_irqsave(>641xx_irq_lock, flags); |
78 | mask = GT_READ(GT_INTRMASK_OFS); | 78 | mask = GT_READ(GT_INTRMASK_OFS); |
79 | mask |= GT641XX_IRQ_TO_BIT(irq); | 79 | mask |= GT641XX_IRQ_TO_BIT(d->irq); |
80 | GT_WRITE(GT_INTRMASK_OFS, mask); | 80 | GT_WRITE(GT_INTRMASK_OFS, mask); |
81 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); | 81 | raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); |
82 | } | 82 | } |
83 | 83 | ||
84 | static struct irq_chip gt641xx_irq_chip = { | 84 | static struct irq_chip gt641xx_irq_chip = { |
85 | .name = "GT641xx", | 85 | .name = "GT641xx", |
86 | .ack = ack_gt641xx_irq, | 86 | .irq_ack = ack_gt641xx_irq, |
87 | .mask = mask_gt641xx_irq, | 87 | .irq_mask = mask_gt641xx_irq, |
88 | .mask_ack = mask_ack_gt641xx_irq, | 88 | .irq_mask_ack = mask_ack_gt641xx_irq, |
89 | .unmask = unmask_gt641xx_irq, | 89 | .irq_unmask = unmask_gt641xx_irq, |
90 | }; | 90 | }; |
91 | 91 | ||
92 | void gt641xx_irq_dispatch(void) | 92 | void gt641xx_irq_dispatch(void) |
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 6a8cd28133d5..fc800cd9947e 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c | |||
@@ -28,8 +28,10 @@ static unsigned long _icctrl_msc; | |||
28 | static unsigned int irq_base; | 28 | static unsigned int irq_base; |
29 | 29 | ||
30 | /* mask off an interrupt */ | 30 | /* mask off an interrupt */ |
31 | static inline void mask_msc_irq(unsigned int irq) | 31 | static inline void mask_msc_irq(struct irq_data *d) |
32 | { | 32 | { |
33 | unsigned int irq = d->irq; | ||
34 | |||
33 | if (irq < (irq_base + 32)) | 35 | if (irq < (irq_base + 32)) |
34 | MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base)); | 36 | MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base)); |
35 | else | 37 | else |
@@ -37,8 +39,10 @@ static inline void mask_msc_irq(unsigned int irq) | |||
37 | } | 39 | } |
38 | 40 | ||
39 | /* unmask an interrupt */ | 41 | /* unmask an interrupt */ |
40 | static inline void unmask_msc_irq(unsigned int irq) | 42 | static inline void unmask_msc_irq(struct irq_data *d) |
41 | { | 43 | { |
44 | unsigned int irq = d->irq; | ||
45 | |||
42 | if (irq < (irq_base + 32)) | 46 | if (irq < (irq_base + 32)) |
43 | MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base)); | 47 | MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base)); |
44 | else | 48 | else |
@@ -48,9 +52,11 @@ static inline void unmask_msc_irq(unsigned int irq) | |||
48 | /* | 52 | /* |
49 | * Masks and ACKs an IRQ | 53 | * Masks and ACKs an IRQ |
50 | */ | 54 | */ |
51 | static void level_mask_and_ack_msc_irq(unsigned int irq) | 55 | static void level_mask_and_ack_msc_irq(struct irq_data *d) |
52 | { | 56 | { |
53 | mask_msc_irq(irq); | 57 | unsigned int irq = d->irq; |
58 | |||
59 | mask_msc_irq(d); | ||
54 | if (!cpu_has_veic) | 60 | if (!cpu_has_veic) |
55 | MSCIC_WRITE(MSC01_IC_EOI, 0); | 61 | MSCIC_WRITE(MSC01_IC_EOI, 0); |
56 | /* This actually needs to be a call into platform code */ | 62 | /* This actually needs to be a call into platform code */ |
@@ -60,9 +66,11 @@ static void level_mask_and_ack_msc_irq(unsigned int irq) | |||
60 | /* | 66 | /* |
61 | * Masks and ACKs an IRQ | 67 | * Masks and ACKs an IRQ |
62 | */ | 68 | */ |
63 | static void edge_mask_and_ack_msc_irq(unsigned int irq) | 69 | static void edge_mask_and_ack_msc_irq(struct irq_data *d) |
64 | { | 70 | { |
65 | mask_msc_irq(irq); | 71 | unsigned int irq = d->irq; |
72 | |||
73 | mask_msc_irq(d); | ||
66 | if (!cpu_has_veic) | 74 | if (!cpu_has_veic) |
67 | MSCIC_WRITE(MSC01_IC_EOI, 0); | 75 | MSCIC_WRITE(MSC01_IC_EOI, 0); |
68 | else { | 76 | else { |
@@ -75,15 +83,6 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq) | |||
75 | } | 83 | } |
76 | 84 | ||
77 | /* | 85 | /* |
78 | * End IRQ processing | ||
79 | */ | ||
80 | static void end_msc_irq(unsigned int irq) | ||
81 | { | ||
82 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
83 | unmask_msc_irq(irq); | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Interrupt handler for interrupts coming from SOC-it. | 86 | * Interrupt handler for interrupts coming from SOC-it. |
88 | */ | 87 | */ |
89 | void ll_msc_irq(void) | 88 | void ll_msc_irq(void) |
@@ -107,22 +106,20 @@ static void msc_bind_eic_interrupt(int irq, int set) | |||
107 | 106 | ||
108 | static struct irq_chip msc_levelirq_type = { | 107 | static struct irq_chip msc_levelirq_type = { |
109 | .name = "SOC-it-Level", | 108 | .name = "SOC-it-Level", |
110 | .ack = level_mask_and_ack_msc_irq, | 109 | .irq_ack = level_mask_and_ack_msc_irq, |
111 | .mask = mask_msc_irq, | 110 | .irq_mask = mask_msc_irq, |
112 | .mask_ack = level_mask_and_ack_msc_irq, | 111 | .irq_mask_ack = level_mask_and_ack_msc_irq, |
113 | .unmask = unmask_msc_irq, | 112 | .irq_unmask = unmask_msc_irq, |
114 | .eoi = unmask_msc_irq, | 113 | .irq_eoi = unmask_msc_irq, |
115 | .end = end_msc_irq, | ||
116 | }; | 114 | }; |
117 | 115 | ||
118 | static struct irq_chip msc_edgeirq_type = { | 116 | static struct irq_chip msc_edgeirq_type = { |
119 | .name = "SOC-it-Edge", | 117 | .name = "SOC-it-Edge", |
120 | .ack = edge_mask_and_ack_msc_irq, | 118 | .irq_ack = edge_mask_and_ack_msc_irq, |
121 | .mask = mask_msc_irq, | 119 | .irq_mask = mask_msc_irq, |
122 | .mask_ack = edge_mask_and_ack_msc_irq, | 120 | .irq_mask_ack = edge_mask_and_ack_msc_irq, |
123 | .unmask = unmask_msc_irq, | 121 | .irq_unmask = unmask_msc_irq, |
124 | .eoi = unmask_msc_irq, | 122 | .irq_eoi = unmask_msc_irq, |
125 | .end = end_msc_irq, | ||
126 | }; | 123 | }; |
127 | 124 | ||
128 | 125 | ||
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 9731e8b47862..fd24fd98b041 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c | |||
@@ -18,23 +18,23 @@ | |||
18 | #include <asm/mipsregs.h> | 18 | #include <asm/mipsregs.h> |
19 | #include <asm/system.h> | 19 | #include <asm/system.h> |
20 | 20 | ||
21 | static inline void unmask_rm7k_irq(unsigned int irq) | 21 | static inline void unmask_rm7k_irq(struct irq_data *d) |
22 | { | 22 | { |
23 | set_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE)); | 23 | set_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE)); |
24 | } | 24 | } |
25 | 25 | ||
26 | static inline void mask_rm7k_irq(unsigned int irq) | 26 | static inline void mask_rm7k_irq(struct irq_data *d) |
27 | { | 27 | { |
28 | clear_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE)); | 28 | clear_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE)); |
29 | } | 29 | } |
30 | 30 | ||
31 | static struct irq_chip rm7k_irq_controller = { | 31 | static struct irq_chip rm7k_irq_controller = { |
32 | .name = "RM7000", | 32 | .name = "RM7000", |
33 | .ack = mask_rm7k_irq, | 33 | .irq_ack = mask_rm7k_irq, |
34 | .mask = mask_rm7k_irq, | 34 | .irq_mask = mask_rm7k_irq, |
35 | .mask_ack = mask_rm7k_irq, | 35 | .irq_mask_ack = mask_rm7k_irq, |
36 | .unmask = unmask_rm7k_irq, | 36 | .irq_unmask = unmask_rm7k_irq, |
37 | .eoi = unmask_rm7k_irq | 37 | .irq_eoi = unmask_rm7k_irq |
38 | }; | 38 | }; |
39 | 39 | ||
40 | void __init rm7k_cpu_irq_init(void) | 40 | void __init rm7k_cpu_irq_init(void) |
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index b7e4025b58a8..ca463ec9bad5 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c | |||
@@ -19,22 +19,22 @@ | |||
19 | #include <asm/mipsregs.h> | 19 | #include <asm/mipsregs.h> |
20 | #include <asm/system.h> | 20 | #include <asm/system.h> |
21 | 21 | ||
22 | static inline void unmask_rm9k_irq(unsigned int irq) | 22 | static inline void unmask_rm9k_irq(struct irq_data *d) |
23 | { | 23 | { |
24 | set_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE)); | 24 | set_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE)); |
25 | } | 25 | } |
26 | 26 | ||
27 | static inline void mask_rm9k_irq(unsigned int irq) | 27 | static inline void mask_rm9k_irq(struct irq_data *d) |
28 | { | 28 | { |
29 | clear_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE)); | 29 | clear_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE)); |
30 | } | 30 | } |
31 | 31 | ||
32 | static inline void rm9k_cpu_irq_enable(unsigned int irq) | 32 | static inline void rm9k_cpu_irq_enable(struct irq_data *d) |
33 | { | 33 | { |
34 | unsigned long flags; | 34 | unsigned long flags; |
35 | 35 | ||
36 | local_irq_save(flags); | 36 | local_irq_save(flags); |
37 | unmask_rm9k_irq(irq); | 37 | unmask_rm9k_irq(d); |
38 | local_irq_restore(flags); | 38 | local_irq_restore(flags); |
39 | } | 39 | } |
40 | 40 | ||
@@ -43,50 +43,47 @@ static inline void rm9k_cpu_irq_enable(unsigned int irq) | |||
43 | */ | 43 | */ |
44 | static void local_rm9k_perfcounter_irq_startup(void *args) | 44 | static void local_rm9k_perfcounter_irq_startup(void *args) |
45 | { | 45 | { |
46 | unsigned int irq = (unsigned int) args; | 46 | rm9k_cpu_irq_enable(args); |
47 | |||
48 | rm9k_cpu_irq_enable(irq); | ||
49 | } | 47 | } |
50 | 48 | ||
51 | static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq) | 49 | static unsigned int rm9k_perfcounter_irq_startup(struct irq_data *d) |
52 | { | 50 | { |
53 | on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 1); | 51 | on_each_cpu(local_rm9k_perfcounter_irq_startup, d, 1); |
54 | 52 | ||
55 | return 0; | 53 | return 0; |
56 | } | 54 | } |
57 | 55 | ||
58 | static void local_rm9k_perfcounter_irq_shutdown(void *args) | 56 | static void local_rm9k_perfcounter_irq_shutdown(void *args) |
59 | { | 57 | { |
60 | unsigned int irq = (unsigned int) args; | ||
61 | unsigned long flags; | 58 | unsigned long flags; |
62 | 59 | ||
63 | local_irq_save(flags); | 60 | local_irq_save(flags); |
64 | mask_rm9k_irq(irq); | 61 | mask_rm9k_irq(args); |
65 | local_irq_restore(flags); | 62 | local_irq_restore(flags); |
66 | } | 63 | } |
67 | 64 | ||
68 | static void rm9k_perfcounter_irq_shutdown(unsigned int irq) | 65 | static void rm9k_perfcounter_irq_shutdown(struct irq_data *d) |
69 | { | 66 | { |
70 | on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 1); | 67 | on_each_cpu(local_rm9k_perfcounter_irq_shutdown, d, 1); |
71 | } | 68 | } |
72 | 69 | ||
73 | static struct irq_chip rm9k_irq_controller = { | 70 | static struct irq_chip rm9k_irq_controller = { |
74 | .name = "RM9000", | 71 | .name = "RM9000", |
75 | .ack = mask_rm9k_irq, | 72 | .irq_ack = mask_rm9k_irq, |
76 | .mask = mask_rm9k_irq, | 73 | .irq_mask = mask_rm9k_irq, |
77 | .mask_ack = mask_rm9k_irq, | 74 | .irq_mask_ack = mask_rm9k_irq, |
78 | .unmask = unmask_rm9k_irq, | 75 | .irq_unmask = unmask_rm9k_irq, |
79 | .eoi = unmask_rm9k_irq | 76 | .irq_eoi = unmask_rm9k_irq |
80 | }; | 77 | }; |
81 | 78 | ||
82 | static struct irq_chip rm9k_perfcounter_irq = { | 79 | static struct irq_chip rm9k_perfcounter_irq = { |
83 | .name = "RM9000", | 80 | .name = "RM9000", |
84 | .startup = rm9k_perfcounter_irq_startup, | 81 | .irq_startup = rm9k_perfcounter_irq_startup, |
85 | .shutdown = rm9k_perfcounter_irq_shutdown, | 82 | .irq_shutdown = rm9k_perfcounter_irq_shutdown, |
86 | .ack = mask_rm9k_irq, | 83 | .irq_ack = mask_rm9k_irq, |
87 | .mask = mask_rm9k_irq, | 84 | .irq_mask = mask_rm9k_irq, |
88 | .mask_ack = mask_rm9k_irq, | 85 | .irq_mask_ack = mask_rm9k_irq, |
89 | .unmask = unmask_rm9k_irq, | 86 | .irq_unmask = unmask_rm9k_irq, |
90 | }; | 87 | }; |
91 | 88 | ||
92 | unsigned int rm9000_perfcount_irq; | 89 | unsigned int rm9000_perfcount_irq; |
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 4f93db58a79e..1b68ebe1b458 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
@@ -81,48 +81,9 @@ void ack_bad_irq(unsigned int irq) | |||
81 | 81 | ||
82 | atomic_t irq_err_count; | 82 | atomic_t irq_err_count; |
83 | 83 | ||
84 | /* | 84 | int arch_show_interrupts(struct seq_file *p, int prec) |
85 | * Generic, controller-independent functions: | ||
86 | */ | ||
87 | |||
88 | int show_interrupts(struct seq_file *p, void *v) | ||
89 | { | 85 | { |
90 | int i = *(loff_t *) v, j; | 86 | seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); |
91 | struct irqaction * action; | ||
92 | unsigned long flags; | ||
93 | |||
94 | if (i == 0) { | ||
95 | seq_printf(p, " "); | ||
96 | for_each_online_cpu(j) | ||
97 | seq_printf(p, "CPU%d ", j); | ||
98 | seq_putc(p, '\n'); | ||
99 | } | ||
100 | |||
101 | if (i < NR_IRQS) { | ||
102 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
103 | action = irq_desc[i].action; | ||
104 | if (!action) | ||
105 | goto skip; | ||
106 | seq_printf(p, "%3d: ", i); | ||
107 | #ifndef CONFIG_SMP | ||
108 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
109 | #else | ||
110 | for_each_online_cpu(j) | ||
111 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | ||
112 | #endif | ||
113 | seq_printf(p, " %14s", irq_desc[i].chip->name); | ||
114 | seq_printf(p, " %s", action->name); | ||
115 | |||
116 | for (action=action->next; action; action = action->next) | ||
117 | seq_printf(p, ", %s", action->name); | ||
118 | |||
119 | seq_putc(p, '\n'); | ||
120 | skip: | ||
121 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
122 | } else if (i == NR_IRQS) { | ||
123 | seq_putc(p, '\n'); | ||
124 | seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); | ||
125 | } | ||
126 | return 0; | 87 | return 0; |
127 | } | 88 | } |
128 | 89 | ||
@@ -183,8 +144,8 @@ void __irq_entry do_IRQ(unsigned int irq) | |||
183 | { | 144 | { |
184 | irq_enter(); | 145 | irq_enter(); |
185 | check_stack_overflow(); | 146 | check_stack_overflow(); |
186 | __DO_IRQ_SMTC_HOOK(irq); | 147 | if (!smtc_handle_on_other_cpu(irq)) |
187 | generic_handle_irq(irq); | 148 | generic_handle_irq(irq); |
188 | irq_exit(); | 149 | irq_exit(); |
189 | } | 150 | } |
190 | 151 | ||
@@ -197,7 +158,7 @@ void __irq_entry do_IRQ(unsigned int irq) | |||
197 | void __irq_entry do_IRQ_no_affinity(unsigned int irq) | 158 | void __irq_entry do_IRQ_no_affinity(unsigned int irq) |
198 | { | 159 | { |
199 | irq_enter(); | 160 | irq_enter(); |
200 | __NO_AFFINITY_IRQ_SMTC_HOOK(irq); | 161 | smtc_im_backstop(irq); |
201 | generic_handle_irq(irq); | 162 | generic_handle_irq(irq); |
202 | irq_exit(); | 163 | irq_exit(); |
203 | } | 164 | } |
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 0262abe09121..fd945c56bc33 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c | |||
@@ -37,42 +37,38 @@ | |||
37 | #include <asm/mipsmtregs.h> | 37 | #include <asm/mipsmtregs.h> |
38 | #include <asm/system.h> | 38 | #include <asm/system.h> |
39 | 39 | ||
40 | static inline void unmask_mips_irq(unsigned int irq) | 40 | static inline void unmask_mips_irq(struct irq_data *d) |
41 | { | 41 | { |
42 | set_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE)); | 42 | set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); |
43 | irq_enable_hazard(); | 43 | irq_enable_hazard(); |
44 | } | 44 | } |
45 | 45 | ||
46 | static inline void mask_mips_irq(unsigned int irq) | 46 | static inline void mask_mips_irq(struct irq_data *d) |
47 | { | 47 | { |
48 | clear_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE)); | 48 | clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); |
49 | irq_disable_hazard(); | 49 | irq_disable_hazard(); |
50 | } | 50 | } |
51 | 51 | ||
52 | static struct irq_chip mips_cpu_irq_controller = { | 52 | static struct irq_chip mips_cpu_irq_controller = { |
53 | .name = "MIPS", | 53 | .name = "MIPS", |
54 | .ack = mask_mips_irq, | 54 | .irq_ack = mask_mips_irq, |
55 | .mask = mask_mips_irq, | 55 | .irq_mask = mask_mips_irq, |
56 | .mask_ack = mask_mips_irq, | 56 | .irq_mask_ack = mask_mips_irq, |
57 | .unmask = unmask_mips_irq, | 57 | .irq_unmask = unmask_mips_irq, |
58 | .eoi = unmask_mips_irq, | 58 | .irq_eoi = unmask_mips_irq, |
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * Basically the same as above but taking care of all the MT stuff | 62 | * Basically the same as above but taking care of all the MT stuff |
63 | */ | 63 | */ |
64 | 64 | ||
65 | #define unmask_mips_mt_irq unmask_mips_irq | 65 | static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d) |
66 | #define mask_mips_mt_irq mask_mips_irq | ||
67 | |||
68 | static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) | ||
69 | { | 66 | { |
70 | unsigned int vpflags = dvpe(); | 67 | unsigned int vpflags = dvpe(); |
71 | 68 | ||
72 | clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE)); | 69 | clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); |
73 | evpe(vpflags); | 70 | evpe(vpflags); |
74 | unmask_mips_mt_irq(irq); | 71 | unmask_mips_irq(d); |
75 | |||
76 | return 0; | 72 | return 0; |
77 | } | 73 | } |
78 | 74 | ||
@@ -80,22 +76,22 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) | |||
80 | * While we ack the interrupt interrupts are disabled and thus we don't need | 76 | * While we ack the interrupt interrupts are disabled and thus we don't need |
81 | * to deal with concurrency issues. Same for mips_cpu_irq_end. | 77 | * to deal with concurrency issues. Same for mips_cpu_irq_end. |
82 | */ | 78 | */ |
83 | static void mips_mt_cpu_irq_ack(unsigned int irq) | 79 | static void mips_mt_cpu_irq_ack(struct irq_data *d) |
84 | { | 80 | { |
85 | unsigned int vpflags = dvpe(); | 81 | unsigned int vpflags = dvpe(); |
86 | clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE)); | 82 | clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); |
87 | evpe(vpflags); | 83 | evpe(vpflags); |
88 | mask_mips_mt_irq(irq); | 84 | mask_mips_irq(d); |
89 | } | 85 | } |
90 | 86 | ||
91 | static struct irq_chip mips_mt_cpu_irq_controller = { | 87 | static struct irq_chip mips_mt_cpu_irq_controller = { |
92 | .name = "MIPS", | 88 | .name = "MIPS", |
93 | .startup = mips_mt_cpu_irq_startup, | 89 | .irq_startup = mips_mt_cpu_irq_startup, |
94 | .ack = mips_mt_cpu_irq_ack, | 90 | .irq_ack = mips_mt_cpu_irq_ack, |
95 | .mask = mask_mips_mt_irq, | 91 | .irq_mask = mask_mips_irq, |
96 | .mask_ack = mips_mt_cpu_irq_ack, | 92 | .irq_mask_ack = mips_mt_cpu_irq_ack, |
97 | .unmask = unmask_mips_mt_irq, | 93 | .irq_unmask = unmask_mips_irq, |
98 | .eoi = unmask_mips_mt_irq, | 94 | .irq_eoi = unmask_mips_irq, |
99 | }; | 95 | }; |
100 | 96 | ||
101 | void __init mips_cpu_irq_init(void) | 97 | void __init mips_cpu_irq_init(void) |
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c index 95a96f69172d..526e1581549a 100644 --- a/arch/mips/kernel/irq_txx9.c +++ b/arch/mips/kernel/irq_txx9.c | |||
@@ -63,9 +63,9 @@ static struct { | |||
63 | unsigned char mode; | 63 | unsigned char mode; |
64 | } txx9irq[TXx9_MAX_IR] __read_mostly; | 64 | } txx9irq[TXx9_MAX_IR] __read_mostly; |
65 | 65 | ||
66 | static void txx9_irq_unmask(unsigned int irq) | 66 | static void txx9_irq_unmask(struct irq_data *d) |
67 | { | 67 | { |
68 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 68 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
69 | u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2]; | 69 | u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2]; |
70 | int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8; | 70 | int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8; |
71 | 71 | ||
@@ -79,9 +79,9 @@ static void txx9_irq_unmask(unsigned int irq) | |||
79 | #endif | 79 | #endif |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void txx9_irq_mask(unsigned int irq) | 82 | static inline void txx9_irq_mask(struct irq_data *d) |
83 | { | 83 | { |
84 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 84 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
85 | u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2]; | 85 | u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2]; |
86 | int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8; | 86 | int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8; |
87 | 87 | ||
@@ -99,19 +99,19 @@ static inline void txx9_irq_mask(unsigned int irq) | |||
99 | #endif | 99 | #endif |
100 | } | 100 | } |
101 | 101 | ||
102 | static void txx9_irq_mask_ack(unsigned int irq) | 102 | static void txx9_irq_mask_ack(struct irq_data *d) |
103 | { | 103 | { |
104 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 104 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
105 | 105 | ||
106 | txx9_irq_mask(irq); | 106 | txx9_irq_mask(d); |
107 | /* clear edge detection */ | 107 | /* clear edge detection */ |
108 | if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode))) | 108 | if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode))) |
109 | __raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr); | 109 | __raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr); |
110 | } | 110 | } |
111 | 111 | ||
112 | static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type) | 112 | static int txx9_irq_set_type(struct irq_data *d, unsigned int flow_type) |
113 | { | 113 | { |
114 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 114 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
115 | u32 cr; | 115 | u32 cr; |
116 | u32 __iomem *crp; | 116 | u32 __iomem *crp; |
117 | int ofs; | 117 | int ofs; |
@@ -139,11 +139,11 @@ static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type) | |||
139 | 139 | ||
140 | static struct irq_chip txx9_irq_chip = { | 140 | static struct irq_chip txx9_irq_chip = { |
141 | .name = "TXX9", | 141 | .name = "TXX9", |
142 | .ack = txx9_irq_mask_ack, | 142 | .irq_ack = txx9_irq_mask_ack, |
143 | .mask = txx9_irq_mask, | 143 | .irq_mask = txx9_irq_mask, |
144 | .mask_ack = txx9_irq_mask_ack, | 144 | .irq_mask_ack = txx9_irq_mask_ack, |
145 | .unmask = txx9_irq_unmask, | 145 | .irq_unmask = txx9_irq_unmask, |
146 | .set_type = txx9_irq_set_type, | 146 | .irq_set_type = txx9_irq_set_type, |
147 | }; | 147 | }; |
148 | 148 | ||
149 | void __init txx9_irq_init(unsigned long baseaddr) | 149 | void __init txx9_irq_init(unsigned long baseaddr) |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index fbaabad0e6e2..7f5468b38d4c 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -586,6 +586,10 @@ einval: li v0, -ENOSYS | |||
586 | sys sys_fanotify_init 2 | 586 | sys sys_fanotify_init 2 |
587 | sys sys_fanotify_mark 6 | 587 | sys sys_fanotify_mark 6 |
588 | sys sys_prlimit64 4 | 588 | sys sys_prlimit64 4 |
589 | sys sys_name_to_handle_at 5 | ||
590 | sys sys_open_by_handle_at 3 /* 4340 */ | ||
591 | sys sys_clock_adjtime 2 | ||
592 | sys sys_syncfs 1 | ||
589 | .endm | 593 | .endm |
590 | 594 | ||
591 | /* We pre-compute the number of _instruction_ bytes needed to | 595 | /* 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 3f4179283207..a2e1fcbc41dc 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -425,4 +425,8 @@ sys_call_table: | |||
425 | PTR sys_fanotify_init /* 5295 */ | 425 | PTR sys_fanotify_init /* 5295 */ |
426 | PTR sys_fanotify_mark | 426 | PTR sys_fanotify_mark |
427 | PTR sys_prlimit64 | 427 | PTR sys_prlimit64 |
428 | PTR sys_name_to_handle_at | ||
429 | PTR sys_open_by_handle_at | ||
430 | PTR sys_clock_adjtime /* 5300 */ | ||
431 | PTR sys_syncfs | ||
428 | .size sys_call_table,.-sys_call_table | 432 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f08ece6d8acc..b2c7624995b8 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -425,4 +425,8 @@ EXPORT(sysn32_call_table) | |||
425 | PTR sys_fanotify_init /* 6300 */ | 425 | PTR sys_fanotify_init /* 6300 */ |
426 | PTR sys_fanotify_mark | 426 | PTR sys_fanotify_mark |
427 | PTR sys_prlimit64 | 427 | PTR sys_prlimit64 |
428 | PTR sys_name_to_handle_at | ||
429 | PTR sys_open_by_handle_at | ||
430 | PTR compat_sys_clock_adjtime /* 6305 */ | ||
431 | PTR sys_syncfs | ||
428 | .size sysn32_call_table,.-sysn32_call_table | 432 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 78d768a3e19d..049a9c8c49a0 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -543,4 +543,8 @@ sys_call_table: | |||
543 | PTR sys_fanotify_init | 543 | PTR sys_fanotify_init |
544 | PTR sys_32_fanotify_mark | 544 | PTR sys_32_fanotify_mark |
545 | PTR sys_prlimit64 | 545 | PTR sys_prlimit64 |
546 | PTR sys_name_to_handle_at | ||
547 | PTR compat_sys_open_by_handle_at /* 4340 */ | ||
548 | PTR compat_sys_clock_adjtime | ||
549 | PTR sys_syncfs | ||
546 | .size sys_call_table,.-sys_call_table | 550 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 39c08254b0f1..f7e2c7807d7b 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -677,8 +677,9 @@ void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity) | |||
677 | */ | 677 | */ |
678 | } | 678 | } |
679 | 679 | ||
680 | void smtc_forward_irq(unsigned int irq) | 680 | void smtc_forward_irq(struct irq_data *d) |
681 | { | 681 | { |
682 | unsigned int irq = d->irq; | ||
682 | int target; | 683 | int target; |
683 | 684 | ||
684 | /* | 685 | /* |
@@ -692,7 +693,7 @@ void smtc_forward_irq(unsigned int irq) | |||
692 | * and efficiency, we just pick the easiest one to find. | 693 | * and efficiency, we just pick the easiest one to find. |
693 | */ | 694 | */ |
694 | 695 | ||
695 | target = cpumask_first(irq_desc[irq].affinity); | 696 | target = cpumask_first(d->affinity); |
696 | 697 | ||
697 | /* | 698 | /* |
698 | * We depend on the platform code to have correctly processed | 699 | * We depend on the platform code to have correctly processed |
@@ -707,12 +708,10 @@ void smtc_forward_irq(unsigned int irq) | |||
707 | */ | 708 | */ |
708 | 709 | ||
709 | /* If no one is eligible, service locally */ | 710 | /* If no one is eligible, service locally */ |
710 | if (target >= NR_CPUS) { | 711 | if (target >= NR_CPUS) |
711 | do_IRQ_no_affinity(irq); | 712 | do_IRQ_no_affinity(irq); |
712 | return; | 713 | else |
713 | } | 714 | smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq); |
714 | |||
715 | smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq); | ||
716 | } | 715 | } |
717 | 716 | ||
718 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | 717 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ |
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 1353fb135ed3..670e3e70d198 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c | |||
@@ -32,24 +32,24 @@ static volatile int *lasat_int_status; | |||
32 | static volatile int *lasat_int_mask; | 32 | static volatile int *lasat_int_mask; |
33 | static volatile int lasat_int_mask_shift; | 33 | static volatile int lasat_int_mask_shift; |
34 | 34 | ||
35 | void disable_lasat_irq(unsigned int irq_nr) | 35 | void disable_lasat_irq(struct irq_data *d) |
36 | { | 36 | { |
37 | irq_nr -= LASAT_IRQ_BASE; | 37 | unsigned int irq_nr = d->irq - LASAT_IRQ_BASE; |
38 | |||
38 | *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; | 39 | *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; |
39 | } | 40 | } |
40 | 41 | ||
41 | void enable_lasat_irq(unsigned int irq_nr) | 42 | void enable_lasat_irq(struct irq_data *d) |
42 | { | 43 | { |
43 | irq_nr -= LASAT_IRQ_BASE; | 44 | unsigned int irq_nr = d->irq - LASAT_IRQ_BASE; |
45 | |||
44 | *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; | 46 | *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; |
45 | } | 47 | } |
46 | 48 | ||
47 | static struct irq_chip lasat_irq_type = { | 49 | static struct irq_chip lasat_irq_type = { |
48 | .name = "Lasat", | 50 | .name = "Lasat", |
49 | .ack = disable_lasat_irq, | 51 | .irq_mask = disable_lasat_irq, |
50 | .mask = disable_lasat_irq, | 52 | .irq_unmask = enable_lasat_irq, |
51 | .mask_ack = disable_lasat_irq, | ||
52 | .unmask = enable_lasat_irq, | ||
53 | }; | 53 | }; |
54 | 54 | ||
55 | static inline int ls1bit32(unsigned int x) | 55 | static inline int ls1bit32(unsigned int x) |
diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index 2dc2a4cc632a..1549361696ad 100644 --- a/arch/mips/loongson/common/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c | |||
@@ -16,24 +16,22 @@ | |||
16 | 16 | ||
17 | #include <loongson.h> | 17 | #include <loongson.h> |
18 | 18 | ||
19 | static inline void bonito_irq_enable(unsigned int irq) | 19 | static inline void bonito_irq_enable(struct irq_data *d) |
20 | { | 20 | { |
21 | LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE)); | 21 | LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE)); |
22 | mmiowb(); | 22 | mmiowb(); |
23 | } | 23 | } |
24 | 24 | ||
25 | static inline void bonito_irq_disable(unsigned int irq) | 25 | static inline void bonito_irq_disable(struct irq_data *d) |
26 | { | 26 | { |
27 | LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE)); | 27 | LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE)); |
28 | mmiowb(); | 28 | mmiowb(); |
29 | } | 29 | } |
30 | 30 | ||
31 | static struct irq_chip bonito_irq_type = { | 31 | static struct irq_chip bonito_irq_type = { |
32 | .name = "bonito_irq", | 32 | .name = "bonito_irq", |
33 | .ack = bonito_irq_disable, | 33 | .irq_mask = bonito_irq_disable, |
34 | .mask = bonito_irq_disable, | 34 | .irq_unmask = bonito_irq_enable, |
35 | .mask_ack = bonito_irq_disable, | ||
36 | .unmask = bonito_irq_enable, | ||
37 | }; | 35 | }; |
38 | 36 | ||
39 | static struct irqaction __maybe_unused dma_timeout_irqaction = { | 37 | static struct irqaction __maybe_unused dma_timeout_irqaction = { |
diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c index 5da30b6a65b7..30df47258c2c 100644 --- a/arch/mips/mipssim/sim_smtc.c +++ b/arch/mips/mipssim/sim_smtc.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/atomic.h> | 27 | #include <asm/atomic.h> |
28 | #include <asm/cpu.h> | 28 | #include <asm/cpu.h> |
29 | #include <asm/processor.h> | 29 | #include <asm/processor.h> |
30 | #include <asm/smtc.h> | ||
30 | #include <asm/system.h> | 31 | #include <asm/system.h> |
31 | #include <asm/mmu_context.h> | 32 | #include <asm/mmu_context.h> |
32 | #include <asm/smtc_ipi.h> | 33 | #include <asm/smtc_ipi.h> |
@@ -57,8 +58,6 @@ static inline void ssmtc_send_ipi_mask(const struct cpumask *mask, | |||
57 | */ | 58 | */ |
58 | static void __cpuinit ssmtc_init_secondary(void) | 59 | static void __cpuinit ssmtc_init_secondary(void) |
59 | { | 60 | { |
60 | void smtc_init_secondary(void); | ||
61 | |||
62 | smtc_init_secondary(); | 61 | smtc_init_secondary(); |
63 | } | 62 | } |
64 | 63 | ||
diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c index 192cfd2a539c..e67891521ac1 100644 --- a/arch/mips/mti-malta/malta-smtc.c +++ b/arch/mips/mti-malta/malta-smtc.c | |||
@@ -34,7 +34,6 @@ static void msmtc_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
34 | */ | 34 | */ |
35 | static void __cpuinit msmtc_init_secondary(void) | 35 | static void __cpuinit msmtc_init_secondary(void) |
36 | { | 36 | { |
37 | void smtc_init_secondary(void); | ||
38 | int myvpe; | 37 | int myvpe; |
39 | 38 | ||
40 | /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ | 39 | /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ |
@@ -114,7 +113,8 @@ struct plat_smp_ops msmtc_smp_ops = { | |||
114 | */ | 113 | */ |
115 | 114 | ||
116 | 115 | ||
117 | int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) | 116 | int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, |
117 | bool force) | ||
118 | { | 118 | { |
119 | cpumask_t tmask; | 119 | cpumask_t tmask; |
120 | int cpu = 0; | 120 | int cpu = 0; |
@@ -144,7 +144,7 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) | |||
144 | if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu)) | 144 | if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu)) |
145 | cpu_clear(cpu, tmask); | 145 | cpu_clear(cpu, tmask); |
146 | } | 146 | } |
147 | cpumask_copy(irq_desc[irq].affinity, &tmask); | 147 | cpumask_copy(d->affinity, &tmask); |
148 | 148 | ||
149 | if (cpus_empty(tmask)) | 149 | if (cpus_empty(tmask)) |
150 | /* | 150 | /* |
@@ -155,8 +155,8 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) | |||
155 | "IRQ affinity leaves no legal CPU for IRQ %d\n", irq); | 155 | "IRQ affinity leaves no legal CPU for IRQ %d\n", irq); |
156 | 156 | ||
157 | /* Do any generic SMTC IRQ affinity setup */ | 157 | /* Do any generic SMTC IRQ affinity setup */ |
158 | smtc_set_irq_affinity(irq, tmask); | 158 | smtc_set_irq_affinity(d->irq, tmask); |
159 | 159 | ||
160 | return 0; | 160 | return IRQ_SET_MASK_OK_NOCOPY; |
161 | } | 161 | } |
162 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | 162 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ |
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig index 8d798497c614..bbd76082fa8c 100644 --- a/arch/mips/pmc-sierra/Kconfig +++ b/arch/mips/pmc-sierra/Kconfig | |||
@@ -23,6 +23,8 @@ config PMC_MSP7120_GW | |||
23 | select SYS_SUPPORTS_MULTITHREADING | 23 | select SYS_SUPPORTS_MULTITHREADING |
24 | select IRQ_MSP_CIC | 24 | select IRQ_MSP_CIC |
25 | select HW_HAS_PCI | 25 | select HW_HAS_PCI |
26 | select MSP_HAS_USB | ||
27 | select MSP_ETH | ||
26 | 28 | ||
27 | config PMC_MSP7120_FPGA | 29 | config PMC_MSP7120_FPGA |
28 | bool "PMC-Sierra MSP7120 FPGA" | 30 | bool "PMC-Sierra MSP7120 FPGA" |
@@ -35,3 +37,16 @@ endchoice | |||
35 | config HYPERTRANSPORT | 37 | config HYPERTRANSPORT |
36 | bool "Hypertransport Support for PMC-Sierra Yosemite" | 38 | bool "Hypertransport Support for PMC-Sierra Yosemite" |
37 | depends on PMC_YOSEMITE | 39 | depends on PMC_YOSEMITE |
40 | |||
41 | config MSP_HAS_USB | ||
42 | boolean | ||
43 | depends on PMC_MSP | ||
44 | |||
45 | config MSP_ETH | ||
46 | boolean | ||
47 | select MSP_HAS_MAC | ||
48 | depends on PMC_MSP | ||
49 | |||
50 | config MSP_HAS_MAC | ||
51 | boolean | ||
52 | depends on PMC_MSP | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile index e107f79b1491..cefba7733b73 100644 --- a/arch/mips/pmc-sierra/msp71xx/Makefile +++ b/arch/mips/pmc-sierra/msp71xx/Makefile | |||
@@ -6,7 +6,9 @@ obj-y += msp_prom.o msp_setup.o msp_irq.o \ | |||
6 | obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o | 6 | obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o |
7 | obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o | 7 | obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o |
8 | obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o | 8 | obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o |
9 | obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o | 9 | obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o |
10 | obj-$(CONFIG_PCI) += msp_pci.o | 10 | obj-$(CONFIG_PCI) += msp_pci.o |
11 | obj-$(CONFIG_MSPETH) += msp_eth.o | 11 | obj-$(CONFIG_MSP_HAS_MAC) += msp_eth.o |
12 | obj-$(CONFIG_USB_MSP71XX) += msp_usb.o | 12 | obj-$(CONFIG_MSP_HAS_USB) += msp_usb.o |
13 | obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o | ||
14 | obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_eth.c b/arch/mips/pmc-sierra/msp71xx/msp_eth.c new file mode 100644 index 000000000000..c584df393de2 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_eth.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * The setup file for ethernet related hardware on PMC-Sierra MSP processors. | ||
3 | * | ||
4 | * Copyright 2010 PMC-Sierra, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
12 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
13 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
14 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
15 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
16 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
17 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
18 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
19 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
20 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License along | ||
23 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
24 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #include <linux/init.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <msp_regs.h> | ||
33 | #include <msp_int.h> | ||
34 | #include <msp_gpio_macros.h> | ||
35 | |||
36 | |||
37 | #define MSP_ETHERNET_GPIO0 14 | ||
38 | #define MSP_ETHERNET_GPIO1 15 | ||
39 | #define MSP_ETHERNET_GPIO2 16 | ||
40 | |||
41 | #ifdef CONFIG_MSP_HAS_TSMAC | ||
42 | #define MSP_TSMAC_SIZE 0x10020 | ||
43 | #define MSP_TSMAC_ID "pmc_tsmac" | ||
44 | |||
45 | static struct resource msp_tsmac0_resources[] = { | ||
46 | [0] = { | ||
47 | .start = MSP_MAC0_BASE, | ||
48 | .end = MSP_MAC0_BASE + MSP_TSMAC_SIZE - 1, | ||
49 | .flags = IORESOURCE_MEM, | ||
50 | }, | ||
51 | [1] = { | ||
52 | .start = MSP_INT_MAC0, | ||
53 | .end = MSP_INT_MAC0, | ||
54 | .flags = IORESOURCE_IRQ, | ||
55 | }, | ||
56 | }; | ||
57 | |||
58 | static struct resource msp_tsmac1_resources[] = { | ||
59 | [0] = { | ||
60 | .start = MSP_MAC1_BASE, | ||
61 | .end = MSP_MAC1_BASE + MSP_TSMAC_SIZE - 1, | ||
62 | .flags = IORESOURCE_MEM, | ||
63 | }, | ||
64 | [1] = { | ||
65 | .start = MSP_INT_MAC1, | ||
66 | .end = MSP_INT_MAC1, | ||
67 | .flags = IORESOURCE_IRQ, | ||
68 | }, | ||
69 | }; | ||
70 | static struct resource msp_tsmac2_resources[] = { | ||
71 | [0] = { | ||
72 | .start = MSP_MAC2_BASE, | ||
73 | .end = MSP_MAC2_BASE + MSP_TSMAC_SIZE - 1, | ||
74 | .flags = IORESOURCE_MEM, | ||
75 | }, | ||
76 | [1] = { | ||
77 | .start = MSP_INT_SAR, | ||
78 | .end = MSP_INT_SAR, | ||
79 | .flags = IORESOURCE_IRQ, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | |||
84 | static struct platform_device tsmac_device[] = { | ||
85 | [0] = { | ||
86 | .name = MSP_TSMAC_ID, | ||
87 | .id = 0, | ||
88 | .num_resources = ARRAY_SIZE(msp_tsmac0_resources), | ||
89 | .resource = msp_tsmac0_resources, | ||
90 | }, | ||
91 | [1] = { | ||
92 | .name = MSP_TSMAC_ID, | ||
93 | .id = 1, | ||
94 | .num_resources = ARRAY_SIZE(msp_tsmac1_resources), | ||
95 | .resource = msp_tsmac1_resources, | ||
96 | }, | ||
97 | [2] = { | ||
98 | .name = MSP_TSMAC_ID, | ||
99 | .id = 2, | ||
100 | .num_resources = ARRAY_SIZE(msp_tsmac2_resources), | ||
101 | .resource = msp_tsmac2_resources, | ||
102 | }, | ||
103 | }; | ||
104 | #define msp_eth_devs tsmac_device | ||
105 | |||
106 | #else | ||
107 | /* If it is not TSMAC assume MSP_ETH (100Mbps) */ | ||
108 | #define MSP_ETH_ID "pmc_mspeth" | ||
109 | #define MSP_ETH_SIZE 0xE0 | ||
110 | static struct resource msp_eth0_resources[] = { | ||
111 | [0] = { | ||
112 | .start = MSP_MAC0_BASE, | ||
113 | .end = MSP_MAC0_BASE + MSP_ETH_SIZE - 1, | ||
114 | .flags = IORESOURCE_MEM, | ||
115 | }, | ||
116 | [1] = { | ||
117 | .start = MSP_INT_MAC0, | ||
118 | .end = MSP_INT_MAC0, | ||
119 | .flags = IORESOURCE_IRQ, | ||
120 | }, | ||
121 | }; | ||
122 | |||
123 | static struct resource msp_eth1_resources[] = { | ||
124 | [0] = { | ||
125 | .start = MSP_MAC1_BASE, | ||
126 | .end = MSP_MAC1_BASE + MSP_ETH_SIZE - 1, | ||
127 | .flags = IORESOURCE_MEM, | ||
128 | }, | ||
129 | [1] = { | ||
130 | .start = MSP_INT_MAC1, | ||
131 | .end = MSP_INT_MAC1, | ||
132 | .flags = IORESOURCE_IRQ, | ||
133 | }, | ||
134 | }; | ||
135 | |||
136 | |||
137 | |||
138 | static struct platform_device mspeth_device[] = { | ||
139 | [0] = { | ||
140 | .name = MSP_ETH_ID, | ||
141 | .id = 0, | ||
142 | .num_resources = ARRAY_SIZE(msp_eth0_resources), | ||
143 | .resource = msp_eth0_resources, | ||
144 | }, | ||
145 | [1] = { | ||
146 | .name = MSP_ETH_ID, | ||
147 | .id = 1, | ||
148 | .num_resources = ARRAY_SIZE(msp_eth1_resources), | ||
149 | .resource = msp_eth1_resources, | ||
150 | }, | ||
151 | |||
152 | }; | ||
153 | #define msp_eth_devs mspeth_device | ||
154 | |||
155 | #endif | ||
156 | int __init msp_eth_setup(void) | ||
157 | { | ||
158 | int i, ret = 0; | ||
159 | |||
160 | /* Configure the GPIO and take the ethernet PHY out of reset */ | ||
161 | msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO0); | ||
162 | msp_gpio_pin_hi(MSP_ETHERNET_GPIO0); | ||
163 | |||
164 | #ifdef CONFIG_MSP_HAS_TSMAC | ||
165 | /* 3 phys on boards with TSMAC */ | ||
166 | msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO1); | ||
167 | msp_gpio_pin_hi(MSP_ETHERNET_GPIO1); | ||
168 | |||
169 | msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO2); | ||
170 | msp_gpio_pin_hi(MSP_ETHERNET_GPIO2); | ||
171 | #endif | ||
172 | for (i = 0; i < ARRAY_SIZE(msp_eth_devs); i++) { | ||
173 | ret = platform_device_register(&msp_eth_devs[i]); | ||
174 | printk(KERN_INFO "device: %d, return value = %d\n", i, ret); | ||
175 | if (ret) { | ||
176 | platform_device_unregister(&msp_eth_devs[i]); | ||
177 | break; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | if (ret) | ||
182 | printk(KERN_WARNING "Could not initialize " | ||
183 | "MSPETH device structures.\n"); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | subsys_initcall(msp_eth_setup); | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c index 734d598a2e3a..4531c4a514bc 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c | |||
@@ -19,8 +19,6 @@ | |||
19 | 19 | ||
20 | #include <msp_int.h> | 20 | #include <msp_int.h> |
21 | 21 | ||
22 | extern void msp_int_handle(void); | ||
23 | |||
24 | /* SLP bases systems */ | 22 | /* SLP bases systems */ |
25 | extern void msp_slp_irq_init(void); | 23 | extern void msp_slp_irq_init(void); |
26 | extern void msp_slp_irq_dispatch(void); | 24 | extern void msp_slp_irq_dispatch(void); |
@@ -29,6 +27,18 @@ extern void msp_slp_irq_dispatch(void); | |||
29 | extern void msp_cic_irq_init(void); | 27 | extern void msp_cic_irq_init(void); |
30 | extern void msp_cic_irq_dispatch(void); | 28 | extern void msp_cic_irq_dispatch(void); |
31 | 29 | ||
30 | /* VSMP support init */ | ||
31 | extern void msp_vsmp_int_init(void); | ||
32 | |||
33 | /* vectored interrupt implementation */ | ||
34 | |||
35 | /* SW0/1 interrupts are used for SMP/SMTC */ | ||
36 | static inline void mac0_int_dispatch(void) { do_IRQ(MSP_INT_MAC0); } | ||
37 | static inline void mac1_int_dispatch(void) { do_IRQ(MSP_INT_MAC1); } | ||
38 | static inline void mac2_int_dispatch(void) { do_IRQ(MSP_INT_SAR); } | ||
39 | static inline void usb_int_dispatch(void) { do_IRQ(MSP_INT_USB); } | ||
40 | static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); } | ||
41 | |||
32 | /* | 42 | /* |
33 | * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded | 43 | * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded |
34 | * hierarchical system. The first level are the direct MIPS interrupts | 44 | * hierarchical system. The first level are the direct MIPS interrupts |
@@ -96,29 +106,57 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | |||
96 | do_IRQ(MSP_INT_SW1); | 106 | do_IRQ(MSP_INT_SW1); |
97 | } | 107 | } |
98 | 108 | ||
99 | static struct irqaction cascade_msp = { | 109 | static struct irqaction cic_cascade_msp = { |
100 | .handler = no_action, | 110 | .handler = no_action, |
101 | .name = "MSP cascade" | 111 | .name = "MSP CIC cascade" |
102 | }; | 112 | }; |
103 | 113 | ||
114 | static struct irqaction per_cascade_msp = { | ||
115 | .handler = no_action, | ||
116 | .name = "MSP PER cascade" | ||
117 | }; | ||
104 | 118 | ||
105 | void __init arch_init_irq(void) | 119 | void __init arch_init_irq(void) |
106 | { | 120 | { |
121 | /* assume we'll be using vectored interrupt mode except in UP mode*/ | ||
122 | #ifdef CONFIG_MIPS_MT | ||
123 | BUG_ON(!cpu_has_vint); | ||
124 | #endif | ||
107 | /* initialize the 1st-level CPU based interrupt controller */ | 125 | /* initialize the 1st-level CPU based interrupt controller */ |
108 | mips_cpu_irq_init(); | 126 | mips_cpu_irq_init(); |
109 | 127 | ||
110 | #ifdef CONFIG_IRQ_MSP_CIC | 128 | #ifdef CONFIG_IRQ_MSP_CIC |
111 | msp_cic_irq_init(); | 129 | msp_cic_irq_init(); |
112 | 130 | #ifdef CONFIG_MIPS_MT | |
131 | set_vi_handler(MSP_INT_CIC, msp_cic_irq_dispatch); | ||
132 | set_vi_handler(MSP_INT_MAC0, mac0_int_dispatch); | ||
133 | set_vi_handler(MSP_INT_MAC1, mac1_int_dispatch); | ||
134 | set_vi_handler(MSP_INT_SAR, mac2_int_dispatch); | ||
135 | set_vi_handler(MSP_INT_USB, usb_int_dispatch); | ||
136 | set_vi_handler(MSP_INT_SEC, sec_int_dispatch); | ||
137 | #ifdef CONFIG_MIPS_MT_SMP | ||
138 | msp_vsmp_int_init(); | ||
139 | #elif defined CONFIG_MIPS_MT_SMTC | ||
140 | /*Set hwmask for all platform devices */ | ||
141 | irq_hwmask[MSP_INT_MAC0] = C_IRQ0; | ||
142 | irq_hwmask[MSP_INT_MAC1] = C_IRQ1; | ||
143 | irq_hwmask[MSP_INT_USB] = C_IRQ2; | ||
144 | irq_hwmask[MSP_INT_SAR] = C_IRQ3; | ||
145 | irq_hwmask[MSP_INT_SEC] = C_IRQ5; | ||
146 | |||
147 | #endif /* CONFIG_MIPS_MT_SMP */ | ||
148 | #endif /* CONFIG_MIPS_MT */ | ||
113 | /* setup the cascaded interrupts */ | 149 | /* setup the cascaded interrupts */ |
114 | setup_irq(MSP_INT_CIC, &cascade_msp); | 150 | setup_irq(MSP_INT_CIC, &cic_cascade_msp); |
115 | setup_irq(MSP_INT_PER, &cascade_msp); | 151 | setup_irq(MSP_INT_PER, &per_cascade_msp); |
152 | |||
116 | #else | 153 | #else |
117 | /* setup the 2nd-level SLP register based interrupt controller */ | 154 | /* setup the 2nd-level SLP register based interrupt controller */ |
155 | /* VSMP /SMTC support support is not enabled for SLP */ | ||
118 | msp_slp_irq_init(); | 156 | msp_slp_irq_init(); |
119 | 157 | ||
120 | /* setup the cascaded SLP/PER interrupts */ | 158 | /* setup the cascaded SLP/PER interrupts */ |
121 | setup_irq(MSP_INT_SLP, &cascade_msp); | 159 | setup_irq(MSP_INT_SLP, &cic_cascade_msp); |
122 | setup_irq(MSP_INT_PER, &cascade_msp); | 160 | setup_irq(MSP_INT_PER, &per_cascade_msp); |
123 | #endif | 161 | #endif |
124 | } | 162 | } |
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c index 07e71ff2433f..352f29d9226f 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c | |||
@@ -1,8 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * This file define the irq handler for MSP SLM subsystem interrupts. | 2 | * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c |
3 | * | 3 | * |
4 | * Copyright 2005-2007 PMC-Sierra, Inc, derived from irq_cpu.c | 4 | * This file define the irq handler for MSP CIC subsystem interrupts. |
5 | * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com | ||
6 | * | 5 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -16,119 +15,203 @@ | |||
16 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
17 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
18 | 17 | ||
18 | #include <asm/mipsregs.h> | ||
19 | #include <asm/system.h> | 19 | #include <asm/system.h> |
20 | 20 | ||
21 | #include <msp_cic_int.h> | 21 | #include <msp_cic_int.h> |
22 | #include <msp_regs.h> | 22 | #include <msp_regs.h> |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * NOTE: We are only enabling support for VPE0 right now. | 25 | * External API |
26 | */ | 26 | */ |
27 | extern void msp_per_irq_init(void); | ||
28 | extern void msp_per_irq_dispatch(void); | ||
27 | 29 | ||
28 | static inline void unmask_msp_cic_irq(unsigned int irq) | 30 | |
31 | /* | ||
32 | * Convenience Macro. Should be somewhere generic. | ||
33 | */ | ||
34 | #define get_current_vpe() \ | ||
35 | ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE) | ||
36 | |||
37 | #ifdef CONFIG_SMP | ||
38 | |||
39 | #define LOCK_VPE(flags, mtflags) \ | ||
40 | do { \ | ||
41 | local_irq_save(flags); \ | ||
42 | mtflags = dmt(); \ | ||
43 | } while (0) | ||
44 | |||
45 | #define UNLOCK_VPE(flags, mtflags) \ | ||
46 | do { \ | ||
47 | emt(mtflags); \ | ||
48 | local_irq_restore(flags);\ | ||
49 | } while (0) | ||
50 | |||
51 | #define LOCK_CORE(flags, mtflags) \ | ||
52 | do { \ | ||
53 | local_irq_save(flags); \ | ||
54 | mtflags = dvpe(); \ | ||
55 | } while (0) | ||
56 | |||
57 | #define UNLOCK_CORE(flags, mtflags) \ | ||
58 | do { \ | ||
59 | evpe(mtflags); \ | ||
60 | local_irq_restore(flags);\ | ||
61 | } while (0) | ||
62 | |||
63 | #else | ||
64 | |||
65 | #define LOCK_VPE(flags, mtflags) | ||
66 | #define UNLOCK_VPE(flags, mtflags) | ||
67 | #endif | ||
68 | |||
69 | /* ensure writes to cic are completed */ | ||
70 | static inline void cic_wmb(void) | ||
29 | { | 71 | { |
72 | const volatile void __iomem *cic_mem = CIC_VPE0_MSK_REG; | ||
73 | volatile u32 dummy_read; | ||
30 | 74 | ||
31 | /* check for PER interrupt range */ | 75 | wmb(); |
32 | if (irq < MSP_PER_INTBASE) | 76 | dummy_read = __raw_readl(cic_mem); |
33 | *CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE)); | 77 | dummy_read++; |
34 | else | ||
35 | *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE)); | ||
36 | } | 78 | } |
37 | 79 | ||
38 | static inline void mask_msp_cic_irq(unsigned int irq) | 80 | static void unmask_cic_irq(struct irq_data *d) |
39 | { | 81 | { |
40 | /* check for PER interrupt range */ | 82 | volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG; |
41 | if (irq < MSP_PER_INTBASE) | 83 | int vpe; |
42 | *CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE)); | 84 | #ifdef CONFIG_SMP |
43 | else | 85 | unsigned int mtflags; |
44 | *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE)); | 86 | unsigned long flags; |
87 | |||
88 | /* | ||
89 | * Make sure we have IRQ affinity. It may have changed while | ||
90 | * we were processing the IRQ. | ||
91 | */ | ||
92 | if (!cpumask_test_cpu(smp_processor_id(), d->affinity)) | ||
93 | return; | ||
94 | #endif | ||
95 | |||
96 | vpe = get_current_vpe(); | ||
97 | LOCK_VPE(flags, mtflags); | ||
98 | cic_msk_reg[vpe] |= (1 << (d->irq - MSP_CIC_INTBASE)); | ||
99 | UNLOCK_VPE(flags, mtflags); | ||
100 | cic_wmb(); | ||
45 | } | 101 | } |
46 | 102 | ||
47 | /* | 103 | static void mask_cic_irq(struct irq_data *d) |
48 | * While we ack the interrupt interrupts are disabled and thus we don't need | ||
49 | * to deal with concurrency issues. Same for msp_cic_irq_end. | ||
50 | */ | ||
51 | static inline void ack_msp_cic_irq(unsigned int irq) | ||
52 | { | 104 | { |
53 | mask_msp_cic_irq(irq); | 105 | volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG; |
54 | 106 | int vpe = get_current_vpe(); | |
107 | #ifdef CONFIG_SMP | ||
108 | unsigned long flags, mtflags; | ||
109 | #endif | ||
110 | LOCK_VPE(flags, mtflags); | ||
111 | cic_msk_reg[vpe] &= ~(1 << (d->irq - MSP_CIC_INTBASE)); | ||
112 | UNLOCK_VPE(flags, mtflags); | ||
113 | cic_wmb(); | ||
114 | } | ||
115 | static void msp_cic_irq_ack(struct irq_data *d) | ||
116 | { | ||
117 | mask_cic_irq(d); | ||
55 | /* | 118 | /* |
56 | * only really necessary for 18, 16-14 and sometimes 3:0 (since | 119 | * Only really necessary for 18, 16-14 and sometimes 3:0 |
57 | * these can be edge sensitive) but it doesn't hurt for the others. | 120 | * (since these can be edge sensitive) but it doesn't |
58 | */ | 121 | * hurt for the others |
59 | 122 | */ | |
60 | /* check for PER interrupt range */ | 123 | *CIC_STS_REG = (1 << (d->irq - MSP_CIC_INTBASE)); |
61 | if (irq < MSP_PER_INTBASE) | 124 | smtc_im_ack_irq(d->irq); |
62 | *CIC_STS_REG = (1 << (irq - MSP_CIC_INTBASE)); | ||
63 | else | ||
64 | *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE)); | ||
65 | } | 125 | } |
66 | 126 | ||
127 | /*Note: Limiting to VSMP . Not tested in SMTC */ | ||
128 | |||
129 | #ifdef CONFIG_MIPS_MT_SMP | ||
130 | static int msp_cic_irq_set_affinity(struct irq_data *d, | ||
131 | const struct cpumask *cpumask, bool force) | ||
132 | { | ||
133 | int cpu; | ||
134 | unsigned long flags; | ||
135 | unsigned int mtflags; | ||
136 | unsigned long imask = (1 << (irq - MSP_CIC_INTBASE)); | ||
137 | volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG; | ||
138 | |||
139 | /* timer balancing should be disabled in kernel code */ | ||
140 | BUG_ON(irq == MSP_INT_VPE0_TIMER || irq == MSP_INT_VPE1_TIMER); | ||
141 | |||
142 | LOCK_CORE(flags, mtflags); | ||
143 | /* enable if any of each VPE's TCs require this IRQ */ | ||
144 | for_each_online_cpu(cpu) { | ||
145 | if (cpumask_test_cpu(cpu, cpumask)) | ||
146 | cic_mask[cpu] |= imask; | ||
147 | else | ||
148 | cic_mask[cpu] &= ~imask; | ||
149 | |||
150 | } | ||
151 | |||
152 | UNLOCK_CORE(flags, mtflags); | ||
153 | return 0; | ||
154 | |||
155 | } | ||
156 | #endif | ||
157 | |||
67 | static struct irq_chip msp_cic_irq_controller = { | 158 | static struct irq_chip msp_cic_irq_controller = { |
68 | .name = "MSP_CIC", | 159 | .name = "MSP_CIC", |
69 | .ack = ack_msp_cic_irq, | 160 | .irq_mask = mask_cic_irq, |
70 | .mask = ack_msp_cic_irq, | 161 | .irq_mask_ack = msp_cic_irq_ack, |
71 | .mask_ack = ack_msp_cic_irq, | 162 | .irq_unmask = unmask_cic_irq, |
72 | .unmask = unmask_msp_cic_irq, | 163 | .irq_ack = msp_cic_irq_ack, |
164 | #ifdef CONFIG_MIPS_MT_SMP | ||
165 | .irq_set_affinity = msp_cic_irq_set_affinity, | ||
166 | #endif | ||
73 | }; | 167 | }; |
74 | 168 | ||
75 | |||
76 | void __init msp_cic_irq_init(void) | 169 | void __init msp_cic_irq_init(void) |
77 | { | 170 | { |
78 | int i; | 171 | int i; |
79 | |||
80 | /* Mask/clear interrupts. */ | 172 | /* Mask/clear interrupts. */ |
81 | *CIC_VPE0_MSK_REG = 0x00000000; | 173 | *CIC_VPE0_MSK_REG = 0x00000000; |
82 | *PER_INT_MSK_REG = 0x00000000; | 174 | *CIC_VPE1_MSK_REG = 0x00000000; |
83 | *CIC_STS_REG = 0xFFFFFFFF; | 175 | *CIC_STS_REG = 0xFFFFFFFF; |
84 | *PER_INT_STS_REG = 0xFFFFFFFF; | ||
85 | |||
86 | #if defined(CONFIG_PMC_MSP7120_GW) || \ | ||
87 | defined(CONFIG_PMC_MSP7120_EVAL) | ||
88 | /* | 176 | /* |
89 | * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI. | 177 | * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI. |
90 | * These inputs map to EXT_INT_POL[6:4] inside the CIC. | 178 | * These inputs map to EXT_INT_POL[6:4] inside the CIC. |
91 | * They are to be active low, level sensitive. | 179 | * They are to be active low, level sensitive. |
92 | */ | 180 | */ |
93 | *CIC_EXT_CFG_REG &= 0xFFFF8F8F; | 181 | *CIC_EXT_CFG_REG &= 0xFFFF8F8F; |
94 | #endif | ||
95 | 182 | ||
96 | /* initialize all the IRQ descriptors */ | 183 | /* initialize all the IRQ descriptors */ |
97 | for (i = MSP_CIC_INTBASE; i < MSP_PER_INTBASE + 32; i++) | 184 | for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) { |
98 | set_irq_chip_and_handler(i, &msp_cic_irq_controller, | 185 | set_irq_chip_and_handler(i, &msp_cic_irq_controller, |
99 | handle_level_irq); | 186 | handle_level_irq); |
187 | #ifdef CONFIG_MIPS_MT_SMTC | ||
188 | /* Mask of CIC interrupt */ | ||
189 | irq_hwmask[i] = C_IRQ4; | ||
190 | #endif | ||
191 | } | ||
192 | |||
193 | /* Initialize the PER interrupt sub-system */ | ||
194 | msp_per_irq_init(); | ||
100 | } | 195 | } |
101 | 196 | ||
197 | /* CIC masked by CIC vector processing before dispatch called */ | ||
102 | void msp_cic_irq_dispatch(void) | 198 | void msp_cic_irq_dispatch(void) |
103 | { | 199 | { |
104 | u32 pending; | 200 | volatile u32 *cic_msk_reg = (volatile u32 *)CIC_VPE0_MSK_REG; |
105 | int intbase; | 201 | u32 cic_mask; |
106 | 202 | u32 pending; | |
107 | intbase = MSP_CIC_INTBASE; | 203 | int cic_status = *CIC_STS_REG; |
108 | pending = *CIC_STS_REG & *CIC_VPE0_MSK_REG; | 204 | cic_mask = cic_msk_reg[get_current_vpe()]; |
109 | 205 | pending = cic_status & cic_mask; | |
110 | /* check for PER interrupt */ | 206 | if (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))) { |
111 | if (pending == (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) { | ||
112 | intbase = MSP_PER_INTBASE; | ||
113 | pending = *PER_INT_STS_REG & *PER_INT_MSK_REG; | ||
114 | } | ||
115 | |||
116 | /* check for spurious interrupt */ | ||
117 | if (pending == 0x00000000) { | ||
118 | printk(KERN_ERR | ||
119 | "Spurious %s interrupt? status %08x, mask %08x\n", | ||
120 | (intbase == MSP_CIC_INTBASE) ? "CIC" : "PER", | ||
121 | (intbase == MSP_CIC_INTBASE) ? | ||
122 | *CIC_STS_REG : *PER_INT_STS_REG, | ||
123 | (intbase == MSP_CIC_INTBASE) ? | ||
124 | *CIC_VPE0_MSK_REG : *PER_INT_MSK_REG); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | /* check for the timer and dispatch it first */ | ||
129 | if ((intbase == MSP_CIC_INTBASE) && | ||
130 | (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE)))) | ||
131 | do_IRQ(MSP_INT_VPE0_TIMER); | 207 | do_IRQ(MSP_INT_VPE0_TIMER); |
132 | else | 208 | } else if (pending & (1 << (MSP_INT_VPE1_TIMER - MSP_CIC_INTBASE))) { |
133 | do_IRQ(ffs(pending) + intbase - 1); | 209 | do_IRQ(MSP_INT_VPE1_TIMER); |
210 | } else if (pending & (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) { | ||
211 | msp_per_irq_dispatch(); | ||
212 | } else if (pending) { | ||
213 | do_IRQ(ffs(pending) + MSP_CIC_INTBASE - 1); | ||
214 | } else{ | ||
215 | spurious_interrupt(); | ||
216 | } | ||
134 | } | 217 | } |
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c new file mode 100644 index 000000000000..f9b9dcdfa9dd --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c | ||
3 | * | ||
4 | * This file define the irq handler for MSP PER subsystem interrupts. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/bitops.h> | ||
17 | |||
18 | #include <asm/mipsregs.h> | ||
19 | #include <asm/system.h> | ||
20 | |||
21 | #include <msp_cic_int.h> | ||
22 | #include <msp_regs.h> | ||
23 | |||
24 | |||
25 | /* | ||
26 | * Convenience Macro. Should be somewhere generic. | ||
27 | */ | ||
28 | #define get_current_vpe() \ | ||
29 | ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE) | ||
30 | |||
31 | #ifdef CONFIG_SMP | ||
32 | /* | ||
33 | * The PER registers must be protected from concurrent access. | ||
34 | */ | ||
35 | |||
36 | static DEFINE_SPINLOCK(per_lock); | ||
37 | #endif | ||
38 | |||
39 | /* ensure writes to per are completed */ | ||
40 | |||
41 | static inline void per_wmb(void) | ||
42 | { | ||
43 | const volatile void __iomem *per_mem = PER_INT_MSK_REG; | ||
44 | volatile u32 dummy_read; | ||
45 | |||
46 | wmb(); | ||
47 | dummy_read = __raw_readl(per_mem); | ||
48 | dummy_read++; | ||
49 | } | ||
50 | |||
51 | static inline void unmask_per_irq(struct irq_data *d) | ||
52 | { | ||
53 | #ifdef CONFIG_SMP | ||
54 | unsigned long flags; | ||
55 | spin_lock_irqsave(&per_lock, flags); | ||
56 | *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE)); | ||
57 | spin_unlock_irqrestore(&per_lock, flags); | ||
58 | #else | ||
59 | *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE)); | ||
60 | #endif | ||
61 | per_wmb(); | ||
62 | } | ||
63 | |||
64 | static inline void mask_per_irq(struct irq_data *d) | ||
65 | { | ||
66 | #ifdef CONFIG_SMP | ||
67 | unsigned long flags; | ||
68 | spin_lock_irqsave(&per_lock, flags); | ||
69 | *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE)); | ||
70 | spin_unlock_irqrestore(&per_lock, flags); | ||
71 | #else | ||
72 | *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE)); | ||
73 | #endif | ||
74 | per_wmb(); | ||
75 | } | ||
76 | |||
77 | static inline void msp_per_irq_ack(struct irq_data *d) | ||
78 | { | ||
79 | mask_per_irq(d); | ||
80 | /* | ||
81 | * In the PER interrupt controller, only bits 11 and 10 | ||
82 | * are write-to-clear, (SPI TX complete, SPI RX complete). | ||
83 | * It does nothing for any others. | ||
84 | */ | ||
85 | *PER_INT_STS_REG = (1 << (d->irq - MSP_PER_INTBASE)); | ||
86 | } | ||
87 | |||
88 | #ifdef CONFIG_SMP | ||
89 | static int msp_per_irq_set_affinity(struct irq_data *d, | ||
90 | const struct cpumask *affinity, bool force) | ||
91 | { | ||
92 | /* WTF is this doing ????? */ | ||
93 | unmask_per_irq(d); | ||
94 | return 0; | ||
95 | } | ||
96 | #endif | ||
97 | |||
98 | static struct irq_chip msp_per_irq_controller = { | ||
99 | .name = "MSP_PER", | ||
100 | .irq_enable = unmask_per_irq. | ||
101 | .irq_disable = mask_per_irq, | ||
102 | .irq_ack = msp_per_irq_ack, | ||
103 | #ifdef CONFIG_SMP | ||
104 | .irq_set_affinity = msp_per_irq_set_affinity, | ||
105 | #endif | ||
106 | }; | ||
107 | |||
108 | void __init msp_per_irq_init(void) | ||
109 | { | ||
110 | int i; | ||
111 | /* Mask/clear interrupts. */ | ||
112 | *PER_INT_MSK_REG = 0x00000000; | ||
113 | *PER_INT_STS_REG = 0xFFFFFFFF; | ||
114 | /* initialize all the IRQ descriptors */ | ||
115 | for (i = MSP_PER_INTBASE; i < MSP_PER_INTBASE + 32; i++) { | ||
116 | irq_set_chip(i, &msp_per_irq_controller); | ||
117 | #ifdef CONFIG_MIPS_MT_SMTC | ||
118 | irq_hwmask[i] = C_IRQ4; | ||
119 | #endif | ||
120 | } | ||
121 | } | ||
122 | |||
123 | void msp_per_irq_dispatch(void) | ||
124 | { | ||
125 | u32 per_mask = *PER_INT_MSK_REG; | ||
126 | u32 per_status = *PER_INT_STS_REG; | ||
127 | u32 pending; | ||
128 | |||
129 | pending = per_status & per_mask; | ||
130 | if (pending) { | ||
131 | do_IRQ(ffs(pending) + MSP_PER_INTBASE - 1); | ||
132 | } else { | ||
133 | spurious_interrupt(); | ||
134 | } | ||
135 | } | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c index 61f390232346..8f51e4adc438 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c | |||
@@ -21,8 +21,10 @@ | |||
21 | #include <msp_slp_int.h> | 21 | #include <msp_slp_int.h> |
22 | #include <msp_regs.h> | 22 | #include <msp_regs.h> |
23 | 23 | ||
24 | static inline void unmask_msp_slp_irq(unsigned int irq) | 24 | static inline void unmask_msp_slp_irq(struct irq_data *d) |
25 | { | 25 | { |
26 | unsigned int irq = d->irq; | ||
27 | |||
26 | /* check for PER interrupt range */ | 28 | /* check for PER interrupt range */ |
27 | if (irq < MSP_PER_INTBASE) | 29 | if (irq < MSP_PER_INTBASE) |
28 | *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE)); | 30 | *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE)); |
@@ -30,8 +32,10 @@ static inline void unmask_msp_slp_irq(unsigned int irq) | |||
30 | *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE)); | 32 | *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE)); |
31 | } | 33 | } |
32 | 34 | ||
33 | static inline void mask_msp_slp_irq(unsigned int irq) | 35 | static inline void mask_msp_slp_irq(struct irq_data *d) |
34 | { | 36 | { |
37 | unsigned int irq = d->irq; | ||
38 | |||
35 | /* check for PER interrupt range */ | 39 | /* check for PER interrupt range */ |
36 | if (irq < MSP_PER_INTBASE) | 40 | if (irq < MSP_PER_INTBASE) |
37 | *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE)); | 41 | *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE)); |
@@ -43,8 +47,10 @@ static inline void mask_msp_slp_irq(unsigned int irq) | |||
43 | * While we ack the interrupt interrupts are disabled and thus we don't need | 47 | * While we ack the interrupt interrupts are disabled and thus we don't need |
44 | * to deal with concurrency issues. Same for msp_slp_irq_end. | 48 | * to deal with concurrency issues. Same for msp_slp_irq_end. |
45 | */ | 49 | */ |
46 | static inline void ack_msp_slp_irq(unsigned int irq) | 50 | static inline void ack_msp_slp_irq(struct irq_data *d) |
47 | { | 51 | { |
52 | unsigned int irq = d->irq; | ||
53 | |||
48 | /* check for PER interrupt range */ | 54 | /* check for PER interrupt range */ |
49 | if (irq < MSP_PER_INTBASE) | 55 | if (irq < MSP_PER_INTBASE) |
50 | *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE)); | 56 | *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE)); |
@@ -54,9 +60,9 @@ static inline void ack_msp_slp_irq(unsigned int irq) | |||
54 | 60 | ||
55 | static struct irq_chip msp_slp_irq_controller = { | 61 | static struct irq_chip msp_slp_irq_controller = { |
56 | .name = "MSP_SLP", | 62 | .name = "MSP_SLP", |
57 | .ack = ack_msp_slp_irq, | 63 | .irq_ack = ack_msp_slp_irq, |
58 | .mask = mask_msp_slp_irq, | 64 | .irq_mask = mask_msp_slp_irq, |
59 | .unmask = unmask_msp_slp_irq, | 65 | .irq_unmask = unmask_msp_slp_irq, |
60 | }; | 66 | }; |
61 | 67 | ||
62 | void __init msp_slp_irq_init(void) | 68 | void __init msp_slp_irq_init(void) |
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c index a54e85b3cf29..fb37a10e0309 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c | |||
@@ -146,6 +146,8 @@ void __init plat_mem_setup(void) | |||
146 | pm_power_off = msp_power_off; | 146 | pm_power_off = msp_power_off; |
147 | } | 147 | } |
148 | 148 | ||
149 | extern struct plat_smp_ops msp_smtc_smp_ops; | ||
150 | |||
149 | void __init prom_init(void) | 151 | void __init prom_init(void) |
150 | { | 152 | { |
151 | unsigned long family; | 153 | unsigned long family; |
@@ -226,6 +228,14 @@ void __init prom_init(void) | |||
226 | */ | 228 | */ |
227 | msp_serial_setup(); | 229 | msp_serial_setup(); |
228 | 230 | ||
231 | #ifdef CONFIG_MIPS_MT_SMP | ||
232 | register_smp_ops(&vsmp_smp_ops); | ||
233 | #endif | ||
234 | |||
235 | #ifdef CONFIG_MIPS_MT_SMTC | ||
236 | register_smp_ops(&msp_smtc_smp_ops); | ||
237 | #endif | ||
238 | |||
229 | #ifdef CONFIG_PMCTWILED | 239 | #ifdef CONFIG_PMCTWILED |
230 | /* | 240 | /* |
231 | * Setup LED states before the subsys_initcall loads other | 241 | * Setup LED states before the subsys_initcall loads other |
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/arch/mips/pmc-sierra/msp71xx/msp_smp.c new file mode 100644 index 000000000000..43a9e26e1c69 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smp.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. | ||
3 | * Copyright (C) 2001 Ralf Baechle | ||
4 | * Copyright (C) 2010 PMC-Sierra, Inc. | ||
5 | * | ||
6 | * VSMP support for MSP platforms . Derived from malta vsmp support. | ||
7 | * | ||
8 | * This program is free software; you can distribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (Version 2) as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
15 | * for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
20 | * | ||
21 | */ | ||
22 | #include <linux/smp.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #ifdef CONFIG_MIPS_MT_SMP | ||
26 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ | ||
27 | #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */ | ||
28 | |||
29 | |||
30 | static void ipi_resched_dispatch(void) | ||
31 | { | ||
32 | do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ); | ||
33 | } | ||
34 | |||
35 | static void ipi_call_dispatch(void) | ||
36 | { | ||
37 | do_IRQ(MIPS_CPU_IPI_CALL_IRQ); | ||
38 | } | ||
39 | |||
40 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | ||
41 | { | ||
42 | return IRQ_HANDLED; | ||
43 | } | ||
44 | |||
45 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | ||
46 | { | ||
47 | smp_call_function_interrupt(); | ||
48 | |||
49 | return IRQ_HANDLED; | ||
50 | } | ||
51 | |||
52 | static struct irqaction irq_resched = { | ||
53 | .handler = ipi_resched_interrupt, | ||
54 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
55 | .name = "IPI_resched" | ||
56 | }; | ||
57 | |||
58 | static struct irqaction irq_call = { | ||
59 | .handler = ipi_call_interrupt, | ||
60 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
61 | .name = "IPI_call" | ||
62 | }; | ||
63 | |||
64 | void __init arch_init_ipiirq(int irq, struct irqaction *action) | ||
65 | { | ||
66 | setup_irq(irq, action); | ||
67 | set_irq_handler(irq, handle_percpu_irq); | ||
68 | } | ||
69 | |||
70 | void __init msp_vsmp_int_init(void) | ||
71 | { | ||
72 | set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); | ||
73 | set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); | ||
74 | arch_init_ipiirq(MIPS_CPU_IPI_RESCHED_IRQ, &irq_resched); | ||
75 | arch_init_ipiirq(MIPS_CPU_IPI_CALL_IRQ, &irq_call); | ||
76 | } | ||
77 | #endif /* CONFIG_MIPS_MT_SMP */ | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smtc.c b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c new file mode 100644 index 000000000000..c8dcc1c01e18 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * MSP71xx Platform-specific hooks for SMP operation | ||
3 | */ | ||
4 | #include <linux/irq.h> | ||
5 | #include <linux/init.h> | ||
6 | |||
7 | #include <asm/mipsmtregs.h> | ||
8 | #include <asm/mipsregs.h> | ||
9 | #include <asm/smtc.h> | ||
10 | #include <asm/smtc_ipi.h> | ||
11 | |||
12 | /* VPE/SMP Prototype implements platform interfaces directly */ | ||
13 | |||
14 | /* | ||
15 | * Cause the specified action to be performed on a targeted "CPU" | ||
16 | */ | ||
17 | |||
18 | static void msp_smtc_send_ipi_single(int cpu, unsigned int action) | ||
19 | { | ||
20 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | ||
21 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | ||
22 | } | ||
23 | |||
24 | static void msp_smtc_send_ipi_mask(const struct cpumask *mask, | ||
25 | unsigned int action) | ||
26 | { | ||
27 | unsigned int i; | ||
28 | |||
29 | for_each_cpu(i, mask) | ||
30 | msp_smtc_send_ipi_single(i, action); | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * Post-config but pre-boot cleanup entry point | ||
35 | */ | ||
36 | static void __cpuinit msp_smtc_init_secondary(void) | ||
37 | { | ||
38 | int myvpe; | ||
39 | |||
40 | /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ | ||
41 | myvpe = read_c0_tcbind() & TCBIND_CURVPE; | ||
42 | if (myvpe > 0) | ||
43 | change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | | ||
44 | STATUSF_IP6 | STATUSF_IP7); | ||
45 | smtc_init_secondary(); | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * Platform "CPU" startup hook | ||
50 | */ | ||
51 | static void __cpuinit msp_smtc_boot_secondary(int cpu, | ||
52 | struct task_struct *idle) | ||
53 | { | ||
54 | smtc_boot_secondary(cpu, idle); | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * SMP initialization finalization entry point | ||
59 | */ | ||
60 | static void __cpuinit msp_smtc_smp_finish(void) | ||
61 | { | ||
62 | smtc_smp_finish(); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * Hook for after all CPUs are online | ||
67 | */ | ||
68 | |||
69 | static void msp_smtc_cpus_done(void) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Platform SMP pre-initialization | ||
75 | * | ||
76 | * As noted above, we can assume a single CPU for now | ||
77 | * but it may be multithreaded. | ||
78 | */ | ||
79 | |||
80 | static void __init msp_smtc_smp_setup(void) | ||
81 | { | ||
82 | /* | ||
83 | * we won't get the definitive value until | ||
84 | * we've run smtc_prepare_cpus later, but | ||
85 | */ | ||
86 | |||
87 | if (read_c0_config3() & (1 << 2)) | ||
88 | smp_num_siblings = smtc_build_cpu_map(0); | ||
89 | } | ||
90 | |||
91 | static void __init msp_smtc_prepare_cpus(unsigned int max_cpus) | ||
92 | { | ||
93 | smtc_prepare_cpus(max_cpus); | ||
94 | } | ||
95 | |||
96 | struct plat_smp_ops msp_smtc_smp_ops = { | ||
97 | .send_ipi_single = msp_smtc_send_ipi_single, | ||
98 | .send_ipi_mask = msp_smtc_send_ipi_mask, | ||
99 | .init_secondary = msp_smtc_init_secondary, | ||
100 | .smp_finish = msp_smtc_smp_finish, | ||
101 | .cpus_done = msp_smtc_cpus_done, | ||
102 | .boot_secondary = msp_smtc_boot_secondary, | ||
103 | .smp_setup = msp_smtc_smp_setup, | ||
104 | .prepare_cpus = msp_smtc_prepare_cpus, | ||
105 | }; | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c index 01df84ce31e2..8b42f307a7a7 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_time.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
31 | 31 | ||
32 | #include <asm/cevt-r4k.h> | ||
32 | #include <asm/mipsregs.h> | 33 | #include <asm/mipsregs.h> |
33 | #include <asm/time.h> | 34 | #include <asm/time.h> |
34 | 35 | ||
@@ -36,6 +37,12 @@ | |||
36 | #include <msp_int.h> | 37 | #include <msp_int.h> |
37 | #include <msp_regs.h> | 38 | #include <msp_regs.h> |
38 | 39 | ||
40 | #define get_current_vpe() \ | ||
41 | ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE) | ||
42 | |||
43 | static struct irqaction timer_vpe1; | ||
44 | static int tim_installed; | ||
45 | |||
39 | void __init plat_time_init(void) | 46 | void __init plat_time_init(void) |
40 | { | 47 | { |
41 | char *endp, *s; | 48 | char *endp, *s; |
@@ -83,5 +90,12 @@ void __init plat_time_init(void) | |||
83 | 90 | ||
84 | unsigned int __cpuinit get_c0_compare_int(void) | 91 | unsigned int __cpuinit get_c0_compare_int(void) |
85 | { | 92 | { |
86 | return MSP_INT_VPE0_TIMER; | 93 | /* MIPS_MT modes may want timer for second VPE */ |
94 | if ((get_current_vpe()) && !tim_installed) { | ||
95 | memcpy(&timer_vpe1, &c0_compare_irqaction, sizeof(timer_vpe1)); | ||
96 | setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1); | ||
97 | tim_installed++; | ||
98 | } | ||
99 | |||
100 | return get_current_vpe() ? MSP_INT_VPE1_TIMER : MSP_INT_VPE0_TIMER; | ||
87 | } | 101 | } |
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c index 0ee01e359dd8..9a1aef89bd4c 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_usb.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_usb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * The setup file for USB related hardware on PMC-Sierra MSP processors. | 2 | * The setup file for USB related hardware on PMC-Sierra MSP processors. |
3 | * | 3 | * |
4 | * Copyright 2006-2007 PMC-Sierra, Inc. | 4 | * Copyright 2006 PMC-Sierra, Inc. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -23,8 +23,8 @@ | |||
23 | * with this program; if not, write to the Free Software Foundation, Inc., | 23 | * with this program; if not, write to the Free Software Foundation, Inc., |
24 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 24 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
25 | */ | 25 | */ |
26 | #if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) | ||
26 | 27 | ||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
@@ -34,40 +34,56 @@ | |||
34 | #include <msp_regs.h> | 34 | #include <msp_regs.h> |
35 | #include <msp_int.h> | 35 | #include <msp_int.h> |
36 | #include <msp_prom.h> | 36 | #include <msp_prom.h> |
37 | #include <msp_usb.h> | ||
38 | |||
37 | 39 | ||
38 | #if defined(CONFIG_USB_EHCI_HCD) | 40 | #if defined(CONFIG_USB_EHCI_HCD) |
39 | static struct resource msp_usbhost_resources [] = { | 41 | static struct resource msp_usbhost0_resources[] = { |
40 | [0] = { | 42 | [0] = { /* EHCI-HS operational and capabilities registers */ |
41 | .start = MSP_USB_BASE_START, | 43 | .start = MSP_USB0_HS_START, |
42 | .end = MSP_USB_BASE_END, | 44 | .end = MSP_USB0_HS_END, |
43 | .flags = IORESOURCE_MEM, | 45 | .flags = IORESOURCE_MEM, |
44 | }, | 46 | }, |
45 | [1] = { | 47 | [1] = { |
46 | .start = MSP_INT_USB, | 48 | .start = MSP_INT_USB, |
47 | .end = MSP_INT_USB, | 49 | .end = MSP_INT_USB, |
48 | .flags = IORESOURCE_IRQ, | 50 | .flags = IORESOURCE_IRQ, |
51 | }, | ||
52 | [2] = { /* MSBus-to-AMBA bridge register space */ | ||
53 | .start = MSP_USB0_MAB_START, | ||
54 | .end = MSP_USB0_MAB_END, | ||
55 | .flags = IORESOURCE_MEM, | ||
56 | }, | ||
57 | [3] = { /* Identification and general hardware parameters */ | ||
58 | .start = MSP_USB0_ID_START, | ||
59 | .end = MSP_USB0_ID_END, | ||
60 | .flags = IORESOURCE_MEM, | ||
49 | }, | 61 | }, |
50 | }; | 62 | }; |
51 | 63 | ||
52 | static u64 msp_usbhost_dma_mask = DMA_BIT_MASK(32); | 64 | static u64 msp_usbhost0_dma_mask = 0xffffffffUL; |
53 | 65 | ||
54 | static struct platform_device msp_usbhost_device = { | 66 | static struct mspusb_device msp_usbhost0_device = { |
55 | .name = "pmcmsp-ehci", | ||
56 | .id = 0, | ||
57 | .dev = { | 67 | .dev = { |
58 | .dma_mask = &msp_usbhost_dma_mask, | 68 | .name = "pmcmsp-ehci", |
59 | .coherent_dma_mask = DMA_BIT_MASK(32), | 69 | .id = 0, |
70 | .dev = { | ||
71 | .dma_mask = &msp_usbhost0_dma_mask, | ||
72 | .coherent_dma_mask = 0xffffffffUL, | ||
73 | }, | ||
74 | .num_resources = ARRAY_SIZE(msp_usbhost0_resources), | ||
75 | .resource = msp_usbhost0_resources, | ||
60 | }, | 76 | }, |
61 | .num_resources = ARRAY_SIZE(msp_usbhost_resources), | ||
62 | .resource = msp_usbhost_resources, | ||
63 | }; | 77 | }; |
64 | #endif /* CONFIG_USB_EHCI_HCD */ | ||
65 | 78 | ||
66 | #if defined(CONFIG_USB_GADGET) | 79 | /* MSP7140/MSP82XX has two USB2 hosts. */ |
67 | static struct resource msp_usbdev_resources [] = { | 80 | #ifdef CONFIG_MSP_HAS_DUAL_USB |
68 | [0] = { | 81 | static u64 msp_usbhost1_dma_mask = 0xffffffffUL; |
69 | .start = MSP_USB_BASE, | 82 | |
70 | .end = MSP_USB_BASE_END, | 83 | static struct resource msp_usbhost1_resources[] = { |
84 | [0] = { /* EHCI-HS operational and capabilities registers */ | ||
85 | .start = MSP_USB1_HS_START, | ||
86 | .end = MSP_USB1_HS_END, | ||
71 | .flags = IORESOURCE_MEM, | 87 | .flags = IORESOURCE_MEM, |
72 | }, | 88 | }, |
73 | [1] = { | 89 | [1] = { |
@@ -75,76 +91,173 @@ static struct resource msp_usbdev_resources [] = { | |||
75 | .end = MSP_INT_USB, | 91 | .end = MSP_INT_USB, |
76 | .flags = IORESOURCE_IRQ, | 92 | .flags = IORESOURCE_IRQ, |
77 | }, | 93 | }, |
94 | [2] = { /* MSBus-to-AMBA bridge register space */ | ||
95 | .start = MSP_USB1_MAB_START, | ||
96 | .end = MSP_USB1_MAB_END, | ||
97 | .flags = IORESOURCE_MEM, | ||
98 | }, | ||
99 | [3] = { /* Identification and general hardware parameters */ | ||
100 | .start = MSP_USB1_ID_START, | ||
101 | .end = MSP_USB1_ID_END, | ||
102 | .flags = IORESOURCE_MEM, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | static struct mspusb_device msp_usbhost1_device = { | ||
107 | .dev = { | ||
108 | .name = "pmcmsp-ehci", | ||
109 | .id = 1, | ||
110 | .dev = { | ||
111 | .dma_mask = &msp_usbhost1_dma_mask, | ||
112 | .coherent_dma_mask = 0xffffffffUL, | ||
113 | }, | ||
114 | .num_resources = ARRAY_SIZE(msp_usbhost1_resources), | ||
115 | .resource = msp_usbhost1_resources, | ||
116 | }, | ||
78 | }; | 117 | }; |
118 | #endif /* CONFIG_MSP_HAS_DUAL_USB */ | ||
119 | #endif /* CONFIG_USB_EHCI_HCD */ | ||
79 | 120 | ||
80 | static u64 msp_usbdev_dma_mask = DMA_BIT_MASK(32); | 121 | #if defined(CONFIG_USB_GADGET) |
122 | static struct resource msp_usbdev0_resources[] = { | ||
123 | [0] = { /* EHCI-HS operational and capabilities registers */ | ||
124 | .start = MSP_USB0_HS_START, | ||
125 | .end = MSP_USB0_HS_END, | ||
126 | .flags = IORESOURCE_MEM, | ||
127 | }, | ||
128 | [1] = { | ||
129 | .start = MSP_INT_USB, | ||
130 | .end = MSP_INT_USB, | ||
131 | .flags = IORESOURCE_IRQ, | ||
132 | }, | ||
133 | [2] = { /* MSBus-to-AMBA bridge register space */ | ||
134 | .start = MSP_USB0_MAB_START, | ||
135 | .end = MSP_USB0_MAB_END, | ||
136 | .flags = IORESOURCE_MEM, | ||
137 | }, | ||
138 | [3] = { /* Identification and general hardware parameters */ | ||
139 | .start = MSP_USB0_ID_START, | ||
140 | .end = MSP_USB0_ID_END, | ||
141 | .flags = IORESOURCE_MEM, | ||
142 | }, | ||
143 | }; | ||
81 | 144 | ||
82 | static struct platform_device msp_usbdev_device = { | 145 | static u64 msp_usbdev_dma_mask = 0xffffffffUL; |
83 | .name = "msp71xx_udc", | 146 | |
84 | .id = 0, | 147 | /* This may need to be converted to a mspusb_device, too. */ |
148 | static struct mspusb_device msp_usbdev0_device = { | ||
85 | .dev = { | 149 | .dev = { |
86 | .dma_mask = &msp_usbdev_dma_mask, | 150 | .name = "msp71xx_udc", |
87 | .coherent_dma_mask = DMA_BIT_MASK(32), | 151 | .id = 0, |
152 | .dev = { | ||
153 | .dma_mask = &msp_usbdev_dma_mask, | ||
154 | .coherent_dma_mask = 0xffffffffUL, | ||
155 | }, | ||
156 | .num_resources = ARRAY_SIZE(msp_usbdev0_resources), | ||
157 | .resource = msp_usbdev0_resources, | ||
88 | }, | 158 | }, |
89 | .num_resources = ARRAY_SIZE(msp_usbdev_resources), | ||
90 | .resource = msp_usbdev_resources, | ||
91 | }; | 159 | }; |
92 | #endif /* CONFIG_USB_GADGET */ | ||
93 | 160 | ||
94 | #if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) | 161 | #ifdef CONFIG_MSP_HAS_DUAL_USB |
95 | static struct platform_device *msp_devs[1]; | 162 | static struct resource msp_usbdev1_resources[] = { |
96 | #endif | 163 | [0] = { /* EHCI-HS operational and capabilities registers */ |
164 | .start = MSP_USB1_HS_START, | ||
165 | .end = MSP_USB1_HS_END, | ||
166 | .flags = IORESOURCE_MEM, | ||
167 | }, | ||
168 | [1] = { | ||
169 | .start = MSP_INT_USB, | ||
170 | .end = MSP_INT_USB, | ||
171 | .flags = IORESOURCE_IRQ, | ||
172 | }, | ||
173 | [2] = { /* MSBus-to-AMBA bridge register space */ | ||
174 | .start = MSP_USB1_MAB_START, | ||
175 | .end = MSP_USB1_MAB_END, | ||
176 | .flags = IORESOURCE_MEM, | ||
177 | }, | ||
178 | [3] = { /* Identification and general hardware parameters */ | ||
179 | .start = MSP_USB1_ID_START, | ||
180 | .end = MSP_USB1_ID_END, | ||
181 | .flags = IORESOURCE_MEM, | ||
182 | }, | ||
183 | }; | ||
97 | 184 | ||
185 | /* This may need to be converted to a mspusb_device, too. */ | ||
186 | static struct mspusb_device msp_usbdev1_device = { | ||
187 | .dev = { | ||
188 | .name = "msp71xx_udc", | ||
189 | .id = 0, | ||
190 | .dev = { | ||
191 | .dma_mask = &msp_usbdev_dma_mask, | ||
192 | .coherent_dma_mask = 0xffffffffUL, | ||
193 | }, | ||
194 | .num_resources = ARRAY_SIZE(msp_usbdev1_resources), | ||
195 | .resource = msp_usbdev1_resources, | ||
196 | }, | ||
197 | }; | ||
198 | |||
199 | #endif /* CONFIG_MSP_HAS_DUAL_USB */ | ||
200 | #endif /* CONFIG_USB_GADGET */ | ||
98 | 201 | ||
99 | static int __init msp_usb_setup(void) | 202 | static int __init msp_usb_setup(void) |
100 | { | 203 | { |
101 | #if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) | 204 | char *strp; |
102 | char *strp; | 205 | char envstr[32]; |
103 | char envstr[32]; | 206 | struct platform_device *msp_devs[NUM_USB_DEVS]; |
104 | unsigned int val = 0; | 207 | unsigned int val; |
105 | int result = 0; | ||
106 | 208 | ||
209 | /* construct environment name usbmode */ | ||
210 | /* set usbmode <host/device> as pmon environment var */ | ||
107 | /* | 211 | /* |
108 | * construct environment name usbmode | 212 | * Could this perhaps be integrated into the "features" env var? |
109 | * set usbmode <host/device> as pmon environment var | 213 | * Use the features key "U", and follow with "H" for host-mode, |
214 | * "D" for device-mode. If it works for Ethernet, why not USB... | ||
215 | * -- hammtrev, 2007/03/22 | ||
110 | */ | 216 | */ |
111 | snprintf((char *)&envstr[0], sizeof(envstr), "usbmode"); | 217 | snprintf((char *)&envstr[0], sizeof(envstr), "usbmode"); |
112 | 218 | ||
113 | #if defined(CONFIG_USB_EHCI_HCD) | 219 | /* set default host mode */ |
114 | /* default to host mode */ | ||
115 | val = 1; | 220 | val = 1; |
116 | #endif | ||
117 | 221 | ||
118 | /* get environment string */ | 222 | /* get environment string */ |
119 | strp = prom_getenv((char *)&envstr[0]); | 223 | strp = prom_getenv((char *)&envstr[0]); |
120 | if (strp) { | 224 | if (strp) { |
225 | /* compare string */ | ||
121 | if (!strcmp(strp, "device")) | 226 | if (!strcmp(strp, "device")) |
122 | val = 0; | 227 | val = 0; |
123 | } | 228 | } |
124 | 229 | ||
125 | if (val) { | 230 | if (val) { |
126 | #if defined(CONFIG_USB_EHCI_HCD) | 231 | #if defined(CONFIG_USB_EHCI_HCD) |
127 | /* get host mode device */ | 232 | msp_devs[0] = &msp_usbhost0_device.dev; |
128 | msp_devs[0] = &msp_usbhost_device; | 233 | ppfinit("platform add USB HOST done %s.\n", msp_devs[0]->name); |
129 | ppfinit("platform add USB HOST done %s.\n", | 234 | #ifdef CONFIG_MSP_HAS_DUAL_USB |
130 | msp_devs[0]->name); | 235 | msp_devs[1] = &msp_usbhost1_device.dev; |
131 | 236 | ppfinit("platform add USB HOST done %s.\n", msp_devs[1]->name); | |
132 | result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs)); | 237 | #endif |
133 | #endif /* CONFIG_USB_EHCI_HCD */ | 238 | #else |
134 | } | 239 | ppfinit("%s: echi_hcd not supported\n", __FILE__); |
240 | #endif /* CONFIG_USB_EHCI_HCD */ | ||
241 | } else { | ||
135 | #if defined(CONFIG_USB_GADGET) | 242 | #if defined(CONFIG_USB_GADGET) |
136 | else { | ||
137 | /* get device mode structure */ | 243 | /* get device mode structure */ |
138 | msp_devs[0] = &msp_usbdev_device; | 244 | msp_devs[0] = &msp_usbdev0_device.dev; |
139 | ppfinit("platform add USB DEVICE done %s.\n", | 245 | ppfinit("platform add USB DEVICE done %s.\n" |
140 | msp_devs[0]->name); | 246 | , msp_devs[0]->name); |
141 | 247 | #ifdef CONFIG_MSP_HAS_DUAL_USB | |
142 | result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs)); | 248 | msp_devs[1] = &msp_usbdev1_device.dev; |
249 | ppfinit("platform add USB DEVICE done %s.\n" | ||
250 | , msp_devs[1]->name); | ||
251 | #endif | ||
252 | #else | ||
253 | ppfinit("%s: usb_gadget not supported\n", __FILE__); | ||
254 | #endif /* CONFIG_USB_GADGET */ | ||
143 | } | 255 | } |
144 | #endif /* CONFIG_USB_GADGET */ | 256 | /* add device */ |
145 | #endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */ | 257 | platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs)); |
146 | 258 | ||
147 | return result; | 259 | return 0; |
148 | } | 260 | } |
149 | 261 | ||
150 | subsys_initcall(msp_usb_setup); | 262 | subsys_initcall(msp_usb_setup); |
263 | #endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */ | ||
diff --git a/arch/mips/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c index 941916f8aaff..b226bcb0a2f4 100644 --- a/arch/mips/pnx833x/common/interrupts.c +++ b/arch/mips/pnx833x/common/interrupts.c | |||
@@ -152,10 +152,6 @@ static inline void pnx833x_hard_disable_pic_irq(unsigned int irq) | |||
152 | PNX833X_PIC_INT_REG(irq) = 0; | 152 | PNX833X_PIC_INT_REG(irq) = 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int irqflags[PNX833X_PIC_NUM_IRQ]; /* initialized by zeroes */ | ||
156 | #define IRQFLAG_STARTED 1 | ||
157 | #define IRQFLAG_DISABLED 2 | ||
158 | |||
159 | static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock); | 155 | static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock); |
160 | 156 | ||
161 | static unsigned int pnx833x_startup_pic_irq(unsigned int irq) | 157 | static unsigned int pnx833x_startup_pic_irq(unsigned int irq) |
@@ -164,108 +160,54 @@ static unsigned int pnx833x_startup_pic_irq(unsigned int irq) | |||
164 | unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; | 160 | unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; |
165 | 161 | ||
166 | raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); | 162 | raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); |
167 | |||
168 | irqflags[pic_irq] = IRQFLAG_STARTED; /* started, not disabled */ | ||
169 | pnx833x_hard_enable_pic_irq(pic_irq); | 163 | pnx833x_hard_enable_pic_irq(pic_irq); |
170 | |||
171 | raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); | 164 | raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); |
172 | return 0; | 165 | return 0; |
173 | } | 166 | } |
174 | 167 | ||
175 | static void pnx833x_shutdown_pic_irq(unsigned int irq) | 168 | static void pnx833x_enable_pic_irq(struct irq_data *d) |
176 | { | ||
177 | unsigned long flags; | ||
178 | unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; | ||
179 | |||
180 | raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); | ||
181 | |||
182 | irqflags[pic_irq] = 0; /* not started */ | ||
183 | pnx833x_hard_disable_pic_irq(pic_irq); | ||
184 | |||
185 | raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); | ||
186 | } | ||
187 | |||
188 | static void pnx833x_enable_pic_irq(unsigned int irq) | ||
189 | { | 169 | { |
190 | unsigned long flags; | 170 | unsigned long flags; |
191 | unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; | 171 | unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE; |
192 | 172 | ||
193 | raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); | 173 | raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); |
194 | 174 | pnx833x_hard_enable_pic_irq(pic_irq); | |
195 | irqflags[pic_irq] &= ~IRQFLAG_DISABLED; | ||
196 | if (irqflags[pic_irq] == IRQFLAG_STARTED) | ||
197 | pnx833x_hard_enable_pic_irq(pic_irq); | ||
198 | |||
199 | raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); | 175 | raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); |
200 | } | 176 | } |
201 | 177 | ||
202 | static void pnx833x_disable_pic_irq(unsigned int irq) | 178 | static void pnx833x_disable_pic_irq(struct irq_data *d) |
203 | { | 179 | { |
204 | unsigned long flags; | 180 | unsigned long flags; |
205 | unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; | 181 | unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE; |
206 | 182 | ||
207 | raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); | 183 | raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); |
208 | |||
209 | irqflags[pic_irq] |= IRQFLAG_DISABLED; | ||
210 | pnx833x_hard_disable_pic_irq(pic_irq); | 184 | pnx833x_hard_disable_pic_irq(pic_irq); |
211 | |||
212 | raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); | 185 | raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); |
213 | } | 186 | } |
214 | 187 | ||
215 | static void pnx833x_ack_pic_irq(unsigned int irq) | ||
216 | { | ||
217 | } | ||
218 | |||
219 | static void pnx833x_end_pic_irq(unsigned int irq) | ||
220 | { | ||
221 | } | ||
222 | |||
223 | static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock); | 188 | static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock); |
224 | 189 | ||
225 | static unsigned int pnx833x_startup_gpio_irq(unsigned int irq) | 190 | static void pnx833x_enable_gpio_irq(struct irq_data *d) |
226 | { | ||
227 | int pin = irq - PNX833X_GPIO_IRQ_BASE; | ||
228 | unsigned long flags; | ||
229 | raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); | ||
230 | pnx833x_gpio_enable_irq(pin); | ||
231 | raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static void pnx833x_enable_gpio_irq(unsigned int irq) | ||
236 | { | 191 | { |
237 | int pin = irq - PNX833X_GPIO_IRQ_BASE; | 192 | int pin = d->irq - PNX833X_GPIO_IRQ_BASE; |
238 | unsigned long flags; | 193 | unsigned long flags; |
239 | raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); | 194 | raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); |
240 | pnx833x_gpio_enable_irq(pin); | 195 | pnx833x_gpio_enable_irq(pin); |
241 | raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); | 196 | raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); |
242 | } | 197 | } |
243 | 198 | ||
244 | static void pnx833x_disable_gpio_irq(unsigned int irq) | 199 | static void pnx833x_disable_gpio_irq(struct irq_data *d) |
245 | { | 200 | { |
246 | int pin = irq - PNX833X_GPIO_IRQ_BASE; | 201 | int pin = d->irq - PNX833X_GPIO_IRQ_BASE; |
247 | unsigned long flags; | 202 | unsigned long flags; |
248 | raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); | 203 | raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); |
249 | pnx833x_gpio_disable_irq(pin); | 204 | pnx833x_gpio_disable_irq(pin); |
250 | raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); | 205 | raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); |
251 | } | 206 | } |
252 | 207 | ||
253 | static void pnx833x_ack_gpio_irq(unsigned int irq) | 208 | static int pnx833x_set_type_gpio_irq(struct irq_data *d, unsigned int flow_type) |
254 | { | ||
255 | } | ||
256 | |||
257 | static void pnx833x_end_gpio_irq(unsigned int irq) | ||
258 | { | ||
259 | int pin = irq - PNX833X_GPIO_IRQ_BASE; | ||
260 | unsigned long flags; | ||
261 | raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); | ||
262 | pnx833x_gpio_clear_irq(pin); | ||
263 | raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); | ||
264 | } | ||
265 | |||
266 | static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type) | ||
267 | { | 209 | { |
268 | int pin = irq - PNX833X_GPIO_IRQ_BASE; | 210 | int pin = d->irq - PNX833X_GPIO_IRQ_BASE; |
269 | int gpio_mode; | 211 | int gpio_mode; |
270 | 212 | ||
271 | switch (flow_type) { | 213 | switch (flow_type) { |
@@ -296,23 +238,15 @@ static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type) | |||
296 | 238 | ||
297 | static struct irq_chip pnx833x_pic_irq_type = { | 239 | static struct irq_chip pnx833x_pic_irq_type = { |
298 | .name = "PNX-PIC", | 240 | .name = "PNX-PIC", |
299 | .startup = pnx833x_startup_pic_irq, | 241 | .irq_enable = pnx833x_enable_pic_irq, |
300 | .shutdown = pnx833x_shutdown_pic_irq, | 242 | .irq_disable = pnx833x_disable_pic_irq, |
301 | .enable = pnx833x_enable_pic_irq, | ||
302 | .disable = pnx833x_disable_pic_irq, | ||
303 | .ack = pnx833x_ack_pic_irq, | ||
304 | .end = pnx833x_end_pic_irq | ||
305 | }; | 243 | }; |
306 | 244 | ||
307 | static struct irq_chip pnx833x_gpio_irq_type = { | 245 | static struct irq_chip pnx833x_gpio_irq_type = { |
308 | .name = "PNX-GPIO", | 246 | .name = "PNX-GPIO", |
309 | .startup = pnx833x_startup_gpio_irq, | 247 | .irq_enable = pnx833x_enable_gpio_irq, |
310 | .shutdown = pnx833x_disable_gpio_irq, | 248 | .irq_disable = pnx833x_disable_gpio_irq, |
311 | .enable = pnx833x_enable_gpio_irq, | 249 | .irq_set_type = pnx833x_set_type_gpio_irq, |
312 | .disable = pnx833x_disable_gpio_irq, | ||
313 | .ack = pnx833x_ack_gpio_irq, | ||
314 | .end = pnx833x_end_gpio_irq, | ||
315 | .set_type = pnx833x_set_type_gpio_irq | ||
316 | }; | 250 | }; |
317 | 251 | ||
318 | void __init arch_init_irq(void) | 252 | void __init arch_init_irq(void) |
diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c index cfed5051dc6d..dbdc35c3531d 100644 --- a/arch/mips/pnx8550/common/int.c +++ b/arch/mips/pnx8550/common/int.c | |||
@@ -114,8 +114,10 @@ static inline void unmask_gic_int(unsigned int irq_nr) | |||
114 | PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr]; | 114 | PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr]; |
115 | } | 115 | } |
116 | 116 | ||
117 | static inline void mask_irq(unsigned int irq_nr) | 117 | static inline void mask_irq(struct irq_data *d) |
118 | { | 118 | { |
119 | unsigned int irq_nr = d->irq; | ||
120 | |||
119 | if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { | 121 | if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { |
120 | modify_cp0_intmask(1 << irq_nr, 0); | 122 | modify_cp0_intmask(1 << irq_nr, 0); |
121 | } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && | 123 | } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && |
@@ -129,8 +131,10 @@ static inline void mask_irq(unsigned int irq_nr) | |||
129 | } | 131 | } |
130 | } | 132 | } |
131 | 133 | ||
132 | static inline void unmask_irq(unsigned int irq_nr) | 134 | static inline void unmask_irq(struct irq_data *d) |
133 | { | 135 | { |
136 | unsigned int irq_nr = d->irq; | ||
137 | |||
134 | if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { | 138 | if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { |
135 | modify_cp0_intmask(0, 1 << irq_nr); | 139 | modify_cp0_intmask(0, 1 << irq_nr); |
136 | } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && | 140 | } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && |
@@ -157,10 +161,8 @@ int pnx8550_set_gic_priority(int irq, int priority) | |||
157 | 161 | ||
158 | static struct irq_chip level_irq_type = { | 162 | static struct irq_chip level_irq_type = { |
159 | .name = "PNX Level IRQ", | 163 | .name = "PNX Level IRQ", |
160 | .ack = mask_irq, | 164 | .irq_mask = mask_irq, |
161 | .mask = mask_irq, | 165 | .irq_unmask = unmask_irq, |
162 | .mask_ack = mask_irq, | ||
163 | .unmask = unmask_irq, | ||
164 | }; | 166 | }; |
165 | 167 | ||
166 | static struct irqaction gic_action = { | 168 | static struct irqaction gic_action = { |
@@ -180,10 +182,8 @@ void __init arch_init_irq(void) | |||
180 | int i; | 182 | int i; |
181 | int configPR; | 183 | int configPR; |
182 | 184 | ||
183 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { | 185 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) |
184 | set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); | 186 | set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); |
185 | mask_irq(i); /* mask the irq just in case */ | ||
186 | } | ||
187 | 187 | ||
188 | /* init of GIC/IPC interrupts */ | 188 | /* init of GIC/IPC interrupts */ |
189 | /* should be done before cp0 since cp0 init enables the GIC int */ | 189 | /* should be done before cp0 since cp0 init enables the GIC int */ |
diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c index e55382434155..6f1c8ef6a719 100644 --- a/arch/mips/powertv/asic/irq_asic.c +++ b/arch/mips/powertv/asic/irq_asic.c | |||
@@ -21,9 +21,10 @@ | |||
21 | 21 | ||
22 | #include <asm/mach-powertv/asic_regs.h> | 22 | #include <asm/mach-powertv/asic_regs.h> |
23 | 23 | ||
24 | static inline void unmask_asic_irq(unsigned int irq) | 24 | static inline void unmask_asic_irq(struct irq_data *d) |
25 | { | 25 | { |
26 | unsigned long enable_bit; | 26 | unsigned long enable_bit; |
27 | unsigned int irq = d->irq; | ||
27 | 28 | ||
28 | enable_bit = (1 << (irq & 0x1f)); | 29 | enable_bit = (1 << (irq & 0x1f)); |
29 | 30 | ||
@@ -45,9 +46,10 @@ static inline void unmask_asic_irq(unsigned int irq) | |||
45 | } | 46 | } |
46 | } | 47 | } |
47 | 48 | ||
48 | static inline void mask_asic_irq(unsigned int irq) | 49 | static inline void mask_asic_irq(struct irq_data *d) |
49 | { | 50 | { |
50 | unsigned long disable_mask; | 51 | unsigned long disable_mask; |
52 | unsigned int irq = d->irq; | ||
51 | 53 | ||
52 | disable_mask = ~(1 << (irq & 0x1f)); | 54 | disable_mask = ~(1 << (irq & 0x1f)); |
53 | 55 | ||
@@ -71,11 +73,8 @@ static inline void mask_asic_irq(unsigned int irq) | |||
71 | 73 | ||
72 | static struct irq_chip asic_irq_chip = { | 74 | static struct irq_chip asic_irq_chip = { |
73 | .name = "ASIC Level", | 75 | .name = "ASIC Level", |
74 | .ack = mask_asic_irq, | 76 | .irq_mask = mask_asic_irq, |
75 | .mask = mask_asic_irq, | 77 | .irq_unmask = unmask_asic_irq, |
76 | .mask_ack = mask_asic_irq, | ||
77 | .unmask = unmask_asic_irq, | ||
78 | .eoi = unmask_asic_irq, | ||
79 | }; | 78 | }; |
80 | 79 | ||
81 | void __init asic_irq_init(void) | 80 | void __init asic_irq_init(void) |
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c index ea6cec3c1e0d..b32a768da894 100644 --- a/arch/mips/rb532/irq.c +++ b/arch/mips/rb532/irq.c | |||
@@ -111,10 +111,10 @@ static inline void ack_local_irq(unsigned int ip) | |||
111 | clear_c0_cause(ipnum); | 111 | clear_c0_cause(ipnum); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void rb532_enable_irq(unsigned int irq_nr) | 114 | static void rb532_enable_irq(struct irq_data *d) |
115 | { | 115 | { |
116 | unsigned int group, intr_bit, irq_nr = d->irq; | ||
116 | int ip = irq_nr - GROUP0_IRQ_BASE; | 117 | int ip = irq_nr - GROUP0_IRQ_BASE; |
117 | unsigned int group, intr_bit; | ||
118 | volatile unsigned int *addr; | 118 | volatile unsigned int *addr; |
119 | 119 | ||
120 | if (ip < 0) | 120 | if (ip < 0) |
@@ -132,10 +132,10 @@ static void rb532_enable_irq(unsigned int irq_nr) | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | static void rb532_disable_irq(unsigned int irq_nr) | 135 | static void rb532_disable_irq(struct irq_data *d) |
136 | { | 136 | { |
137 | unsigned int group, intr_bit, mask, irq_nr = d->irq; | ||
137 | int ip = irq_nr - GROUP0_IRQ_BASE; | 138 | int ip = irq_nr - GROUP0_IRQ_BASE; |
138 | unsigned int group, intr_bit, mask; | ||
139 | volatile unsigned int *addr; | 139 | volatile unsigned int *addr; |
140 | 140 | ||
141 | if (ip < 0) { | 141 | if (ip < 0) { |
@@ -163,18 +163,18 @@ static void rb532_disable_irq(unsigned int irq_nr) | |||
163 | } | 163 | } |
164 | } | 164 | } |
165 | 165 | ||
166 | static void rb532_mask_and_ack_irq(unsigned int irq_nr) | 166 | static void rb532_mask_and_ack_irq(struct irq_data *d) |
167 | { | 167 | { |
168 | rb532_disable_irq(irq_nr); | 168 | rb532_disable_irq(d); |
169 | ack_local_irq(group_to_ip(irq_to_group(irq_nr))); | 169 | ack_local_irq(group_to_ip(irq_to_group(d->irq))); |
170 | } | 170 | } |
171 | 171 | ||
172 | static int rb532_set_type(unsigned int irq_nr, unsigned type) | 172 | static int rb532_set_type(struct irq_data *d, unsigned type) |
173 | { | 173 | { |
174 | int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE; | 174 | int gpio = d->irq - GPIO_MAPPED_IRQ_BASE; |
175 | int group = irq_to_group(irq_nr); | 175 | int group = irq_to_group(d->irq); |
176 | 176 | ||
177 | if (group != GPIO_MAPPED_IRQ_GROUP || irq_nr > (GROUP4_IRQ_BASE + 13)) | 177 | if (group != GPIO_MAPPED_IRQ_GROUP || d->irq > (GROUP4_IRQ_BASE + 13)) |
178 | return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL; | 178 | return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL; |
179 | 179 | ||
180 | switch (type) { | 180 | switch (type) { |
@@ -193,11 +193,11 @@ static int rb532_set_type(unsigned int irq_nr, unsigned type) | |||
193 | 193 | ||
194 | static struct irq_chip rc32434_irq_type = { | 194 | static struct irq_chip rc32434_irq_type = { |
195 | .name = "RB532", | 195 | .name = "RB532", |
196 | .ack = rb532_disable_irq, | 196 | .irq_ack = rb532_disable_irq, |
197 | .mask = rb532_disable_irq, | 197 | .irq_mask = rb532_disable_irq, |
198 | .mask_ack = rb532_mask_and_ack_irq, | 198 | .irq_mask_ack = rb532_mask_and_ack_irq, |
199 | .unmask = rb532_enable_irq, | 199 | .irq_unmask = rb532_enable_irq, |
200 | .set_type = rb532_set_type, | 200 | .irq_set_type = rb532_set_type, |
201 | }; | 201 | }; |
202 | 202 | ||
203 | void __init arch_init_irq(void) | 203 | void __init arch_init_irq(void) |
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 383f11d7f442..e6e64750e90a 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c | |||
@@ -31,88 +31,80 @@ static char lc3msk_to_irqnr[256]; | |||
31 | 31 | ||
32 | extern int ip22_eisa_init(void); | 32 | extern int ip22_eisa_init(void); |
33 | 33 | ||
34 | static void enable_local0_irq(unsigned int irq) | 34 | static void enable_local0_irq(struct irq_data *d) |
35 | { | 35 | { |
36 | /* don't allow mappable interrupt to be enabled from setup_irq, | 36 | /* don't allow mappable interrupt to be enabled from setup_irq, |
37 | * we have our own way to do so */ | 37 | * we have our own way to do so */ |
38 | if (irq != SGI_MAP_0_IRQ) | 38 | if (d->irq != SGI_MAP_0_IRQ) |
39 | sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); | 39 | sgint->imask0 |= (1 << (d->irq - SGINT_LOCAL0)); |
40 | } | 40 | } |
41 | 41 | ||
42 | static void disable_local0_irq(unsigned int irq) | 42 | static void disable_local0_irq(struct irq_data *d) |
43 | { | 43 | { |
44 | sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); | 44 | sgint->imask0 &= ~(1 << (d->irq - SGINT_LOCAL0)); |
45 | } | 45 | } |
46 | 46 | ||
47 | static struct irq_chip ip22_local0_irq_type = { | 47 | static struct irq_chip ip22_local0_irq_type = { |
48 | .name = "IP22 local 0", | 48 | .name = "IP22 local 0", |
49 | .ack = disable_local0_irq, | 49 | .irq_mask = disable_local0_irq, |
50 | .mask = disable_local0_irq, | 50 | .irq_unmask = enable_local0_irq, |
51 | .mask_ack = disable_local0_irq, | ||
52 | .unmask = enable_local0_irq, | ||
53 | }; | 51 | }; |
54 | 52 | ||
55 | static void enable_local1_irq(unsigned int irq) | 53 | static void enable_local1_irq(struct irq_data *d) |
56 | { | 54 | { |
57 | /* don't allow mappable interrupt to be enabled from setup_irq, | 55 | /* don't allow mappable interrupt to be enabled from setup_irq, |
58 | * we have our own way to do so */ | 56 | * we have our own way to do so */ |
59 | if (irq != SGI_MAP_1_IRQ) | 57 | if (d->irq != SGI_MAP_1_IRQ) |
60 | sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); | 58 | sgint->imask1 |= (1 << (d->irq - SGINT_LOCAL1)); |
61 | } | 59 | } |
62 | 60 | ||
63 | static void disable_local1_irq(unsigned int irq) | 61 | static void disable_local1_irq(struct irq_data *d) |
64 | { | 62 | { |
65 | sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); | 63 | sgint->imask1 &= ~(1 << (d->irq - SGINT_LOCAL1)); |
66 | } | 64 | } |
67 | 65 | ||
68 | static struct irq_chip ip22_local1_irq_type = { | 66 | static struct irq_chip ip22_local1_irq_type = { |
69 | .name = "IP22 local 1", | 67 | .name = "IP22 local 1", |
70 | .ack = disable_local1_irq, | 68 | .irq_mask = disable_local1_irq, |
71 | .mask = disable_local1_irq, | 69 | .irq_unmask = enable_local1_irq, |
72 | .mask_ack = disable_local1_irq, | ||
73 | .unmask = enable_local1_irq, | ||
74 | }; | 70 | }; |
75 | 71 | ||
76 | static void enable_local2_irq(unsigned int irq) | 72 | static void enable_local2_irq(struct irq_data *d) |
77 | { | 73 | { |
78 | sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); | 74 | sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); |
79 | sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); | 75 | sgint->cmeimask0 |= (1 << (d->irq - SGINT_LOCAL2)); |
80 | } | 76 | } |
81 | 77 | ||
82 | static void disable_local2_irq(unsigned int irq) | 78 | static void disable_local2_irq(struct irq_data *d) |
83 | { | 79 | { |
84 | sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); | 80 | sgint->cmeimask0 &= ~(1 << (d->irq - SGINT_LOCAL2)); |
85 | if (!sgint->cmeimask0) | 81 | if (!sgint->cmeimask0) |
86 | sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); | 82 | sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); |
87 | } | 83 | } |
88 | 84 | ||
89 | static struct irq_chip ip22_local2_irq_type = { | 85 | static struct irq_chip ip22_local2_irq_type = { |
90 | .name = "IP22 local 2", | 86 | .name = "IP22 local 2", |
91 | .ack = disable_local2_irq, | 87 | .irq_mask = disable_local2_irq, |
92 | .mask = disable_local2_irq, | 88 | .irq_unmask = enable_local2_irq, |
93 | .mask_ack = disable_local2_irq, | ||
94 | .unmask = enable_local2_irq, | ||
95 | }; | 89 | }; |
96 | 90 | ||
97 | static void enable_local3_irq(unsigned int irq) | 91 | static void enable_local3_irq(struct irq_data *d) |
98 | { | 92 | { |
99 | sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); | 93 | sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); |
100 | sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); | 94 | sgint->cmeimask1 |= (1 << (d->irq - SGINT_LOCAL3)); |
101 | } | 95 | } |
102 | 96 | ||
103 | static void disable_local3_irq(unsigned int irq) | 97 | static void disable_local3_irq(struct irq_data *d) |
104 | { | 98 | { |
105 | sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); | 99 | sgint->cmeimask1 &= ~(1 << (d->irq - SGINT_LOCAL3)); |
106 | if (!sgint->cmeimask1) | 100 | if (!sgint->cmeimask1) |
107 | sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); | 101 | sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); |
108 | } | 102 | } |
109 | 103 | ||
110 | static struct irq_chip ip22_local3_irq_type = { | 104 | static struct irq_chip ip22_local3_irq_type = { |
111 | .name = "IP22 local 3", | 105 | .name = "IP22 local 3", |
112 | .ack = disable_local3_irq, | 106 | .irq_mask = disable_local3_irq, |
113 | .mask = disable_local3_irq, | 107 | .irq_unmask = enable_local3_irq, |
114 | .mask_ack = disable_local3_irq, | ||
115 | .unmask = enable_local3_irq, | ||
116 | }; | 108 | }; |
117 | 109 | ||
118 | static void indy_local0_irqdispatch(void) | 110 | static void indy_local0_irqdispatch(void) |
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 6a123ea72de5..f2d09d7700dd 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
@@ -240,7 +240,7 @@ static int intr_disconnect_level(int cpu, int bit) | |||
240 | } | 240 | } |
241 | 241 | ||
242 | /* Startup one of the (PCI ...) IRQs routes over a bridge. */ | 242 | /* Startup one of the (PCI ...) IRQs routes over a bridge. */ |
243 | static unsigned int startup_bridge_irq(unsigned int irq) | 243 | static unsigned int startup_bridge_irq(struct irq_data *d) |
244 | { | 244 | { |
245 | struct bridge_controller *bc; | 245 | struct bridge_controller *bc; |
246 | bridgereg_t device; | 246 | bridgereg_t device; |
@@ -248,16 +248,16 @@ static unsigned int startup_bridge_irq(unsigned int irq) | |||
248 | int pin, swlevel; | 248 | int pin, swlevel; |
249 | cpuid_t cpu; | 249 | cpuid_t cpu; |
250 | 250 | ||
251 | pin = SLOT_FROM_PCI_IRQ(irq); | 251 | pin = SLOT_FROM_PCI_IRQ(d->irq); |
252 | bc = IRQ_TO_BRIDGE(irq); | 252 | bc = IRQ_TO_BRIDGE(d->irq); |
253 | bridge = bc->base; | 253 | bridge = bc->base; |
254 | 254 | ||
255 | pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin); | 255 | pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin); |
256 | /* | 256 | /* |
257 | * "map" irq to a swlevel greater than 6 since the first 6 bits | 257 | * "map" irq to a swlevel greater than 6 since the first 6 bits |
258 | * of INT_PEND0 are taken | 258 | * of INT_PEND0 are taken |
259 | */ | 259 | */ |
260 | swlevel = find_level(&cpu, irq); | 260 | swlevel = find_level(&cpu, d->irq); |
261 | bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); | 261 | bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); |
262 | bridge->b_int_enable |= (1 << pin); | 262 | bridge->b_int_enable |= (1 << pin); |
263 | bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ | 263 | bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ |
@@ -288,53 +288,51 @@ static unsigned int startup_bridge_irq(unsigned int irq) | |||
288 | } | 288 | } |
289 | 289 | ||
290 | /* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ | 290 | /* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ |
291 | static void shutdown_bridge_irq(unsigned int irq) | 291 | static void shutdown_bridge_irq(struct irq_data *d) |
292 | { | 292 | { |
293 | struct bridge_controller *bc = IRQ_TO_BRIDGE(irq); | 293 | struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq); |
294 | bridge_t *bridge = bc->base; | 294 | bridge_t *bridge = bc->base; |
295 | int pin, swlevel; | 295 | int pin, swlevel; |
296 | cpuid_t cpu; | 296 | cpuid_t cpu; |
297 | 297 | ||
298 | pr_debug("bridge_shutdown: irq 0x%x\n", irq); | 298 | pr_debug("bridge_shutdown: irq 0x%x\n", d->irq); |
299 | pin = SLOT_FROM_PCI_IRQ(irq); | 299 | pin = SLOT_FROM_PCI_IRQ(d->irq); |
300 | 300 | ||
301 | /* | 301 | /* |
302 | * map irq to a swlevel greater than 6 since the first 6 bits | 302 | * map irq to a swlevel greater than 6 since the first 6 bits |
303 | * of INT_PEND0 are taken | 303 | * of INT_PEND0 are taken |
304 | */ | 304 | */ |
305 | swlevel = find_level(&cpu, irq); | 305 | swlevel = find_level(&cpu, d->irq); |
306 | intr_disconnect_level(cpu, swlevel); | 306 | intr_disconnect_level(cpu, swlevel); |
307 | 307 | ||
308 | bridge->b_int_enable &= ~(1 << pin); | 308 | bridge->b_int_enable &= ~(1 << pin); |
309 | bridge->b_wid_tflush; | 309 | bridge->b_wid_tflush; |
310 | } | 310 | } |
311 | 311 | ||
312 | static inline void enable_bridge_irq(unsigned int irq) | 312 | static inline void enable_bridge_irq(struct irq_data *d) |
313 | { | 313 | { |
314 | cpuid_t cpu; | 314 | cpuid_t cpu; |
315 | int swlevel; | 315 | int swlevel; |
316 | 316 | ||
317 | swlevel = find_level(&cpu, irq); /* Criminal offence */ | 317 | swlevel = find_level(&cpu, d->irq); /* Criminal offence */ |
318 | intr_connect_level(cpu, swlevel); | 318 | intr_connect_level(cpu, swlevel); |
319 | } | 319 | } |
320 | 320 | ||
321 | static inline void disable_bridge_irq(unsigned int irq) | 321 | static inline void disable_bridge_irq(struct irq_data *d) |
322 | { | 322 | { |
323 | cpuid_t cpu; | 323 | cpuid_t cpu; |
324 | int swlevel; | 324 | int swlevel; |
325 | 325 | ||
326 | swlevel = find_level(&cpu, irq); /* Criminal offence */ | 326 | swlevel = find_level(&cpu, d->irq); /* Criminal offence */ |
327 | intr_disconnect_level(cpu, swlevel); | 327 | intr_disconnect_level(cpu, swlevel); |
328 | } | 328 | } |
329 | 329 | ||
330 | static struct irq_chip bridge_irq_type = { | 330 | static struct irq_chip bridge_irq_type = { |
331 | .name = "bridge", | 331 | .name = "bridge", |
332 | .startup = startup_bridge_irq, | 332 | .irq_startup = startup_bridge_irq, |
333 | .shutdown = shutdown_bridge_irq, | 333 | .irq_shutdown = shutdown_bridge_irq, |
334 | .ack = disable_bridge_irq, | 334 | .irq_mask = disable_bridge_irq, |
335 | .mask = disable_bridge_irq, | 335 | .irq_unmask = enable_bridge_irq, |
336 | .mask_ack = disable_bridge_irq, | ||
337 | .unmask = enable_bridge_irq, | ||
338 | }; | 336 | }; |
339 | 337 | ||
340 | void __devinit register_bridge_irq(unsigned int irq) | 338 | void __devinit register_bridge_irq(unsigned int irq) |
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index d6802d6d1f82..c01f558a2a09 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c | |||
@@ -36,21 +36,18 @@ | |||
36 | #include <asm/sn/sn0/hubio.h> | 36 | #include <asm/sn/sn0/hubio.h> |
37 | #include <asm/pci/bridge.h> | 37 | #include <asm/pci/bridge.h> |
38 | 38 | ||
39 | static void enable_rt_irq(unsigned int irq) | 39 | static void enable_rt_irq(struct irq_data *d) |
40 | { | 40 | { |
41 | } | 41 | } |
42 | 42 | ||
43 | static void disable_rt_irq(unsigned int irq) | 43 | static void disable_rt_irq(struct irq_data *d) |
44 | { | 44 | { |
45 | } | 45 | } |
46 | 46 | ||
47 | static struct irq_chip rt_irq_type = { | 47 | static struct irq_chip rt_irq_type = { |
48 | .name = "SN HUB RT timer", | 48 | .name = "SN HUB RT timer", |
49 | .ack = disable_rt_irq, | 49 | .irq_mask = disable_rt_irq, |
50 | .mask = disable_rt_irq, | 50 | .irq_unmask = enable_rt_irq, |
51 | .mask_ack = disable_rt_irq, | ||
52 | .unmask = enable_rt_irq, | ||
53 | .eoi = enable_rt_irq, | ||
54 | }; | 51 | }; |
55 | 52 | ||
56 | static int rt_next_event(unsigned long delta, struct clock_event_device *evt) | 53 | static int rt_next_event(unsigned long delta, struct clock_event_device *evt) |
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index eb40824b172a..e0a3ce4a8d48 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -130,70 +130,48 @@ static struct irqaction cpuerr_irq = { | |||
130 | 130 | ||
131 | static uint64_t crime_mask; | 131 | static uint64_t crime_mask; |
132 | 132 | ||
133 | static inline void crime_enable_irq(unsigned int irq) | 133 | static inline void crime_enable_irq(struct irq_data *d) |
134 | { | 134 | { |
135 | unsigned int bit = irq - CRIME_IRQ_BASE; | 135 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
136 | 136 | ||
137 | crime_mask |= 1 << bit; | 137 | crime_mask |= 1 << bit; |
138 | crime->imask = crime_mask; | 138 | crime->imask = crime_mask; |
139 | } | 139 | } |
140 | 140 | ||
141 | static inline void crime_disable_irq(unsigned int irq) | 141 | static inline void crime_disable_irq(struct irq_data *d) |
142 | { | 142 | { |
143 | unsigned int bit = irq - CRIME_IRQ_BASE; | 143 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
144 | 144 | ||
145 | crime_mask &= ~(1 << bit); | 145 | crime_mask &= ~(1 << bit); |
146 | crime->imask = crime_mask; | 146 | crime->imask = crime_mask; |
147 | flush_crime_bus(); | 147 | flush_crime_bus(); |
148 | } | 148 | } |
149 | 149 | ||
150 | static void crime_level_mask_and_ack_irq(unsigned int irq) | ||
151 | { | ||
152 | crime_disable_irq(irq); | ||
153 | } | ||
154 | |||
155 | static void crime_level_end_irq(unsigned int irq) | ||
156 | { | ||
157 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
158 | crime_enable_irq(irq); | ||
159 | } | ||
160 | |||
161 | static struct irq_chip crime_level_interrupt = { | 150 | static struct irq_chip crime_level_interrupt = { |
162 | .name = "IP32 CRIME", | 151 | .name = "IP32 CRIME", |
163 | .ack = crime_level_mask_and_ack_irq, | 152 | .irq_mask = crime_disable_irq, |
164 | .mask = crime_disable_irq, | 153 | .irq_unmask = crime_enable_irq, |
165 | .mask_ack = crime_level_mask_and_ack_irq, | ||
166 | .unmask = crime_enable_irq, | ||
167 | .end = crime_level_end_irq, | ||
168 | }; | 154 | }; |
169 | 155 | ||
170 | static void crime_edge_mask_and_ack_irq(unsigned int irq) | 156 | static void crime_edge_mask_and_ack_irq(struct irq_data *d) |
171 | { | 157 | { |
172 | unsigned int bit = irq - CRIME_IRQ_BASE; | 158 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
173 | uint64_t crime_int; | 159 | uint64_t crime_int; |
174 | 160 | ||
175 | /* Edge triggered interrupts must be cleared. */ | 161 | /* Edge triggered interrupts must be cleared. */ |
176 | |||
177 | crime_int = crime->hard_int; | 162 | crime_int = crime->hard_int; |
178 | crime_int &= ~(1 << bit); | 163 | crime_int &= ~(1 << bit); |
179 | crime->hard_int = crime_int; | 164 | crime->hard_int = crime_int; |
180 | 165 | ||
181 | crime_disable_irq(irq); | 166 | crime_disable_irq(d); |
182 | } | ||
183 | |||
184 | static void crime_edge_end_irq(unsigned int irq) | ||
185 | { | ||
186 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
187 | crime_enable_irq(irq); | ||
188 | } | 167 | } |
189 | 168 | ||
190 | static struct irq_chip crime_edge_interrupt = { | 169 | static struct irq_chip crime_edge_interrupt = { |
191 | .name = "IP32 CRIME", | 170 | .name = "IP32 CRIME", |
192 | .ack = crime_edge_mask_and_ack_irq, | 171 | .irq_ack = crime_edge_mask_and_ack_irq, |
193 | .mask = crime_disable_irq, | 172 | .irq_mask = crime_disable_irq, |
194 | .mask_ack = crime_edge_mask_and_ack_irq, | 173 | .irq_mask_ack = crime_edge_mask_and_ack_irq, |
195 | .unmask = crime_enable_irq, | 174 | .irq_unmask = crime_enable_irq, |
196 | .end = crime_edge_end_irq, | ||
197 | }; | 175 | }; |
198 | 176 | ||
199 | /* | 177 | /* |
@@ -204,37 +182,28 @@ static struct irq_chip crime_edge_interrupt = { | |||
204 | 182 | ||
205 | static unsigned long macepci_mask; | 183 | static unsigned long macepci_mask; |
206 | 184 | ||
207 | static void enable_macepci_irq(unsigned int irq) | 185 | static void enable_macepci_irq(struct irq_data *d) |
208 | { | 186 | { |
209 | macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ); | 187 | macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ); |
210 | mace->pci.control = macepci_mask; | 188 | mace->pci.control = macepci_mask; |
211 | crime_mask |= 1 << (irq - CRIME_IRQ_BASE); | 189 | crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE); |
212 | crime->imask = crime_mask; | 190 | crime->imask = crime_mask; |
213 | } | 191 | } |
214 | 192 | ||
215 | static void disable_macepci_irq(unsigned int irq) | 193 | static void disable_macepci_irq(struct irq_data *d) |
216 | { | 194 | { |
217 | crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE)); | 195 | crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE)); |
218 | crime->imask = crime_mask; | 196 | crime->imask = crime_mask; |
219 | flush_crime_bus(); | 197 | flush_crime_bus(); |
220 | macepci_mask &= ~MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ); | 198 | macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ); |
221 | mace->pci.control = macepci_mask; | 199 | mace->pci.control = macepci_mask; |
222 | flush_mace_bus(); | 200 | flush_mace_bus(); |
223 | } | 201 | } |
224 | 202 | ||
225 | static void end_macepci_irq(unsigned int irq) | ||
226 | { | ||
227 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
228 | enable_macepci_irq(irq); | ||
229 | } | ||
230 | |||
231 | static struct irq_chip ip32_macepci_interrupt = { | 203 | static struct irq_chip ip32_macepci_interrupt = { |
232 | .name = "IP32 MACE PCI", | 204 | .name = "IP32 MACE PCI", |
233 | .ack = disable_macepci_irq, | 205 | .irq_mask = disable_macepci_irq, |
234 | .mask = disable_macepci_irq, | 206 | .irq_unmask = enable_macepci_irq, |
235 | .mask_ack = disable_macepci_irq, | ||
236 | .unmask = enable_macepci_irq, | ||
237 | .end = end_macepci_irq, | ||
238 | }; | 207 | }; |
239 | 208 | ||
240 | /* This is used for MACE ISA interrupts. That means bits 4-6 in the | 209 | /* This is used for MACE ISA interrupts. That means bits 4-6 in the |
@@ -276,13 +245,13 @@ static struct irq_chip ip32_macepci_interrupt = { | |||
276 | 245 | ||
277 | static unsigned long maceisa_mask; | 246 | static unsigned long maceisa_mask; |
278 | 247 | ||
279 | static void enable_maceisa_irq(unsigned int irq) | 248 | static void enable_maceisa_irq(struct irq_data *d) |
280 | { | 249 | { |
281 | unsigned int crime_int = 0; | 250 | unsigned int crime_int = 0; |
282 | 251 | ||
283 | pr_debug("maceisa enable: %u\n", irq); | 252 | pr_debug("maceisa enable: %u\n", d->irq); |
284 | 253 | ||
285 | switch (irq) { | 254 | switch (d->irq) { |
286 | case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: | 255 | case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: |
287 | crime_int = MACE_AUDIO_INT; | 256 | crime_int = MACE_AUDIO_INT; |
288 | break; | 257 | break; |
@@ -296,15 +265,15 @@ static void enable_maceisa_irq(unsigned int irq) | |||
296 | pr_debug("crime_int %08x enabled\n", crime_int); | 265 | pr_debug("crime_int %08x enabled\n", crime_int); |
297 | crime_mask |= crime_int; | 266 | crime_mask |= crime_int; |
298 | crime->imask = crime_mask; | 267 | crime->imask = crime_mask; |
299 | maceisa_mask |= 1 << (irq - MACEISA_AUDIO_SW_IRQ); | 268 | maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ); |
300 | mace->perif.ctrl.imask = maceisa_mask; | 269 | mace->perif.ctrl.imask = maceisa_mask; |
301 | } | 270 | } |
302 | 271 | ||
303 | static void disable_maceisa_irq(unsigned int irq) | 272 | static void disable_maceisa_irq(struct irq_data *d) |
304 | { | 273 | { |
305 | unsigned int crime_int = 0; | 274 | unsigned int crime_int = 0; |
306 | 275 | ||
307 | maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); | 276 | maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ)); |
308 | if (!(maceisa_mask & MACEISA_AUDIO_INT)) | 277 | if (!(maceisa_mask & MACEISA_AUDIO_INT)) |
309 | crime_int |= MACE_AUDIO_INT; | 278 | crime_int |= MACE_AUDIO_INT; |
310 | if (!(maceisa_mask & MACEISA_MISC_INT)) | 279 | if (!(maceisa_mask & MACEISA_MISC_INT)) |
@@ -318,76 +287,57 @@ static void disable_maceisa_irq(unsigned int irq) | |||
318 | flush_mace_bus(); | 287 | flush_mace_bus(); |
319 | } | 288 | } |
320 | 289 | ||
321 | static void mask_and_ack_maceisa_irq(unsigned int irq) | 290 | static void mask_and_ack_maceisa_irq(struct irq_data *d) |
322 | { | 291 | { |
323 | unsigned long mace_int; | 292 | unsigned long mace_int; |
324 | 293 | ||
325 | /* edge triggered */ | 294 | /* edge triggered */ |
326 | mace_int = mace->perif.ctrl.istat; | 295 | mace_int = mace->perif.ctrl.istat; |
327 | mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); | 296 | mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ)); |
328 | mace->perif.ctrl.istat = mace_int; | 297 | mace->perif.ctrl.istat = mace_int; |
329 | 298 | ||
330 | disable_maceisa_irq(irq); | 299 | disable_maceisa_irq(d); |
331 | } | ||
332 | |||
333 | static void end_maceisa_irq(unsigned irq) | ||
334 | { | ||
335 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
336 | enable_maceisa_irq(irq); | ||
337 | } | 300 | } |
338 | 301 | ||
339 | static struct irq_chip ip32_maceisa_level_interrupt = { | 302 | static struct irq_chip ip32_maceisa_level_interrupt = { |
340 | .name = "IP32 MACE ISA", | 303 | .name = "IP32 MACE ISA", |
341 | .ack = disable_maceisa_irq, | 304 | .irq_mask = disable_maceisa_irq, |
342 | .mask = disable_maceisa_irq, | 305 | .irq_unmask = enable_maceisa_irq, |
343 | .mask_ack = disable_maceisa_irq, | ||
344 | .unmask = enable_maceisa_irq, | ||
345 | .end = end_maceisa_irq, | ||
346 | }; | 306 | }; |
347 | 307 | ||
348 | static struct irq_chip ip32_maceisa_edge_interrupt = { | 308 | static struct irq_chip ip32_maceisa_edge_interrupt = { |
349 | .name = "IP32 MACE ISA", | 309 | .name = "IP32 MACE ISA", |
350 | .ack = mask_and_ack_maceisa_irq, | 310 | .irq_ack = mask_and_ack_maceisa_irq, |
351 | .mask = disable_maceisa_irq, | 311 | .irq_mask = disable_maceisa_irq, |
352 | .mask_ack = mask_and_ack_maceisa_irq, | 312 | .irq_mask_ack = mask_and_ack_maceisa_irq, |
353 | .unmask = enable_maceisa_irq, | 313 | .irq_unmask = enable_maceisa_irq, |
354 | .end = end_maceisa_irq, | ||
355 | }; | 314 | }; |
356 | 315 | ||
357 | /* This is used for regular non-ISA, non-PCI MACE interrupts. That means | 316 | /* This is used for regular non-ISA, non-PCI MACE interrupts. That means |
358 | * bits 0-3 and 7 in the CRIME register. | 317 | * bits 0-3 and 7 in the CRIME register. |
359 | */ | 318 | */ |
360 | 319 | ||
361 | static void enable_mace_irq(unsigned int irq) | 320 | static void enable_mace_irq(struct irq_data *d) |
362 | { | 321 | { |
363 | unsigned int bit = irq - CRIME_IRQ_BASE; | 322 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
364 | 323 | ||
365 | crime_mask |= (1 << bit); | 324 | crime_mask |= (1 << bit); |
366 | crime->imask = crime_mask; | 325 | crime->imask = crime_mask; |
367 | } | 326 | } |
368 | 327 | ||
369 | static void disable_mace_irq(unsigned int irq) | 328 | static void disable_mace_irq(struct irq_data *d) |
370 | { | 329 | { |
371 | unsigned int bit = irq - CRIME_IRQ_BASE; | 330 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
372 | 331 | ||
373 | crime_mask &= ~(1 << bit); | 332 | crime_mask &= ~(1 << bit); |
374 | crime->imask = crime_mask; | 333 | crime->imask = crime_mask; |
375 | flush_crime_bus(); | 334 | flush_crime_bus(); |
376 | } | 335 | } |
377 | 336 | ||
378 | static void end_mace_irq(unsigned int irq) | ||
379 | { | ||
380 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
381 | enable_mace_irq(irq); | ||
382 | } | ||
383 | |||
384 | static struct irq_chip ip32_mace_interrupt = { | 337 | static struct irq_chip ip32_mace_interrupt = { |
385 | .name = "IP32 MACE", | 338 | .name = "IP32 MACE", |
386 | .ack = disable_mace_irq, | 339 | .irq_mask = disable_mace_irq, |
387 | .mask = disable_mace_irq, | 340 | .irq_unmask = enable_mace_irq, |
388 | .mask_ack = disable_mace_irq, | ||
389 | .unmask = enable_mace_irq, | ||
390 | .end = end_mace_irq, | ||
391 | }; | 341 | }; |
392 | 342 | ||
393 | static void ip32_unknown_interrupt(void) | 343 | static void ip32_unknown_interrupt(void) |
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 044bbe462c2c..89e8188a4665 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c | |||
@@ -44,31 +44,10 @@ | |||
44 | * for interrupt lines | 44 | * for interrupt lines |
45 | */ | 45 | */ |
46 | 46 | ||
47 | |||
48 | static void end_bcm1480_irq(unsigned int irq); | ||
49 | static void enable_bcm1480_irq(unsigned int irq); | ||
50 | static void disable_bcm1480_irq(unsigned int irq); | ||
51 | static void ack_bcm1480_irq(unsigned int irq); | ||
52 | #ifdef CONFIG_SMP | ||
53 | static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask); | ||
54 | #endif | ||
55 | |||
56 | #ifdef CONFIG_PCI | 47 | #ifdef CONFIG_PCI |
57 | extern unsigned long ht_eoi_space; | 48 | extern unsigned long ht_eoi_space; |
58 | #endif | 49 | #endif |
59 | 50 | ||
60 | static struct irq_chip bcm1480_irq_type = { | ||
61 | .name = "BCM1480-IMR", | ||
62 | .ack = ack_bcm1480_irq, | ||
63 | .mask = disable_bcm1480_irq, | ||
64 | .mask_ack = ack_bcm1480_irq, | ||
65 | .unmask = enable_bcm1480_irq, | ||
66 | .end = end_bcm1480_irq, | ||
67 | #ifdef CONFIG_SMP | ||
68 | .set_affinity = bcm1480_set_affinity | ||
69 | #endif | ||
70 | }; | ||
71 | |||
72 | /* Store the CPU id (not the logical number) */ | 51 | /* Store the CPU id (not the logical number) */ |
73 | int bcm1480_irq_owner[BCM1480_NR_IRQS]; | 52 | int bcm1480_irq_owner[BCM1480_NR_IRQS]; |
74 | 53 | ||
@@ -109,12 +88,13 @@ void bcm1480_unmask_irq(int cpu, int irq) | |||
109 | } | 88 | } |
110 | 89 | ||
111 | #ifdef CONFIG_SMP | 90 | #ifdef CONFIG_SMP |
112 | static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask) | 91 | static int bcm1480_set_affinity(struct irq_data *d, const struct cpumask *mask, |
92 | bool force) | ||
113 | { | 93 | { |
94 | unsigned int irq_dirty, irq = d->irq; | ||
114 | int i = 0, old_cpu, cpu, int_on, k; | 95 | int i = 0, old_cpu, cpu, int_on, k; |
115 | u64 cur_ints; | 96 | u64 cur_ints; |
116 | unsigned long flags; | 97 | unsigned long flags; |
117 | unsigned int irq_dirty; | ||
118 | 98 | ||
119 | i = cpumask_first(mask); | 99 | i = cpumask_first(mask); |
120 | 100 | ||
@@ -156,21 +136,25 @@ static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask) | |||
156 | 136 | ||
157 | /*****************************************************************************/ | 137 | /*****************************************************************************/ |
158 | 138 | ||
159 | static void disable_bcm1480_irq(unsigned int irq) | 139 | static void disable_bcm1480_irq(struct irq_data *d) |
160 | { | 140 | { |
141 | unsigned int irq = d->irq; | ||
142 | |||
161 | bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); | 143 | bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); |
162 | } | 144 | } |
163 | 145 | ||
164 | static void enable_bcm1480_irq(unsigned int irq) | 146 | static void enable_bcm1480_irq(struct irq_data *d) |
165 | { | 147 | { |
148 | unsigned int irq = d->irq; | ||
149 | |||
166 | bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); | 150 | bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); |
167 | } | 151 | } |
168 | 152 | ||
169 | 153 | ||
170 | static void ack_bcm1480_irq(unsigned int irq) | 154 | static void ack_bcm1480_irq(struct irq_data *d) |
171 | { | 155 | { |
156 | unsigned int irq_dirty, irq = d->irq; | ||
172 | u64 pending; | 157 | u64 pending; |
173 | unsigned int irq_dirty; | ||
174 | int k; | 158 | int k; |
175 | 159 | ||
176 | /* | 160 | /* |
@@ -217,14 +201,15 @@ static void ack_bcm1480_irq(unsigned int irq) | |||
217 | bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); | 201 | bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); |
218 | } | 202 | } |
219 | 203 | ||
220 | 204 | static struct irq_chip bcm1480_irq_type = { | |
221 | static void end_bcm1480_irq(unsigned int irq) | 205 | .name = "BCM1480-IMR", |
222 | { | 206 | .irq_mask_ack = ack_bcm1480_irq, |
223 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { | 207 | .irq_mask = disable_bcm1480_irq, |
224 | bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); | 208 | .irq_unmask = enable_bcm1480_irq, |
225 | } | 209 | #ifdef CONFIG_SMP |
226 | } | 210 | .irq_set_affinity = bcm1480_set_affinity |
227 | 211 | #endif | |
212 | }; | ||
228 | 213 | ||
229 | void __init init_bcm1480_irqs(void) | 214 | void __init init_bcm1480_irqs(void) |
230 | { | 215 | { |
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 12ac04a658ee..fd269ea8d8a8 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c | |||
@@ -43,31 +43,10 @@ | |||
43 | * for interrupt lines | 43 | * for interrupt lines |
44 | */ | 44 | */ |
45 | 45 | ||
46 | |||
47 | static void end_sb1250_irq(unsigned int irq); | ||
48 | static void enable_sb1250_irq(unsigned int irq); | ||
49 | static void disable_sb1250_irq(unsigned int irq); | ||
50 | static void ack_sb1250_irq(unsigned int irq); | ||
51 | #ifdef CONFIG_SMP | ||
52 | static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask); | ||
53 | #endif | ||
54 | |||
55 | #ifdef CONFIG_SIBYTE_HAS_LDT | 46 | #ifdef CONFIG_SIBYTE_HAS_LDT |
56 | extern unsigned long ldt_eoi_space; | 47 | extern unsigned long ldt_eoi_space; |
57 | #endif | 48 | #endif |
58 | 49 | ||
59 | static struct irq_chip sb1250_irq_type = { | ||
60 | .name = "SB1250-IMR", | ||
61 | .ack = ack_sb1250_irq, | ||
62 | .mask = disable_sb1250_irq, | ||
63 | .mask_ack = ack_sb1250_irq, | ||
64 | .unmask = enable_sb1250_irq, | ||
65 | .end = end_sb1250_irq, | ||
66 | #ifdef CONFIG_SMP | ||
67 | .set_affinity = sb1250_set_affinity | ||
68 | #endif | ||
69 | }; | ||
70 | |||
71 | /* Store the CPU id (not the logical number) */ | 50 | /* Store the CPU id (not the logical number) */ |
72 | int sb1250_irq_owner[SB1250_NR_IRQS]; | 51 | int sb1250_irq_owner[SB1250_NR_IRQS]; |
73 | 52 | ||
@@ -102,9 +81,11 @@ void sb1250_unmask_irq(int cpu, int irq) | |||
102 | } | 81 | } |
103 | 82 | ||
104 | #ifdef CONFIG_SMP | 83 | #ifdef CONFIG_SMP |
105 | static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask) | 84 | static int sb1250_set_affinity(struct irq_data *d, const struct cpumask *mask, |
85 | bool force) | ||
106 | { | 86 | { |
107 | int i = 0, old_cpu, cpu, int_on; | 87 | int i = 0, old_cpu, cpu, int_on; |
88 | unsigned int irq = d->irq; | ||
108 | u64 cur_ints; | 89 | u64 cur_ints; |
109 | unsigned long flags; | 90 | unsigned long flags; |
110 | 91 | ||
@@ -142,21 +123,17 @@ static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask) | |||
142 | } | 123 | } |
143 | #endif | 124 | #endif |
144 | 125 | ||
145 | /*****************************************************************************/ | 126 | static void enable_sb1250_irq(struct irq_data *d) |
146 | |||
147 | static void disable_sb1250_irq(unsigned int irq) | ||
148 | { | 127 | { |
149 | sb1250_mask_irq(sb1250_irq_owner[irq], irq); | 128 | unsigned int irq = d->irq; |
150 | } | ||
151 | 129 | ||
152 | static void enable_sb1250_irq(unsigned int irq) | ||
153 | { | ||
154 | sb1250_unmask_irq(sb1250_irq_owner[irq], irq); | 130 | sb1250_unmask_irq(sb1250_irq_owner[irq], irq); |
155 | } | 131 | } |
156 | 132 | ||
157 | 133 | ||
158 | static void ack_sb1250_irq(unsigned int irq) | 134 | static void ack_sb1250_irq(struct irq_data *d) |
159 | { | 135 | { |
136 | unsigned int irq = d->irq; | ||
160 | #ifdef CONFIG_SIBYTE_HAS_LDT | 137 | #ifdef CONFIG_SIBYTE_HAS_LDT |
161 | u64 pending; | 138 | u64 pending; |
162 | 139 | ||
@@ -199,14 +176,14 @@ static void ack_sb1250_irq(unsigned int irq) | |||
199 | sb1250_mask_irq(sb1250_irq_owner[irq], irq); | 176 | sb1250_mask_irq(sb1250_irq_owner[irq], irq); |
200 | } | 177 | } |
201 | 178 | ||
202 | 179 | static struct irq_chip sb1250_irq_type = { | |
203 | static void end_sb1250_irq(unsigned int irq) | 180 | .name = "SB1250-IMR", |
204 | { | 181 | .irq_mask_ack = ack_sb1250_irq, |
205 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { | 182 | .irq_unmask = enable_sb1250_irq, |
206 | sb1250_unmask_irq(sb1250_irq_owner[irq], irq); | 183 | #ifdef CONFIG_SMP |
207 | } | 184 | .irq_set_affinity = sb1250_set_affinity |
208 | } | 185 | #endif |
209 | 186 | }; | |
210 | 187 | ||
211 | void __init init_sb1250_irqs(void) | 188 | void __init init_sb1250_irqs(void) |
212 | { | 189 | { |
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index bbe7187879fa..72b94155778d 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c | |||
@@ -168,33 +168,22 @@ static u32 a20r_ack_hwint(void) | |||
168 | return status; | 168 | return status; |
169 | } | 169 | } |
170 | 170 | ||
171 | static inline void unmask_a20r_irq(unsigned int irq) | 171 | static inline void unmask_a20r_irq(struct irq_data *d) |
172 | { | 172 | { |
173 | set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE)); | 173 | set_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE)); |
174 | irq_enable_hazard(); | 174 | irq_enable_hazard(); |
175 | } | 175 | } |
176 | 176 | ||
177 | static inline void mask_a20r_irq(unsigned int irq) | 177 | static inline void mask_a20r_irq(struct irq_data *d) |
178 | { | 178 | { |
179 | clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE)); | 179 | clear_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE)); |
180 | irq_disable_hazard(); | 180 | irq_disable_hazard(); |
181 | } | 181 | } |
182 | 182 | ||
183 | static void end_a20r_irq(unsigned int irq) | ||
184 | { | ||
185 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { | ||
186 | a20r_ack_hwint(); | ||
187 | unmask_a20r_irq(irq); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | static struct irq_chip a20r_irq_type = { | 183 | static struct irq_chip a20r_irq_type = { |
192 | .name = "A20R", | 184 | .name = "A20R", |
193 | .ack = mask_a20r_irq, | 185 | .irq_mask = mask_a20r_irq, |
194 | .mask = mask_a20r_irq, | 186 | .irq_unmask = unmask_a20r_irq, |
195 | .mask_ack = mask_a20r_irq, | ||
196 | .unmask = unmask_a20r_irq, | ||
197 | .end = end_a20r_irq, | ||
198 | }; | 187 | }; |
199 | 188 | ||
200 | /* | 189 | /* |
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 8c92c73bc717..cfcc68abc5b2 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c | |||
@@ -194,33 +194,24 @@ static struct pci_controller sni_controller = { | |||
194 | .io_map_base = SNI_PORT_BASE | 194 | .io_map_base = SNI_PORT_BASE |
195 | }; | 195 | }; |
196 | 196 | ||
197 | static void enable_pcimt_irq(unsigned int irq) | 197 | static void enable_pcimt_irq(struct irq_data *d) |
198 | { | 198 | { |
199 | unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); | 199 | unsigned int mask = 1 << (d->irq - PCIMT_IRQ_INT2); |
200 | 200 | ||
201 | *(volatile u8 *) PCIMT_IRQSEL |= mask; | 201 | *(volatile u8 *) PCIMT_IRQSEL |= mask; |
202 | } | 202 | } |
203 | 203 | ||
204 | void disable_pcimt_irq(unsigned int irq) | 204 | void disable_pcimt_irq(struct irq_data *d) |
205 | { | 205 | { |
206 | unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); | 206 | unsigned int mask = ~(1 << (d->irq - PCIMT_IRQ_INT2)); |
207 | 207 | ||
208 | *(volatile u8 *) PCIMT_IRQSEL &= mask; | 208 | *(volatile u8 *) PCIMT_IRQSEL &= mask; |
209 | } | 209 | } |
210 | 210 | ||
211 | static void end_pcimt_irq(unsigned int irq) | ||
212 | { | ||
213 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
214 | enable_pcimt_irq(irq); | ||
215 | } | ||
216 | |||
217 | static struct irq_chip pcimt_irq_type = { | 211 | static struct irq_chip pcimt_irq_type = { |
218 | .name = "PCIMT", | 212 | .name = "PCIMT", |
219 | .ack = disable_pcimt_irq, | 213 | .irq_mask = disable_pcimt_irq, |
220 | .mask = disable_pcimt_irq, | 214 | .irq_unmask = enable_pcimt_irq, |
221 | .mask_ack = disable_pcimt_irq, | ||
222 | .unmask = enable_pcimt_irq, | ||
223 | .end = end_pcimt_irq, | ||
224 | }; | 215 | }; |
225 | 216 | ||
226 | /* | 217 | /* |
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c index dc9874553bec..0846e99a6efe 100644 --- a/arch/mips/sni/pcit.c +++ b/arch/mips/sni/pcit.c | |||
@@ -156,33 +156,24 @@ static struct pci_controller sni_pcit_controller = { | |||
156 | .io_map_base = SNI_PORT_BASE | 156 | .io_map_base = SNI_PORT_BASE |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static void enable_pcit_irq(unsigned int irq) | 159 | static void enable_pcit_irq(struct irq_data *d) |
160 | { | 160 | { |
161 | u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24); | 161 | u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24); |
162 | 162 | ||
163 | *(volatile u32 *)SNI_PCIT_INT_REG |= mask; | 163 | *(volatile u32 *)SNI_PCIT_INT_REG |= mask; |
164 | } | 164 | } |
165 | 165 | ||
166 | void disable_pcit_irq(unsigned int irq) | 166 | void disable_pcit_irq(struct irq_data *d) |
167 | { | 167 | { |
168 | u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24); | 168 | u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24); |
169 | 169 | ||
170 | *(volatile u32 *)SNI_PCIT_INT_REG &= ~mask; | 170 | *(volatile u32 *)SNI_PCIT_INT_REG &= ~mask; |
171 | } | 171 | } |
172 | 172 | ||
173 | void end_pcit_irq(unsigned int irq) | ||
174 | { | ||
175 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
176 | enable_pcit_irq(irq); | ||
177 | } | ||
178 | |||
179 | static struct irq_chip pcit_irq_type = { | 173 | static struct irq_chip pcit_irq_type = { |
180 | .name = "PCIT", | 174 | .name = "PCIT", |
181 | .ack = disable_pcit_irq, | 175 | .irq_mask = disable_pcit_irq, |
182 | .mask = disable_pcit_irq, | 176 | .irq_unmask = enable_pcit_irq, |
183 | .mask_ack = disable_pcit_irq, | ||
184 | .unmask = enable_pcit_irq, | ||
185 | .end = end_pcit_irq, | ||
186 | }; | 177 | }; |
187 | 178 | ||
188 | static void pcit_hwint1(void) | 179 | static void pcit_hwint1(void) |
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c index 0e6f42c2bbc8..f05d8e593300 100644 --- a/arch/mips/sni/rm200.c +++ b/arch/mips/sni/rm200.c | |||
@@ -155,12 +155,11 @@ static __iomem u8 *rm200_pic_slave; | |||
155 | #define cached_master_mask (rm200_cached_irq_mask) | 155 | #define cached_master_mask (rm200_cached_irq_mask) |
156 | #define cached_slave_mask (rm200_cached_irq_mask >> 8) | 156 | #define cached_slave_mask (rm200_cached_irq_mask >> 8) |
157 | 157 | ||
158 | static void sni_rm200_disable_8259A_irq(unsigned int irq) | 158 | static void sni_rm200_disable_8259A_irq(struct irq_data *d) |
159 | { | 159 | { |
160 | unsigned int mask; | 160 | unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE; |
161 | unsigned long flags; | 161 | unsigned long flags; |
162 | 162 | ||
163 | irq -= RM200_I8259A_IRQ_BASE; | ||
164 | mask = 1 << irq; | 163 | mask = 1 << irq; |
165 | raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); | 164 | raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); |
166 | rm200_cached_irq_mask |= mask; | 165 | rm200_cached_irq_mask |= mask; |
@@ -171,12 +170,11 @@ static void sni_rm200_disable_8259A_irq(unsigned int irq) | |||
171 | raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags); | 170 | raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags); |
172 | } | 171 | } |
173 | 172 | ||
174 | static void sni_rm200_enable_8259A_irq(unsigned int irq) | 173 | static void sni_rm200_enable_8259A_irq(struct irq_data *d) |
175 | { | 174 | { |
176 | unsigned int mask; | 175 | unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE; |
177 | unsigned long flags; | 176 | unsigned long flags; |
178 | 177 | ||
179 | irq -= RM200_I8259A_IRQ_BASE; | ||
180 | mask = ~(1 << irq); | 178 | mask = ~(1 << irq); |
181 | raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); | 179 | raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); |
182 | rm200_cached_irq_mask &= mask; | 180 | rm200_cached_irq_mask &= mask; |
@@ -210,12 +208,11 @@ static inline int sni_rm200_i8259A_irq_real(unsigned int irq) | |||
210 | * first, _then_ send the EOI, and the order of EOI | 208 | * first, _then_ send the EOI, and the order of EOI |
211 | * to the two 8259s is important! | 209 | * to the two 8259s is important! |
212 | */ | 210 | */ |
213 | void sni_rm200_mask_and_ack_8259A(unsigned int irq) | 211 | void sni_rm200_mask_and_ack_8259A(struct irq_data *d) |
214 | { | 212 | { |
215 | unsigned int irqmask; | 213 | unsigned int irqmask, irq = d->irq - RM200_I8259A_IRQ_BASE; |
216 | unsigned long flags; | 214 | unsigned long flags; |
217 | 215 | ||
218 | irq -= RM200_I8259A_IRQ_BASE; | ||
219 | irqmask = 1 << irq; | 216 | irqmask = 1 << irq; |
220 | raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); | 217 | raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); |
221 | /* | 218 | /* |
@@ -285,9 +282,9 @@ spurious_8259A_irq: | |||
285 | 282 | ||
286 | static struct irq_chip sni_rm200_i8259A_chip = { | 283 | static struct irq_chip sni_rm200_i8259A_chip = { |
287 | .name = "RM200-XT-PIC", | 284 | .name = "RM200-XT-PIC", |
288 | .mask = sni_rm200_disable_8259A_irq, | 285 | .irq_mask = sni_rm200_disable_8259A_irq, |
289 | .unmask = sni_rm200_enable_8259A_irq, | 286 | .irq_unmask = sni_rm200_enable_8259A_irq, |
290 | .mask_ack = sni_rm200_mask_and_ack_8259A, | 287 | .irq_mask_ack = sni_rm200_mask_and_ack_8259A, |
291 | }; | 288 | }; |
292 | 289 | ||
293 | /* | 290 | /* |
@@ -429,33 +426,24 @@ void __init sni_rm200_i8259_irqs(void) | |||
429 | #define SNI_RM200_INT_START 24 | 426 | #define SNI_RM200_INT_START 24 |
430 | #define SNI_RM200_INT_END 28 | 427 | #define SNI_RM200_INT_END 28 |
431 | 428 | ||
432 | static void enable_rm200_irq(unsigned int irq) | 429 | static void enable_rm200_irq(struct irq_data *d) |
433 | { | 430 | { |
434 | unsigned int mask = 1 << (irq - SNI_RM200_INT_START); | 431 | unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START); |
435 | 432 | ||
436 | *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask; | 433 | *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask; |
437 | } | 434 | } |
438 | 435 | ||
439 | void disable_rm200_irq(unsigned int irq) | 436 | void disable_rm200_irq(struct irq_data *d) |
440 | { | 437 | { |
441 | unsigned int mask = 1 << (irq - SNI_RM200_INT_START); | 438 | unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START); |
442 | 439 | ||
443 | *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask; | 440 | *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask; |
444 | } | 441 | } |
445 | 442 | ||
446 | void end_rm200_irq(unsigned int irq) | ||
447 | { | ||
448 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
449 | enable_rm200_irq(irq); | ||
450 | } | ||
451 | |||
452 | static struct irq_chip rm200_irq_type = { | 443 | static struct irq_chip rm200_irq_type = { |
453 | .name = "RM200", | 444 | .name = "RM200", |
454 | .ack = disable_rm200_irq, | 445 | .irq_mask = disable_rm200_irq, |
455 | .mask = disable_rm200_irq, | 446 | .irq_unmask = enable_rm200_irq, |
456 | .mask_ack = disable_rm200_irq, | ||
457 | .unmask = enable_rm200_irq, | ||
458 | .end = end_rm200_irq, | ||
459 | }; | 447 | }; |
460 | 448 | ||
461 | static void sni_rm200_hwint(void) | 449 | static void sni_rm200_hwint(void) |
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c index 3886ad77cbad..93b6edbedd64 100644 --- a/arch/mips/txx9/generic/irq_tx4939.c +++ b/arch/mips/txx9/generic/irq_tx4939.c | |||
@@ -50,9 +50,9 @@ static struct { | |||
50 | unsigned char mode; | 50 | unsigned char mode; |
51 | } tx4939irq[TX4939_NUM_IR] __read_mostly; | 51 | } tx4939irq[TX4939_NUM_IR] __read_mostly; |
52 | 52 | ||
53 | static void tx4939_irq_unmask(unsigned int irq) | 53 | static void tx4939_irq_unmask(struct irq_data *d) |
54 | { | 54 | { |
55 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 55 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
56 | u32 __iomem *lvlp; | 56 | u32 __iomem *lvlp; |
57 | int ofs; | 57 | int ofs; |
58 | if (irq_nr < 32) { | 58 | if (irq_nr < 32) { |
@@ -68,9 +68,9 @@ static void tx4939_irq_unmask(unsigned int irq) | |||
68 | lvlp); | 68 | lvlp); |
69 | } | 69 | } |
70 | 70 | ||
71 | static inline void tx4939_irq_mask(unsigned int irq) | 71 | static inline void tx4939_irq_mask(struct irq_data *d) |
72 | { | 72 | { |
73 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 73 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
74 | u32 __iomem *lvlp; | 74 | u32 __iomem *lvlp; |
75 | int ofs; | 75 | int ofs; |
76 | if (irq_nr < 32) { | 76 | if (irq_nr < 32) { |
@@ -87,11 +87,11 @@ static inline void tx4939_irq_mask(unsigned int irq) | |||
87 | mmiowb(); | 87 | mmiowb(); |
88 | } | 88 | } |
89 | 89 | ||
90 | static void tx4939_irq_mask_ack(unsigned int irq) | 90 | static void tx4939_irq_mask_ack(struct irq_data *d) |
91 | { | 91 | { |
92 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 92 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
93 | 93 | ||
94 | tx4939_irq_mask(irq); | 94 | tx4939_irq_mask(d); |
95 | if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) { | 95 | if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) { |
96 | irq_nr--; | 96 | irq_nr--; |
97 | /* clear edge detection */ | 97 | /* clear edge detection */ |
@@ -101,9 +101,9 @@ static void tx4939_irq_mask_ack(unsigned int irq) | |||
101 | } | 101 | } |
102 | } | 102 | } |
103 | 103 | ||
104 | static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type) | 104 | static int tx4939_irq_set_type(struct irq_data *d, unsigned int flow_type) |
105 | { | 105 | { |
106 | unsigned int irq_nr = irq - TXX9_IRQ_BASE; | 106 | unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; |
107 | u32 cr; | 107 | u32 cr; |
108 | u32 __iomem *crp; | 108 | u32 __iomem *crp; |
109 | int ofs; | 109 | int ofs; |
@@ -145,11 +145,11 @@ static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type) | |||
145 | 145 | ||
146 | static struct irq_chip tx4939_irq_chip = { | 146 | static struct irq_chip tx4939_irq_chip = { |
147 | .name = "TX4939", | 147 | .name = "TX4939", |
148 | .ack = tx4939_irq_mask_ack, | 148 | .irq_ack = tx4939_irq_mask_ack, |
149 | .mask = tx4939_irq_mask, | 149 | .irq_mask = tx4939_irq_mask, |
150 | .mask_ack = tx4939_irq_mask_ack, | 150 | .irq_mask_ack = tx4939_irq_mask_ack, |
151 | .unmask = tx4939_irq_unmask, | 151 | .irq_unmask = tx4939_irq_unmask, |
152 | .set_type = tx4939_irq_set_type, | 152 | .irq_set_type = tx4939_irq_set_type, |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static int tx4939_irq_set_pri(int irc_irq, int new_pri) | 155 | static int tx4939_irq_set_pri(int irc_irq, int new_pri) |
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c index 0a7f8e3b9fd7..92a5c1b400f0 100644 --- a/arch/mips/txx9/jmr3927/irq.c +++ b/arch/mips/txx9/jmr3927/irq.c | |||
@@ -47,20 +47,20 @@ | |||
47 | * CP0_STATUS is a thread's resource (saved/restored on context switch). | 47 | * CP0_STATUS is a thread's resource (saved/restored on context switch). |
48 | * So disable_irq/enable_irq MUST handle IOC/IRC registers. | 48 | * So disable_irq/enable_irq MUST handle IOC/IRC registers. |
49 | */ | 49 | */ |
50 | static void mask_irq_ioc(unsigned int irq) | 50 | static void mask_irq_ioc(struct irq_data *d) |
51 | { | 51 | { |
52 | /* 0: mask */ | 52 | /* 0: mask */ |
53 | unsigned int irq_nr = irq - JMR3927_IRQ_IOC; | 53 | unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC; |
54 | unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); | 54 | unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); |
55 | unsigned int bit = 1 << irq_nr; | 55 | unsigned int bit = 1 << irq_nr; |
56 | jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); | 56 | jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); |
57 | /* flush write buffer */ | 57 | /* flush write buffer */ |
58 | (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); | 58 | (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); |
59 | } | 59 | } |
60 | static void unmask_irq_ioc(unsigned int irq) | 60 | static void unmask_irq_ioc(struct irq_data *d) |
61 | { | 61 | { |
62 | /* 0: mask */ | 62 | /* 0: mask */ |
63 | unsigned int irq_nr = irq - JMR3927_IRQ_IOC; | 63 | unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC; |
64 | unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); | 64 | unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); |
65 | unsigned int bit = 1 << irq_nr; | 65 | unsigned int bit = 1 << irq_nr; |
66 | jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); | 66 | jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); |
@@ -95,10 +95,8 @@ static int jmr3927_irq_dispatch(int pending) | |||
95 | 95 | ||
96 | static struct irq_chip jmr3927_irq_ioc = { | 96 | static struct irq_chip jmr3927_irq_ioc = { |
97 | .name = "jmr3927_ioc", | 97 | .name = "jmr3927_ioc", |
98 | .ack = mask_irq_ioc, | 98 | .irq_mask = mask_irq_ioc, |
99 | .mask = mask_irq_ioc, | 99 | .irq_unmask = unmask_irq_ioc, |
100 | .mask_ack = mask_irq_ioc, | ||
101 | .unmask = unmask_irq_ioc, | ||
102 | }; | 100 | }; |
103 | 101 | ||
104 | void __init jmr3927_irq_setup(void) | 102 | void __init jmr3927_irq_setup(void) |
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index c4b54d20efd3..7c0a048b307c 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c | |||
@@ -117,18 +117,6 @@ | |||
117 | #include <asm/txx9/generic.h> | 117 | #include <asm/txx9/generic.h> |
118 | #include <asm/txx9/rbtx4927.h> | 118 | #include <asm/txx9/rbtx4927.h> |
119 | 119 | ||
120 | static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); | ||
121 | static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); | ||
122 | |||
123 | #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" | ||
124 | static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { | ||
125 | .name = TOSHIBA_RBTX4927_IOC_NAME, | ||
126 | .ack = toshiba_rbtx4927_irq_ioc_disable, | ||
127 | .mask = toshiba_rbtx4927_irq_ioc_disable, | ||
128 | .mask_ack = toshiba_rbtx4927_irq_ioc_disable, | ||
129 | .unmask = toshiba_rbtx4927_irq_ioc_enable, | ||
130 | }; | ||
131 | |||
132 | static int toshiba_rbtx4927_irq_nested(int sw_irq) | 120 | static int toshiba_rbtx4927_irq_nested(int sw_irq) |
133 | { | 121 | { |
134 | u8 level3; | 122 | u8 level3; |
@@ -139,41 +127,47 @@ static int toshiba_rbtx4927_irq_nested(int sw_irq) | |||
139 | return RBTX4927_IRQ_IOC + __fls8(level3); | 127 | return RBTX4927_IRQ_IOC + __fls8(level3); |
140 | } | 128 | } |
141 | 129 | ||
142 | static void __init toshiba_rbtx4927_irq_ioc_init(void) | 130 | static void toshiba_rbtx4927_irq_ioc_enable(struct irq_data *d) |
143 | { | ||
144 | int i; | ||
145 | |||
146 | /* mask all IOC interrupts */ | ||
147 | writeb(0, rbtx4927_imask_addr); | ||
148 | /* clear SoftInt interrupts */ | ||
149 | writeb(0, rbtx4927_softint_addr); | ||
150 | |||
151 | for (i = RBTX4927_IRQ_IOC; | ||
152 | i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) | ||
153 | set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, | ||
154 | handle_level_irq); | ||
155 | set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); | ||
156 | } | ||
157 | |||
158 | static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) | ||
159 | { | 131 | { |
160 | unsigned char v; | 132 | unsigned char v; |
161 | 133 | ||
162 | v = readb(rbtx4927_imask_addr); | 134 | v = readb(rbtx4927_imask_addr); |
163 | v |= (1 << (irq - RBTX4927_IRQ_IOC)); | 135 | v |= (1 << (d->irq - RBTX4927_IRQ_IOC)); |
164 | writeb(v, rbtx4927_imask_addr); | 136 | writeb(v, rbtx4927_imask_addr); |
165 | } | 137 | } |
166 | 138 | ||
167 | static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) | 139 | static void toshiba_rbtx4927_irq_ioc_disable(struct irq_data *d) |
168 | { | 140 | { |
169 | unsigned char v; | 141 | unsigned char v; |
170 | 142 | ||
171 | v = readb(rbtx4927_imask_addr); | 143 | v = readb(rbtx4927_imask_addr); |
172 | v &= ~(1 << (irq - RBTX4927_IRQ_IOC)); | 144 | v &= ~(1 << (d->irq - RBTX4927_IRQ_IOC)); |
173 | writeb(v, rbtx4927_imask_addr); | 145 | writeb(v, rbtx4927_imask_addr); |
174 | mmiowb(); | 146 | mmiowb(); |
175 | } | 147 | } |
176 | 148 | ||
149 | #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" | ||
150 | static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { | ||
151 | .name = TOSHIBA_RBTX4927_IOC_NAME, | ||
152 | .irq_mask = toshiba_rbtx4927_irq_ioc_disable, | ||
153 | .irq_unmask = toshiba_rbtx4927_irq_ioc_enable, | ||
154 | }; | ||
155 | |||
156 | static void __init toshiba_rbtx4927_irq_ioc_init(void) | ||
157 | { | ||
158 | int i; | ||
159 | |||
160 | /* mask all IOC interrupts */ | ||
161 | writeb(0, rbtx4927_imask_addr); | ||
162 | /* clear SoftInt interrupts */ | ||
163 | writeb(0, rbtx4927_softint_addr); | ||
164 | |||
165 | for (i = RBTX4927_IRQ_IOC; | ||
166 | i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) | ||
167 | set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, | ||
168 | handle_level_irq); | ||
169 | set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); | ||
170 | } | ||
177 | 171 | ||
178 | static int rbtx4927_irq_dispatch(int pending) | 172 | static int rbtx4927_irq_dispatch(int pending) |
179 | { | 173 | { |
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c index 67a73a8065ec..2ec4fe1b1670 100644 --- a/arch/mips/txx9/rbtx4938/irq.c +++ b/arch/mips/txx9/rbtx4938/irq.c | |||
@@ -69,18 +69,6 @@ | |||
69 | #include <asm/txx9/generic.h> | 69 | #include <asm/txx9/generic.h> |
70 | #include <asm/txx9/rbtx4938.h> | 70 | #include <asm/txx9/rbtx4938.h> |
71 | 71 | ||
72 | static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); | ||
73 | static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); | ||
74 | |||
75 | #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" | ||
76 | static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { | ||
77 | .name = TOSHIBA_RBTX4938_IOC_NAME, | ||
78 | .ack = toshiba_rbtx4938_irq_ioc_disable, | ||
79 | .mask = toshiba_rbtx4938_irq_ioc_disable, | ||
80 | .mask_ack = toshiba_rbtx4938_irq_ioc_disable, | ||
81 | .unmask = toshiba_rbtx4938_irq_ioc_enable, | ||
82 | }; | ||
83 | |||
84 | static int toshiba_rbtx4938_irq_nested(int sw_irq) | 72 | static int toshiba_rbtx4938_irq_nested(int sw_irq) |
85 | { | 73 | { |
86 | u8 level3; | 74 | u8 level3; |
@@ -92,41 +80,33 @@ static int toshiba_rbtx4938_irq_nested(int sw_irq) | |||
92 | return RBTX4938_IRQ_IOC + __fls8(level3); | 80 | return RBTX4938_IRQ_IOC + __fls8(level3); |
93 | } | 81 | } |
94 | 82 | ||
95 | static void __init | 83 | static void toshiba_rbtx4938_irq_ioc_enable(struct irq_data *d) |
96 | toshiba_rbtx4938_irq_ioc_init(void) | ||
97 | { | ||
98 | int i; | ||
99 | |||
100 | for (i = RBTX4938_IRQ_IOC; | ||
101 | i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++) | ||
102 | set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, | ||
103 | handle_level_irq); | ||
104 | |||
105 | set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); | ||
106 | } | ||
107 | |||
108 | static void | ||
109 | toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) | ||
110 | { | 84 | { |
111 | unsigned char v; | 85 | unsigned char v; |
112 | 86 | ||
113 | v = readb(rbtx4938_imask_addr); | 87 | v = readb(rbtx4938_imask_addr); |
114 | v |= (1 << (irq - RBTX4938_IRQ_IOC)); | 88 | v |= (1 << (d->irq - RBTX4938_IRQ_IOC)); |
115 | writeb(v, rbtx4938_imask_addr); | 89 | writeb(v, rbtx4938_imask_addr); |
116 | mmiowb(); | 90 | mmiowb(); |
117 | } | 91 | } |
118 | 92 | ||
119 | static void | 93 | static void toshiba_rbtx4938_irq_ioc_disable(struct irq_data *d) |
120 | toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) | ||
121 | { | 94 | { |
122 | unsigned char v; | 95 | unsigned char v; |
123 | 96 | ||
124 | v = readb(rbtx4938_imask_addr); | 97 | v = readb(rbtx4938_imask_addr); |
125 | v &= ~(1 << (irq - RBTX4938_IRQ_IOC)); | 98 | v &= ~(1 << (d->irq - RBTX4938_IRQ_IOC)); |
126 | writeb(v, rbtx4938_imask_addr); | 99 | writeb(v, rbtx4938_imask_addr); |
127 | mmiowb(); | 100 | mmiowb(); |
128 | } | 101 | } |
129 | 102 | ||
103 | #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" | ||
104 | static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { | ||
105 | .name = TOSHIBA_RBTX4938_IOC_NAME, | ||
106 | .irq_mask = toshiba_rbtx4938_irq_ioc_disable, | ||
107 | .irq_unmask = toshiba_rbtx4938_irq_ioc_enable, | ||
108 | }; | ||
109 | |||
130 | static int rbtx4938_irq_dispatch(int pending) | 110 | static int rbtx4938_irq_dispatch(int pending) |
131 | { | 111 | { |
132 | int irq; | 112 | int irq; |
@@ -146,6 +126,18 @@ static int rbtx4938_irq_dispatch(int pending) | |||
146 | return irq; | 126 | return irq; |
147 | } | 127 | } |
148 | 128 | ||
129 | static void __init toshiba_rbtx4938_irq_ioc_init(void) | ||
130 | { | ||
131 | int i; | ||
132 | |||
133 | for (i = RBTX4938_IRQ_IOC; | ||
134 | i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++) | ||
135 | set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, | ||
136 | handle_level_irq); | ||
137 | |||
138 | set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); | ||
139 | } | ||
140 | |||
149 | void __init rbtx4938_irq_setup(void) | 141 | void __init rbtx4938_irq_setup(void) |
150 | { | 142 | { |
151 | txx9_irq_dispatch = rbtx4938_irq_dispatch; | 143 | txx9_irq_dispatch = rbtx4938_irq_dispatch; |
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c index 57fa740a7205..70074632fb99 100644 --- a/arch/mips/txx9/rbtx4939/irq.c +++ b/arch/mips/txx9/rbtx4939/irq.c | |||
@@ -19,16 +19,16 @@ | |||
19 | * RBTX4939 IOC controller definition | 19 | * RBTX4939 IOC controller definition |
20 | */ | 20 | */ |
21 | 21 | ||
22 | static void rbtx4939_ioc_irq_unmask(unsigned int irq) | 22 | static void rbtx4939_ioc_irq_unmask(struct irq_data *d) |
23 | { | 23 | { |
24 | int ioc_nr = irq - RBTX4939_IRQ_IOC; | 24 | int ioc_nr = d->irq - RBTX4939_IRQ_IOC; |
25 | 25 | ||
26 | writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr); | 26 | writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr); |
27 | } | 27 | } |
28 | 28 | ||
29 | static void rbtx4939_ioc_irq_mask(unsigned int irq) | 29 | static void rbtx4939_ioc_irq_mask(struct irq_data *d) |
30 | { | 30 | { |
31 | int ioc_nr = irq - RBTX4939_IRQ_IOC; | 31 | int ioc_nr = d->irq - RBTX4939_IRQ_IOC; |
32 | 32 | ||
33 | writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr); | 33 | writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr); |
34 | mmiowb(); | 34 | mmiowb(); |
@@ -36,10 +36,8 @@ static void rbtx4939_ioc_irq_mask(unsigned int irq) | |||
36 | 36 | ||
37 | static struct irq_chip rbtx4939_ioc_irq_chip = { | 37 | static struct irq_chip rbtx4939_ioc_irq_chip = { |
38 | .name = "IOC", | 38 | .name = "IOC", |
39 | .ack = rbtx4939_ioc_irq_mask, | 39 | .irq_mask = rbtx4939_ioc_irq_mask, |
40 | .mask = rbtx4939_ioc_irq_mask, | 40 | .irq_unmask = rbtx4939_ioc_irq_unmask, |
41 | .mask_ack = rbtx4939_ioc_irq_mask, | ||
42 | .unmask = rbtx4939_ioc_irq_unmask, | ||
43 | }; | 41 | }; |
44 | 42 | ||
45 | 43 | ||
diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 6153b6a05ccf..f53156bb9aa8 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c | |||
@@ -154,7 +154,7 @@ static inline uint16_t icu2_clear(uint8_t offset, uint16_t clear) | |||
154 | 154 | ||
155 | void vr41xx_enable_piuint(uint16_t mask) | 155 | void vr41xx_enable_piuint(uint16_t mask) |
156 | { | 156 | { |
157 | struct irq_desc *desc = irq_desc + PIU_IRQ; | 157 | struct irq_desc *desc = irq_to_desc(PIU_IRQ); |
158 | unsigned long flags; | 158 | unsigned long flags; |
159 | 159 | ||
160 | if (current_cpu_type() == CPU_VR4111 || | 160 | if (current_cpu_type() == CPU_VR4111 || |
@@ -169,7 +169,7 @@ EXPORT_SYMBOL(vr41xx_enable_piuint); | |||
169 | 169 | ||
170 | void vr41xx_disable_piuint(uint16_t mask) | 170 | void vr41xx_disable_piuint(uint16_t mask) |
171 | { | 171 | { |
172 | struct irq_desc *desc = irq_desc + PIU_IRQ; | 172 | struct irq_desc *desc = irq_to_desc(PIU_IRQ); |
173 | unsigned long flags; | 173 | unsigned long flags; |
174 | 174 | ||
175 | if (current_cpu_type() == CPU_VR4111 || | 175 | if (current_cpu_type() == CPU_VR4111 || |
@@ -184,7 +184,7 @@ EXPORT_SYMBOL(vr41xx_disable_piuint); | |||
184 | 184 | ||
185 | void vr41xx_enable_aiuint(uint16_t mask) | 185 | void vr41xx_enable_aiuint(uint16_t mask) |
186 | { | 186 | { |
187 | struct irq_desc *desc = irq_desc + AIU_IRQ; | 187 | struct irq_desc *desc = irq_to_desc(AIU_IRQ); |
188 | unsigned long flags; | 188 | unsigned long flags; |
189 | 189 | ||
190 | if (current_cpu_type() == CPU_VR4111 || | 190 | if (current_cpu_type() == CPU_VR4111 || |
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(vr41xx_enable_aiuint); | |||
199 | 199 | ||
200 | void vr41xx_disable_aiuint(uint16_t mask) | 200 | void vr41xx_disable_aiuint(uint16_t mask) |
201 | { | 201 | { |
202 | struct irq_desc *desc = irq_desc + AIU_IRQ; | 202 | struct irq_desc *desc = irq_to_desc(AIU_IRQ); |
203 | unsigned long flags; | 203 | unsigned long flags; |
204 | 204 | ||
205 | if (current_cpu_type() == CPU_VR4111 || | 205 | if (current_cpu_type() == CPU_VR4111 || |
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(vr41xx_disable_aiuint); | |||
214 | 214 | ||
215 | void vr41xx_enable_kiuint(uint16_t mask) | 215 | void vr41xx_enable_kiuint(uint16_t mask) |
216 | { | 216 | { |
217 | struct irq_desc *desc = irq_desc + KIU_IRQ; | 217 | struct irq_desc *desc = irq_to_desc(KIU_IRQ); |
218 | unsigned long flags; | 218 | unsigned long flags; |
219 | 219 | ||
220 | if (current_cpu_type() == CPU_VR4111 || | 220 | if (current_cpu_type() == CPU_VR4111 || |
@@ -229,7 +229,7 @@ EXPORT_SYMBOL(vr41xx_enable_kiuint); | |||
229 | 229 | ||
230 | void vr41xx_disable_kiuint(uint16_t mask) | 230 | void vr41xx_disable_kiuint(uint16_t mask) |
231 | { | 231 | { |
232 | struct irq_desc *desc = irq_desc + KIU_IRQ; | 232 | struct irq_desc *desc = irq_to_desc(KIU_IRQ); |
233 | unsigned long flags; | 233 | unsigned long flags; |
234 | 234 | ||
235 | if (current_cpu_type() == CPU_VR4111 || | 235 | if (current_cpu_type() == CPU_VR4111 || |
@@ -244,7 +244,7 @@ EXPORT_SYMBOL(vr41xx_disable_kiuint); | |||
244 | 244 | ||
245 | void vr41xx_enable_macint(uint16_t mask) | 245 | void vr41xx_enable_macint(uint16_t mask) |
246 | { | 246 | { |
247 | struct irq_desc *desc = irq_desc + ETHERNET_IRQ; | 247 | struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ); |
248 | unsigned long flags; | 248 | unsigned long flags; |
249 | 249 | ||
250 | raw_spin_lock_irqsave(&desc->lock, flags); | 250 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -256,7 +256,7 @@ EXPORT_SYMBOL(vr41xx_enable_macint); | |||
256 | 256 | ||
257 | void vr41xx_disable_macint(uint16_t mask) | 257 | void vr41xx_disable_macint(uint16_t mask) |
258 | { | 258 | { |
259 | struct irq_desc *desc = irq_desc + ETHERNET_IRQ; | 259 | struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ); |
260 | unsigned long flags; | 260 | unsigned long flags; |
261 | 261 | ||
262 | raw_spin_lock_irqsave(&desc->lock, flags); | 262 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -268,7 +268,7 @@ EXPORT_SYMBOL(vr41xx_disable_macint); | |||
268 | 268 | ||
269 | void vr41xx_enable_dsiuint(uint16_t mask) | 269 | void vr41xx_enable_dsiuint(uint16_t mask) |
270 | { | 270 | { |
271 | struct irq_desc *desc = irq_desc + DSIU_IRQ; | 271 | struct irq_desc *desc = irq_to_desc(DSIU_IRQ); |
272 | unsigned long flags; | 272 | unsigned long flags; |
273 | 273 | ||
274 | raw_spin_lock_irqsave(&desc->lock, flags); | 274 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -280,7 +280,7 @@ EXPORT_SYMBOL(vr41xx_enable_dsiuint); | |||
280 | 280 | ||
281 | void vr41xx_disable_dsiuint(uint16_t mask) | 281 | void vr41xx_disable_dsiuint(uint16_t mask) |
282 | { | 282 | { |
283 | struct irq_desc *desc = irq_desc + DSIU_IRQ; | 283 | struct irq_desc *desc = irq_to_desc(DSIU_IRQ); |
284 | unsigned long flags; | 284 | unsigned long flags; |
285 | 285 | ||
286 | raw_spin_lock_irqsave(&desc->lock, flags); | 286 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -292,7 +292,7 @@ EXPORT_SYMBOL(vr41xx_disable_dsiuint); | |||
292 | 292 | ||
293 | void vr41xx_enable_firint(uint16_t mask) | 293 | void vr41xx_enable_firint(uint16_t mask) |
294 | { | 294 | { |
295 | struct irq_desc *desc = irq_desc + FIR_IRQ; | 295 | struct irq_desc *desc = irq_to_desc(FIR_IRQ); |
296 | unsigned long flags; | 296 | unsigned long flags; |
297 | 297 | ||
298 | raw_spin_lock_irqsave(&desc->lock, flags); | 298 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -304,7 +304,7 @@ EXPORT_SYMBOL(vr41xx_enable_firint); | |||
304 | 304 | ||
305 | void vr41xx_disable_firint(uint16_t mask) | 305 | void vr41xx_disable_firint(uint16_t mask) |
306 | { | 306 | { |
307 | struct irq_desc *desc = irq_desc + FIR_IRQ; | 307 | struct irq_desc *desc = irq_to_desc(FIR_IRQ); |
308 | unsigned long flags; | 308 | unsigned long flags; |
309 | 309 | ||
310 | raw_spin_lock_irqsave(&desc->lock, flags); | 310 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -316,7 +316,7 @@ EXPORT_SYMBOL(vr41xx_disable_firint); | |||
316 | 316 | ||
317 | void vr41xx_enable_pciint(void) | 317 | void vr41xx_enable_pciint(void) |
318 | { | 318 | { |
319 | struct irq_desc *desc = irq_desc + PCI_IRQ; | 319 | struct irq_desc *desc = irq_to_desc(PCI_IRQ); |
320 | unsigned long flags; | 320 | unsigned long flags; |
321 | 321 | ||
322 | if (current_cpu_type() == CPU_VR4122 || | 322 | if (current_cpu_type() == CPU_VR4122 || |
@@ -332,7 +332,7 @@ EXPORT_SYMBOL(vr41xx_enable_pciint); | |||
332 | 332 | ||
333 | void vr41xx_disable_pciint(void) | 333 | void vr41xx_disable_pciint(void) |
334 | { | 334 | { |
335 | struct irq_desc *desc = irq_desc + PCI_IRQ; | 335 | struct irq_desc *desc = irq_to_desc(PCI_IRQ); |
336 | unsigned long flags; | 336 | unsigned long flags; |
337 | 337 | ||
338 | if (current_cpu_type() == CPU_VR4122 || | 338 | if (current_cpu_type() == CPU_VR4122 || |
@@ -348,7 +348,7 @@ EXPORT_SYMBOL(vr41xx_disable_pciint); | |||
348 | 348 | ||
349 | void vr41xx_enable_scuint(void) | 349 | void vr41xx_enable_scuint(void) |
350 | { | 350 | { |
351 | struct irq_desc *desc = irq_desc + SCU_IRQ; | 351 | struct irq_desc *desc = irq_to_desc(SCU_IRQ); |
352 | unsigned long flags; | 352 | unsigned long flags; |
353 | 353 | ||
354 | if (current_cpu_type() == CPU_VR4122 || | 354 | if (current_cpu_type() == CPU_VR4122 || |
@@ -364,7 +364,7 @@ EXPORT_SYMBOL(vr41xx_enable_scuint); | |||
364 | 364 | ||
365 | void vr41xx_disable_scuint(void) | 365 | void vr41xx_disable_scuint(void) |
366 | { | 366 | { |
367 | struct irq_desc *desc = irq_desc + SCU_IRQ; | 367 | struct irq_desc *desc = irq_to_desc(SCU_IRQ); |
368 | unsigned long flags; | 368 | unsigned long flags; |
369 | 369 | ||
370 | if (current_cpu_type() == CPU_VR4122 || | 370 | if (current_cpu_type() == CPU_VR4122 || |
@@ -380,7 +380,7 @@ EXPORT_SYMBOL(vr41xx_disable_scuint); | |||
380 | 380 | ||
381 | void vr41xx_enable_csiint(uint16_t mask) | 381 | void vr41xx_enable_csiint(uint16_t mask) |
382 | { | 382 | { |
383 | struct irq_desc *desc = irq_desc + CSI_IRQ; | 383 | struct irq_desc *desc = irq_to_desc(CSI_IRQ); |
384 | unsigned long flags; | 384 | unsigned long flags; |
385 | 385 | ||
386 | if (current_cpu_type() == CPU_VR4122 || | 386 | if (current_cpu_type() == CPU_VR4122 || |
@@ -396,7 +396,7 @@ EXPORT_SYMBOL(vr41xx_enable_csiint); | |||
396 | 396 | ||
397 | void vr41xx_disable_csiint(uint16_t mask) | 397 | void vr41xx_disable_csiint(uint16_t mask) |
398 | { | 398 | { |
399 | struct irq_desc *desc = irq_desc + CSI_IRQ; | 399 | struct irq_desc *desc = irq_to_desc(CSI_IRQ); |
400 | unsigned long flags; | 400 | unsigned long flags; |
401 | 401 | ||
402 | if (current_cpu_type() == CPU_VR4122 || | 402 | if (current_cpu_type() == CPU_VR4122 || |
@@ -412,7 +412,7 @@ EXPORT_SYMBOL(vr41xx_disable_csiint); | |||
412 | 412 | ||
413 | void vr41xx_enable_bcuint(void) | 413 | void vr41xx_enable_bcuint(void) |
414 | { | 414 | { |
415 | struct irq_desc *desc = irq_desc + BCU_IRQ; | 415 | struct irq_desc *desc = irq_to_desc(BCU_IRQ); |
416 | unsigned long flags; | 416 | unsigned long flags; |
417 | 417 | ||
418 | if (current_cpu_type() == CPU_VR4122 || | 418 | if (current_cpu_type() == CPU_VR4122 || |
@@ -428,7 +428,7 @@ EXPORT_SYMBOL(vr41xx_enable_bcuint); | |||
428 | 428 | ||
429 | void vr41xx_disable_bcuint(void) | 429 | void vr41xx_disable_bcuint(void) |
430 | { | 430 | { |
431 | struct irq_desc *desc = irq_desc + BCU_IRQ; | 431 | struct irq_desc *desc = irq_to_desc(BCU_IRQ); |
432 | unsigned long flags; | 432 | unsigned long flags; |
433 | 433 | ||
434 | if (current_cpu_type() == CPU_VR4122 || | 434 | if (current_cpu_type() == CPU_VR4122 || |
@@ -442,45 +442,41 @@ void vr41xx_disable_bcuint(void) | |||
442 | 442 | ||
443 | EXPORT_SYMBOL(vr41xx_disable_bcuint); | 443 | EXPORT_SYMBOL(vr41xx_disable_bcuint); |
444 | 444 | ||
445 | static void disable_sysint1_irq(unsigned int irq) | 445 | static void disable_sysint1_irq(struct irq_data *d) |
446 | { | 446 | { |
447 | icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); | 447 | icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq)); |
448 | } | 448 | } |
449 | 449 | ||
450 | static void enable_sysint1_irq(unsigned int irq) | 450 | static void enable_sysint1_irq(struct irq_data *d) |
451 | { | 451 | { |
452 | icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); | 452 | icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq)); |
453 | } | 453 | } |
454 | 454 | ||
455 | static struct irq_chip sysint1_irq_type = { | 455 | static struct irq_chip sysint1_irq_type = { |
456 | .name = "SYSINT1", | 456 | .name = "SYSINT1", |
457 | .ack = disable_sysint1_irq, | 457 | .irq_mask = disable_sysint1_irq, |
458 | .mask = disable_sysint1_irq, | 458 | .irq_unmask = enable_sysint1_irq, |
459 | .mask_ack = disable_sysint1_irq, | ||
460 | .unmask = enable_sysint1_irq, | ||
461 | }; | 459 | }; |
462 | 460 | ||
463 | static void disable_sysint2_irq(unsigned int irq) | 461 | static void disable_sysint2_irq(struct irq_data *d) |
464 | { | 462 | { |
465 | icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); | 463 | icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq)); |
466 | } | 464 | } |
467 | 465 | ||
468 | static void enable_sysint2_irq(unsigned int irq) | 466 | static void enable_sysint2_irq(struct irq_data *d) |
469 | { | 467 | { |
470 | icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); | 468 | icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq)); |
471 | } | 469 | } |
472 | 470 | ||
473 | static struct irq_chip sysint2_irq_type = { | 471 | static struct irq_chip sysint2_irq_type = { |
474 | .name = "SYSINT2", | 472 | .name = "SYSINT2", |
475 | .ack = disable_sysint2_irq, | 473 | .irq_mask = disable_sysint2_irq, |
476 | .mask = disable_sysint2_irq, | 474 | .irq_unmask = enable_sysint2_irq, |
477 | .mask_ack = disable_sysint2_irq, | ||
478 | .unmask = enable_sysint2_irq, | ||
479 | }; | 475 | }; |
480 | 476 | ||
481 | static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) | 477 | static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) |
482 | { | 478 | { |
483 | struct irq_desc *desc = irq_desc + irq; | 479 | struct irq_desc *desc = irq_to_desc(irq); |
484 | uint16_t intassign0, intassign1; | 480 | uint16_t intassign0, intassign1; |
485 | unsigned int pin; | 481 | unsigned int pin; |
486 | 482 | ||
@@ -540,7 +536,7 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) | |||
540 | 536 | ||
541 | static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) | 537 | static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) |
542 | { | 538 | { |
543 | struct irq_desc *desc = irq_desc + irq; | 539 | struct irq_desc *desc = irq_to_desc(irq); |
544 | uint16_t intassign2, intassign3; | 540 | uint16_t intassign2, intassign3; |
545 | unsigned int pin; | 541 | unsigned int pin; |
546 | 542 | ||
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 0975eb72d385..9ff7f397c0e1 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c | |||
@@ -62,7 +62,6 @@ EXPORT_SYMBOL_GPL(cascade_irq); | |||
62 | static void irq_dispatch(unsigned int irq) | 62 | static void irq_dispatch(unsigned int irq) |
63 | { | 63 | { |
64 | irq_cascade_t *cascade; | 64 | irq_cascade_t *cascade; |
65 | struct irq_desc *desc; | ||
66 | 65 | ||
67 | if (irq >= NR_IRQS) { | 66 | if (irq >= NR_IRQS) { |
68 | atomic_inc(&irq_err_count); | 67 | atomic_inc(&irq_err_count); |
@@ -71,14 +70,16 @@ static void irq_dispatch(unsigned int irq) | |||
71 | 70 | ||
72 | cascade = irq_cascade + irq; | 71 | cascade = irq_cascade + irq; |
73 | if (cascade->get_irq != NULL) { | 72 | if (cascade->get_irq != NULL) { |
74 | unsigned int source_irq = irq; | 73 | struct irq_desc *desc = irq_to_desc(irq); |
74 | struct irq_data *idata = irq_desc_get_irq_data(desc); | ||
75 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
75 | int ret; | 76 | int ret; |
76 | desc = irq_desc + source_irq; | 77 | |
77 | if (desc->chip->mask_ack) | 78 | if (chip->irq_mask_ack) |
78 | desc->chip->mask_ack(source_irq); | 79 | chip->irq_mask_ack(idata); |
79 | else { | 80 | else { |
80 | desc->chip->mask(source_irq); | 81 | chip->irq_mask(idata); |
81 | desc->chip->ack(source_irq); | 82 | chip->irq_ack(idata); |
82 | } | 83 | } |
83 | ret = cascade->get_irq(irq); | 84 | ret = cascade->get_irq(irq); |
84 | irq = ret; | 85 | irq = ret; |
@@ -86,8 +87,8 @@ static void irq_dispatch(unsigned int irq) | |||
86 | atomic_inc(&irq_err_count); | 87 | atomic_inc(&irq_err_count); |
87 | else | 88 | else |
88 | irq_dispatch(irq); | 89 | irq_dispatch(irq); |
89 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) | 90 | if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask) |
90 | desc->chip->unmask(source_irq); | 91 | chip->irq_unmask(idata); |
91 | } else | 92 | } else |
92 | do_IRQ(irq); | 93 | do_IRQ(irq); |
93 | } | 94 | } |
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index f4f4d700833a..b7ed8d7a9b33 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
@@ -544,7 +544,7 @@ void __init mem_init(void) | |||
544 | unsigned long *empty_zero_page __read_mostly; | 544 | unsigned long *empty_zero_page __read_mostly; |
545 | EXPORT_SYMBOL(empty_zero_page); | 545 | EXPORT_SYMBOL(empty_zero_page); |
546 | 546 | ||
547 | void show_mem(void) | 547 | void show_mem(unsigned int filter) |
548 | { | 548 | { |
549 | int i,free = 0,total = 0,reserved = 0; | 549 | int i,free = 0,total = 0,reserved = 0; |
550 | int shared = 0, cached = 0; | 550 | int shared = 0, cached = 0; |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index d17d04cfb2cd..33794c1d92c3 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -821,7 +821,7 @@ cmds(struct pt_regs *excp) | |||
821 | memzcan(); | 821 | memzcan(); |
822 | break; | 822 | break; |
823 | case 'i': | 823 | case 'i': |
824 | show_mem(); | 824 | show_mem(0); |
825 | break; | 825 | break; |
826 | default: | 826 | default: |
827 | termch = cmd; | 827 | termch = cmd; |
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index ff6f62e0ec3e..623f2fb71774 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h | |||
@@ -112,7 +112,6 @@ enum uc_todo { | |||
112 | 112 | ||
113 | /** | 113 | /** |
114 | * struct ccw driver - device driver for channel attached devices | 114 | * struct ccw driver - device driver for channel attached devices |
115 | * @owner: owning module | ||
116 | * @ids: ids supported by this driver | 115 | * @ids: ids supported by this driver |
117 | * @probe: function called on probe | 116 | * @probe: function called on probe |
118 | * @remove: function called on remove | 117 | * @remove: function called on remove |
@@ -128,10 +127,8 @@ enum uc_todo { | |||
128 | * @restore: callback for restoring after hibernation | 127 | * @restore: callback for restoring after hibernation |
129 | * @uc_handler: callback for unit check handler | 128 | * @uc_handler: callback for unit check handler |
130 | * @driver: embedded device driver structure | 129 | * @driver: embedded device driver structure |
131 | * @name: device driver name | ||
132 | */ | 130 | */ |
133 | struct ccw_driver { | 131 | struct ccw_driver { |
134 | struct module *owner; | ||
135 | struct ccw_device_id *ids; | 132 | struct ccw_device_id *ids; |
136 | int (*probe) (struct ccw_device *); | 133 | int (*probe) (struct ccw_device *); |
137 | void (*remove) (struct ccw_device *); | 134 | void (*remove) (struct ccw_device *); |
@@ -147,7 +144,6 @@ struct ccw_driver { | |||
147 | int (*restore)(struct ccw_device *); | 144 | int (*restore)(struct ccw_device *); |
148 | enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *); | 145 | enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *); |
149 | struct device_driver driver; | 146 | struct device_driver driver; |
150 | char *name; | ||
151 | }; | 147 | }; |
152 | 148 | ||
153 | extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, | 149 | extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, |
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index c79c1e787b86..f2ea2c56a7e1 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h | |||
@@ -29,8 +29,6 @@ struct ccwgroup_device { | |||
29 | 29 | ||
30 | /** | 30 | /** |
31 | * struct ccwgroup_driver - driver for ccw group devices | 31 | * struct ccwgroup_driver - driver for ccw group devices |
32 | * @owner: driver owner | ||
33 | * @name: driver name | ||
34 | * @max_slaves: maximum number of slave devices | 32 | * @max_slaves: maximum number of slave devices |
35 | * @driver_id: unique id | 33 | * @driver_id: unique id |
36 | * @probe: function called on probe | 34 | * @probe: function called on probe |
@@ -46,8 +44,6 @@ struct ccwgroup_device { | |||
46 | * @driver: embedded driver structure | 44 | * @driver: embedded driver structure |
47 | */ | 45 | */ |
48 | struct ccwgroup_driver { | 46 | struct ccwgroup_driver { |
49 | struct module *owner; | ||
50 | char *name; | ||
51 | int max_slaves; | 47 | int max_slaves; |
52 | unsigned long driver_id; | 48 | unsigned long driver_id; |
53 | 49 | ||
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h new file mode 100644 index 000000000000..7488e52efa97 --- /dev/null +++ b/arch/s390/include/asm/cmpxchg.h | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 1999, 2011 | ||
3 | * | ||
4 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
5 | */ | ||
6 | |||
7 | #ifndef __ASM_CMPXCHG_H | ||
8 | #define __ASM_CMPXCHG_H | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | |||
12 | extern void __xchg_called_with_bad_pointer(void); | ||
13 | |||
14 | static inline unsigned long __xchg(unsigned long x, void *ptr, int size) | ||
15 | { | ||
16 | unsigned long addr, old; | ||
17 | int shift; | ||
18 | |||
19 | switch (size) { | ||
20 | case 1: | ||
21 | addr = (unsigned long) ptr; | ||
22 | shift = (3 ^ (addr & 3)) << 3; | ||
23 | addr ^= addr & 3; | ||
24 | asm volatile( | ||
25 | " l %0,%4\n" | ||
26 | "0: lr 0,%0\n" | ||
27 | " nr 0,%3\n" | ||
28 | " or 0,%2\n" | ||
29 | " cs %0,0,%4\n" | ||
30 | " jl 0b\n" | ||
31 | : "=&d" (old), "=Q" (*(int *) addr) | ||
32 | : "d" (x << shift), "d" (~(255 << shift)), | ||
33 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
34 | return old >> shift; | ||
35 | case 2: | ||
36 | addr = (unsigned long) ptr; | ||
37 | shift = (2 ^ (addr & 2)) << 3; | ||
38 | addr ^= addr & 2; | ||
39 | asm volatile( | ||
40 | " l %0,%4\n" | ||
41 | "0: lr 0,%0\n" | ||
42 | " nr 0,%3\n" | ||
43 | " or 0,%2\n" | ||
44 | " cs %0,0,%4\n" | ||
45 | " jl 0b\n" | ||
46 | : "=&d" (old), "=Q" (*(int *) addr) | ||
47 | : "d" (x << shift), "d" (~(65535 << shift)), | ||
48 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
49 | return old >> shift; | ||
50 | case 4: | ||
51 | asm volatile( | ||
52 | " l %0,%3\n" | ||
53 | "0: cs %0,%2,%3\n" | ||
54 | " jl 0b\n" | ||
55 | : "=&d" (old), "=Q" (*(int *) ptr) | ||
56 | : "d" (x), "Q" (*(int *) ptr) | ||
57 | : "memory", "cc"); | ||
58 | return old; | ||
59 | #ifdef CONFIG_64BIT | ||
60 | case 8: | ||
61 | asm volatile( | ||
62 | " lg %0,%3\n" | ||
63 | "0: csg %0,%2,%3\n" | ||
64 | " jl 0b\n" | ||
65 | : "=&d" (old), "=m" (*(long *) ptr) | ||
66 | : "d" (x), "Q" (*(long *) ptr) | ||
67 | : "memory", "cc"); | ||
68 | return old; | ||
69 | #endif /* CONFIG_64BIT */ | ||
70 | } | ||
71 | __xchg_called_with_bad_pointer(); | ||
72 | return x; | ||
73 | } | ||
74 | |||
75 | #define xchg(ptr, x) \ | ||
76 | ({ \ | ||
77 | __typeof__(*(ptr)) __ret; \ | ||
78 | __ret = (__typeof__(*(ptr))) \ | ||
79 | __xchg((unsigned long)(x), (void *)(ptr), sizeof(*(ptr)));\ | ||
80 | __ret; \ | ||
81 | }) | ||
82 | |||
83 | /* | ||
84 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
85 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
86 | * indicated by comparing RETURN with OLD. | ||
87 | */ | ||
88 | |||
89 | #define __HAVE_ARCH_CMPXCHG | ||
90 | |||
91 | extern void __cmpxchg_called_with_bad_pointer(void); | ||
92 | |||
93 | static inline unsigned long __cmpxchg(void *ptr, unsigned long old, | ||
94 | unsigned long new, int size) | ||
95 | { | ||
96 | unsigned long addr, prev, tmp; | ||
97 | int shift; | ||
98 | |||
99 | switch (size) { | ||
100 | case 1: | ||
101 | addr = (unsigned long) ptr; | ||
102 | shift = (3 ^ (addr & 3)) << 3; | ||
103 | addr ^= addr & 3; | ||
104 | asm volatile( | ||
105 | " l %0,%2\n" | ||
106 | "0: nr %0,%5\n" | ||
107 | " lr %1,%0\n" | ||
108 | " or %0,%3\n" | ||
109 | " or %1,%4\n" | ||
110 | " cs %0,%1,%2\n" | ||
111 | " jnl 1f\n" | ||
112 | " xr %1,%0\n" | ||
113 | " nr %1,%5\n" | ||
114 | " jnz 0b\n" | ||
115 | "1:" | ||
116 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
117 | : "d" (old << shift), "d" (new << shift), | ||
118 | "d" (~(255 << shift)), "Q" (*(int *) ptr) | ||
119 | : "memory", "cc"); | ||
120 | return prev >> shift; | ||
121 | case 2: | ||
122 | addr = (unsigned long) ptr; | ||
123 | shift = (2 ^ (addr & 2)) << 3; | ||
124 | addr ^= addr & 2; | ||
125 | asm volatile( | ||
126 | " l %0,%2\n" | ||
127 | "0: nr %0,%5\n" | ||
128 | " lr %1,%0\n" | ||
129 | " or %0,%3\n" | ||
130 | " or %1,%4\n" | ||
131 | " cs %0,%1,%2\n" | ||
132 | " jnl 1f\n" | ||
133 | " xr %1,%0\n" | ||
134 | " nr %1,%5\n" | ||
135 | " jnz 0b\n" | ||
136 | "1:" | ||
137 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
138 | : "d" (old << shift), "d" (new << shift), | ||
139 | "d" (~(65535 << shift)), "Q" (*(int *) ptr) | ||
140 | : "memory", "cc"); | ||
141 | return prev >> shift; | ||
142 | case 4: | ||
143 | asm volatile( | ||
144 | " cs %0,%3,%1\n" | ||
145 | : "=&d" (prev), "=Q" (*(int *) ptr) | ||
146 | : "0" (old), "d" (new), "Q" (*(int *) ptr) | ||
147 | : "memory", "cc"); | ||
148 | return prev; | ||
149 | #ifdef CONFIG_64BIT | ||
150 | case 8: | ||
151 | asm volatile( | ||
152 | " csg %0,%3,%1\n" | ||
153 | : "=&d" (prev), "=Q" (*(long *) ptr) | ||
154 | : "0" (old), "d" (new), "Q" (*(long *) ptr) | ||
155 | : "memory", "cc"); | ||
156 | return prev; | ||
157 | #endif /* CONFIG_64BIT */ | ||
158 | } | ||
159 | __cmpxchg_called_with_bad_pointer(); | ||
160 | return old; | ||
161 | } | ||
162 | |||
163 | #define cmpxchg(ptr, o, n) \ | ||
164 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ | ||
165 | (unsigned long)(n), sizeof(*(ptr)))) | ||
166 | |||
167 | #ifdef CONFIG_64BIT | ||
168 | #define cmpxchg64(ptr, o, n) \ | ||
169 | ({ \ | ||
170 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
171 | cmpxchg((ptr), (o), (n)); \ | ||
172 | }) | ||
173 | #else /* CONFIG_64BIT */ | ||
174 | static inline unsigned long long __cmpxchg64(void *ptr, | ||
175 | unsigned long long old, | ||
176 | unsigned long long new) | ||
177 | { | ||
178 | register_pair rp_old = {.pair = old}; | ||
179 | register_pair rp_new = {.pair = new}; | ||
180 | |||
181 | asm volatile( | ||
182 | " cds %0,%2,%1" | ||
183 | : "+&d" (rp_old), "=Q" (ptr) | ||
184 | : "d" (rp_new), "Q" (ptr) | ||
185 | : "cc"); | ||
186 | return rp_old.pair; | ||
187 | } | ||
188 | #define cmpxchg64(ptr, o, n) \ | ||
189 | ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ | ||
190 | (unsigned long long)(o), \ | ||
191 | (unsigned long long)(n))) | ||
192 | #endif /* CONFIG_64BIT */ | ||
193 | |||
194 | #include <asm-generic/cmpxchg-local.h> | ||
195 | |||
196 | static inline unsigned long __cmpxchg_local(void *ptr, | ||
197 | unsigned long old, | ||
198 | unsigned long new, int size) | ||
199 | { | ||
200 | switch (size) { | ||
201 | case 1: | ||
202 | case 2: | ||
203 | case 4: | ||
204 | #ifdef CONFIG_64BIT | ||
205 | case 8: | ||
206 | #endif | ||
207 | return __cmpxchg(ptr, old, new, size); | ||
208 | default: | ||
209 | return __cmpxchg_local_generic(ptr, old, new, size); | ||
210 | } | ||
211 | |||
212 | return old; | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make | ||
217 | * them available. | ||
218 | */ | ||
219 | #define cmpxchg_local(ptr, o, n) \ | ||
220 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ | ||
221 | (unsigned long)(n), sizeof(*(ptr)))) | ||
222 | |||
223 | #define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n)) | ||
224 | |||
225 | #endif /* __ASM_CMPXCHG_H */ | ||
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 8f8d759f6a7b..d382629a0172 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/setup.h> | 14 | #include <asm/setup.h> |
15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
16 | #include <asm/lowcore.h> | 16 | #include <asm/lowcore.h> |
17 | #include <asm/cmpxchg.h> | ||
17 | 18 | ||
18 | #ifdef __KERNEL__ | 19 | #ifdef __KERNEL__ |
19 | 20 | ||
@@ -120,161 +121,6 @@ extern int memcpy_real(void *, void *, size_t); | |||
120 | 121 | ||
121 | #define nop() asm volatile("nop") | 122 | #define nop() asm volatile("nop") |
122 | 123 | ||
123 | #define xchg(ptr,x) \ | ||
124 | ({ \ | ||
125 | __typeof__(*(ptr)) __ret; \ | ||
126 | __ret = (__typeof__(*(ptr))) \ | ||
127 | __xchg((unsigned long)(x), (void *)(ptr),sizeof(*(ptr))); \ | ||
128 | __ret; \ | ||
129 | }) | ||
130 | |||
131 | extern void __xchg_called_with_bad_pointer(void); | ||
132 | |||
133 | static inline unsigned long __xchg(unsigned long x, void * ptr, int size) | ||
134 | { | ||
135 | unsigned long addr, old; | ||
136 | int shift; | ||
137 | |||
138 | switch (size) { | ||
139 | case 1: | ||
140 | addr = (unsigned long) ptr; | ||
141 | shift = (3 ^ (addr & 3)) << 3; | ||
142 | addr ^= addr & 3; | ||
143 | asm volatile( | ||
144 | " l %0,%4\n" | ||
145 | "0: lr 0,%0\n" | ||
146 | " nr 0,%3\n" | ||
147 | " or 0,%2\n" | ||
148 | " cs %0,0,%4\n" | ||
149 | " jl 0b\n" | ||
150 | : "=&d" (old), "=Q" (*(int *) addr) | ||
151 | : "d" (x << shift), "d" (~(255 << shift)), | ||
152 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
153 | return old >> shift; | ||
154 | case 2: | ||
155 | addr = (unsigned long) ptr; | ||
156 | shift = (2 ^ (addr & 2)) << 3; | ||
157 | addr ^= addr & 2; | ||
158 | asm volatile( | ||
159 | " l %0,%4\n" | ||
160 | "0: lr 0,%0\n" | ||
161 | " nr 0,%3\n" | ||
162 | " or 0,%2\n" | ||
163 | " cs %0,0,%4\n" | ||
164 | " jl 0b\n" | ||
165 | : "=&d" (old), "=Q" (*(int *) addr) | ||
166 | : "d" (x << shift), "d" (~(65535 << shift)), | ||
167 | "Q" (*(int *) addr) : "memory", "cc", "0"); | ||
168 | return old >> shift; | ||
169 | case 4: | ||
170 | asm volatile( | ||
171 | " l %0,%3\n" | ||
172 | "0: cs %0,%2,%3\n" | ||
173 | " jl 0b\n" | ||
174 | : "=&d" (old), "=Q" (*(int *) ptr) | ||
175 | : "d" (x), "Q" (*(int *) ptr) | ||
176 | : "memory", "cc"); | ||
177 | return old; | ||
178 | #ifdef __s390x__ | ||
179 | case 8: | ||
180 | asm volatile( | ||
181 | " lg %0,%3\n" | ||
182 | "0: csg %0,%2,%3\n" | ||
183 | " jl 0b\n" | ||
184 | : "=&d" (old), "=m" (*(long *) ptr) | ||
185 | : "d" (x), "Q" (*(long *) ptr) | ||
186 | : "memory", "cc"); | ||
187 | return old; | ||
188 | #endif /* __s390x__ */ | ||
189 | } | ||
190 | __xchg_called_with_bad_pointer(); | ||
191 | return x; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
196 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
197 | * indicated by comparing RETURN with OLD. | ||
198 | */ | ||
199 | |||
200 | #define __HAVE_ARCH_CMPXCHG 1 | ||
201 | |||
202 | #define cmpxchg(ptr, o, n) \ | ||
203 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ | ||
204 | (unsigned long)(n), sizeof(*(ptr)))) | ||
205 | |||
206 | extern void __cmpxchg_called_with_bad_pointer(void); | ||
207 | |||
208 | static inline unsigned long | ||
209 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | ||
210 | { | ||
211 | unsigned long addr, prev, tmp; | ||
212 | int shift; | ||
213 | |||
214 | switch (size) { | ||
215 | case 1: | ||
216 | addr = (unsigned long) ptr; | ||
217 | shift = (3 ^ (addr & 3)) << 3; | ||
218 | addr ^= addr & 3; | ||
219 | asm volatile( | ||
220 | " l %0,%2\n" | ||
221 | "0: nr %0,%5\n" | ||
222 | " lr %1,%0\n" | ||
223 | " or %0,%3\n" | ||
224 | " or %1,%4\n" | ||
225 | " cs %0,%1,%2\n" | ||
226 | " jnl 1f\n" | ||
227 | " xr %1,%0\n" | ||
228 | " nr %1,%5\n" | ||
229 | " jnz 0b\n" | ||
230 | "1:" | ||
231 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
232 | : "d" (old << shift), "d" (new << shift), | ||
233 | "d" (~(255 << shift)), "Q" (*(int *) ptr) | ||
234 | : "memory", "cc"); | ||
235 | return prev >> shift; | ||
236 | case 2: | ||
237 | addr = (unsigned long) ptr; | ||
238 | shift = (2 ^ (addr & 2)) << 3; | ||
239 | addr ^= addr & 2; | ||
240 | asm volatile( | ||
241 | " l %0,%2\n" | ||
242 | "0: nr %0,%5\n" | ||
243 | " lr %1,%0\n" | ||
244 | " or %0,%3\n" | ||
245 | " or %1,%4\n" | ||
246 | " cs %0,%1,%2\n" | ||
247 | " jnl 1f\n" | ||
248 | " xr %1,%0\n" | ||
249 | " nr %1,%5\n" | ||
250 | " jnz 0b\n" | ||
251 | "1:" | ||
252 | : "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr) | ||
253 | : "d" (old << shift), "d" (new << shift), | ||
254 | "d" (~(65535 << shift)), "Q" (*(int *) ptr) | ||
255 | : "memory", "cc"); | ||
256 | return prev >> shift; | ||
257 | case 4: | ||
258 | asm volatile( | ||
259 | " cs %0,%3,%1\n" | ||
260 | : "=&d" (prev), "=Q" (*(int *) ptr) | ||
261 | : "0" (old), "d" (new), "Q" (*(int *) ptr) | ||
262 | : "memory", "cc"); | ||
263 | return prev; | ||
264 | #ifdef __s390x__ | ||
265 | case 8: | ||
266 | asm volatile( | ||
267 | " csg %0,%3,%1\n" | ||
268 | : "=&d" (prev), "=Q" (*(long *) ptr) | ||
269 | : "0" (old), "d" (new), "Q" (*(long *) ptr) | ||
270 | : "memory", "cc"); | ||
271 | return prev; | ||
272 | #endif /* __s390x__ */ | ||
273 | } | ||
274 | __cmpxchg_called_with_bad_pointer(); | ||
275 | return old; | ||
276 | } | ||
277 | |||
278 | /* | 124 | /* |
279 | * Force strict CPU ordering. | 125 | * Force strict CPU ordering. |
280 | * And yes, this is required on UP too when we're talking | 126 | * And yes, this is required on UP too when we're talking |
@@ -353,46 +199,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
353 | __ctl_load(__dummy, cr, cr); \ | 199 | __ctl_load(__dummy, cr, cr); \ |
354 | }) | 200 | }) |
355 | 201 | ||
356 | #include <linux/irqflags.h> | ||
357 | |||
358 | #include <asm-generic/cmpxchg-local.h> | ||
359 | |||
360 | static inline unsigned long __cmpxchg_local(volatile void *ptr, | ||
361 | unsigned long old, | ||
362 | unsigned long new, int size) | ||
363 | { | ||
364 | switch (size) { | ||
365 | case 1: | ||
366 | case 2: | ||
367 | case 4: | ||
368 | #ifdef __s390x__ | ||
369 | case 8: | ||
370 | #endif | ||
371 | return __cmpxchg(ptr, old, new, size); | ||
372 | default: | ||
373 | return __cmpxchg_local_generic(ptr, old, new, size); | ||
374 | } | ||
375 | |||
376 | return old; | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make | ||
381 | * them available. | ||
382 | */ | ||
383 | #define cmpxchg_local(ptr, o, n) \ | ||
384 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ | ||
385 | (unsigned long)(n), sizeof(*(ptr)))) | ||
386 | #ifdef __s390x__ | ||
387 | #define cmpxchg64_local(ptr, o, n) \ | ||
388 | ({ \ | ||
389 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
390 | cmpxchg_local((ptr), (o), (n)); \ | ||
391 | }) | ||
392 | #else | ||
393 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | ||
394 | #endif | ||
395 | |||
396 | /* | 202 | /* |
397 | * Use to set psw mask except for the first byte which | 203 | * Use to set psw mask except for the first byte which |
398 | * won't be changed by this function. | 204 | * won't be changed by this function. |
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index 1049ef27c15e..e82152572377 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h | |||
@@ -272,7 +272,11 @@ | |||
272 | #define __NR_fanotify_init 332 | 272 | #define __NR_fanotify_init 332 |
273 | #define __NR_fanotify_mark 333 | 273 | #define __NR_fanotify_mark 333 |
274 | #define __NR_prlimit64 334 | 274 | #define __NR_prlimit64 334 |
275 | #define NR_syscalls 335 | 275 | #define __NR_name_to_handle_at 335 |
276 | #define __NR_open_by_handle_at 336 | ||
277 | #define __NR_clock_adjtime 337 | ||
278 | #define __NR_syncfs 338 | ||
279 | #define NR_syscalls 339 | ||
276 | 280 | ||
277 | /* | 281 | /* |
278 | * There are some system calls that are not present on 64 bit, some | 282 | * There are some system calls that are not present on 64 bit, some |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 8e60fb23b90d..1dc96ea08fa8 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1877,3 +1877,30 @@ sys_prlimit64_wrapper: | |||
1877 | llgtr %r4,%r4 # const struct rlimit64 __user * | 1877 | llgtr %r4,%r4 # const struct rlimit64 __user * |
1878 | llgtr %r5,%r5 # struct rlimit64 __user * | 1878 | llgtr %r5,%r5 # struct rlimit64 __user * |
1879 | jg sys_prlimit64 # branch to system call | 1879 | jg sys_prlimit64 # branch to system call |
1880 | |||
1881 | .globl sys_name_to_handle_at_wrapper | ||
1882 | sys_name_to_handle_at_wrapper: | ||
1883 | lgfr %r2,%r2 # int | ||
1884 | llgtr %r3,%r3 # const char __user * | ||
1885 | llgtr %r4,%r4 # struct file_handle __user * | ||
1886 | llgtr %r5,%r5 # int __user * | ||
1887 | lgfr %r6,%r6 # int | ||
1888 | jg sys_name_to_handle_at | ||
1889 | |||
1890 | .globl compat_sys_open_by_handle_at_wrapper | ||
1891 | compat_sys_open_by_handle_at_wrapper: | ||
1892 | lgfr %r2,%r2 # int | ||
1893 | llgtr %r3,%r3 # struct file_handle __user * | ||
1894 | lgfr %r4,%r4 # int | ||
1895 | jg compat_sys_open_by_handle_at | ||
1896 | |||
1897 | .globl compat_sys_clock_adjtime_wrapper | ||
1898 | compat_sys_clock_adjtime_wrapper: | ||
1899 | lgfr %r2,%r2 # clockid_t (int) | ||
1900 | llgtr %r3,%r3 # struct compat_timex __user * | ||
1901 | jg compat_sys_clock_adjtime | ||
1902 | |||
1903 | .globl sys_syncfs_wrapper | ||
1904 | sys_syncfs_wrapper: | ||
1905 | lgfr %r2,%r2 # int | ||
1906 | jg sys_syncfs | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 3b7e7dddc324..068f8465c4ee 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -94,6 +94,7 @@ static noinline __init void create_kernel_nss(void) | |||
94 | unsigned int sinitrd_pfn, einitrd_pfn; | 94 | unsigned int sinitrd_pfn, einitrd_pfn; |
95 | #endif | 95 | #endif |
96 | int response; | 96 | int response; |
97 | int hlen; | ||
97 | size_t len; | 98 | size_t len; |
98 | char *savesys_ptr; | 99 | char *savesys_ptr; |
99 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 100 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
@@ -124,24 +125,27 @@ static noinline __init void create_kernel_nss(void) | |||
124 | end_pfn = PFN_UP(__pa(&_end)); | 125 | end_pfn = PFN_UP(__pa(&_end)); |
125 | min_size = end_pfn << 2; | 126 | min_size = end_pfn << 2; |
126 | 127 | ||
127 | sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", | 128 | hlen = snprintf(defsys_cmd, DEFSYS_CMD_SIZE, |
128 | kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1, | 129 | "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", |
129 | eshared_pfn, end_pfn); | 130 | kernel_nss_name, stext_pfn - 1, stext_pfn, |
131 | eshared_pfn - 1, eshared_pfn, end_pfn); | ||
130 | 132 | ||
131 | #ifdef CONFIG_BLK_DEV_INITRD | 133 | #ifdef CONFIG_BLK_DEV_INITRD |
132 | if (INITRD_START && INITRD_SIZE) { | 134 | if (INITRD_START && INITRD_SIZE) { |
133 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); | 135 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); |
134 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); | 136 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); |
135 | min_size = einitrd_pfn << 2; | 137 | min_size = einitrd_pfn << 2; |
136 | sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd, | 138 | hlen += snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen, |
137 | sinitrd_pfn, einitrd_pfn); | 139 | " EW %.5X-%.5X", sinitrd_pfn, einitrd_pfn); |
138 | } | 140 | } |
139 | #endif | 141 | #endif |
140 | 142 | ||
141 | sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK PARMREGS=0-13", | 143 | snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen, |
142 | defsys_cmd, min_size); | 144 | " EW MINSIZE=%.7iK PARMREGS=0-13", min_size); |
143 | sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", | 145 | defsys_cmd[DEFSYS_CMD_SIZE - 1] = '\0'; |
144 | kernel_nss_name, kernel_nss_name); | 146 | snprintf(savesys_cmd, SAVESYS_CMD_SIZE, "SAVESYS %s \n IPL %s", |
147 | kernel_nss_name, kernel_nss_name); | ||
148 | savesys_cmd[SAVESYS_CMD_SIZE - 1] = '\0'; | ||
145 | 149 | ||
146 | __cpcmd(defsys_cmd, NULL, 0, &response); | 150 | __cpcmd(defsys_cmd, NULL, 0, &response); |
147 | 151 | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 6f6350826c81..ed183c2c6168 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -102,16 +102,6 @@ EXPORT_SYMBOL(lowcore_ptr); | |||
102 | 102 | ||
103 | #include <asm/setup.h> | 103 | #include <asm/setup.h> |
104 | 104 | ||
105 | static struct resource code_resource = { | ||
106 | .name = "Kernel code", | ||
107 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
108 | }; | ||
109 | |||
110 | static struct resource data_resource = { | ||
111 | .name = "Kernel data", | ||
112 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
113 | }; | ||
114 | |||
115 | /* | 105 | /* |
116 | * condev= and conmode= setup parameter. | 106 | * condev= and conmode= setup parameter. |
117 | */ | 107 | */ |
@@ -436,21 +426,43 @@ setup_lowcore(void) | |||
436 | lowcore_ptr[0] = lc; | 426 | lowcore_ptr[0] = lc; |
437 | } | 427 | } |
438 | 428 | ||
439 | static void __init | 429 | static struct resource code_resource = { |
440 | setup_resources(void) | 430 | .name = "Kernel code", |
431 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
432 | }; | ||
433 | |||
434 | static struct resource data_resource = { | ||
435 | .name = "Kernel data", | ||
436 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
437 | }; | ||
438 | |||
439 | static struct resource bss_resource = { | ||
440 | .name = "Kernel bss", | ||
441 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM, | ||
442 | }; | ||
443 | |||
444 | static struct resource __initdata *standard_resources[] = { | ||
445 | &code_resource, | ||
446 | &data_resource, | ||
447 | &bss_resource, | ||
448 | }; | ||
449 | |||
450 | static void __init setup_resources(void) | ||
441 | { | 451 | { |
442 | struct resource *res, *sub_res; | 452 | struct resource *res, *std_res, *sub_res; |
443 | int i; | 453 | int i, j; |
444 | 454 | ||
445 | code_resource.start = (unsigned long) &_text; | 455 | code_resource.start = (unsigned long) &_text; |
446 | code_resource.end = (unsigned long) &_etext - 1; | 456 | code_resource.end = (unsigned long) &_etext - 1; |
447 | data_resource.start = (unsigned long) &_etext; | 457 | data_resource.start = (unsigned long) &_etext; |
448 | data_resource.end = (unsigned long) &_edata - 1; | 458 | data_resource.end = (unsigned long) &_edata - 1; |
459 | bss_resource.start = (unsigned long) &__bss_start; | ||
460 | bss_resource.end = (unsigned long) &__bss_stop - 1; | ||
449 | 461 | ||
450 | for (i = 0; i < MEMORY_CHUNKS; i++) { | 462 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
451 | if (!memory_chunk[i].size) | 463 | if (!memory_chunk[i].size) |
452 | continue; | 464 | continue; |
453 | res = alloc_bootmem_low(sizeof(struct resource)); | 465 | res = alloc_bootmem_low(sizeof(*res)); |
454 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | 466 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; |
455 | switch (memory_chunk[i].type) { | 467 | switch (memory_chunk[i].type) { |
456 | case CHUNK_READ_WRITE: | 468 | case CHUNK_READ_WRITE: |
@@ -464,40 +476,24 @@ setup_resources(void) | |||
464 | res->name = "reserved"; | 476 | res->name = "reserved"; |
465 | } | 477 | } |
466 | res->start = memory_chunk[i].addr; | 478 | res->start = memory_chunk[i].addr; |
467 | res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; | 479 | res->end = res->start + memory_chunk[i].size - 1; |
468 | request_resource(&iomem_resource, res); | 480 | request_resource(&iomem_resource, res); |
469 | 481 | ||
470 | if (code_resource.start >= res->start && | 482 | for (j = 0; j < ARRAY_SIZE(standard_resources); j++) { |
471 | code_resource.start <= res->end && | 483 | std_res = standard_resources[j]; |
472 | code_resource.end > res->end) { | 484 | if (std_res->start < res->start || |
473 | sub_res = alloc_bootmem_low(sizeof(struct resource)); | 485 | std_res->start > res->end) |
474 | memcpy(sub_res, &code_resource, | 486 | continue; |
475 | sizeof(struct resource)); | 487 | if (std_res->end > res->end) { |
476 | sub_res->end = res->end; | 488 | sub_res = alloc_bootmem_low(sizeof(*sub_res)); |
477 | code_resource.start = res->end + 1; | 489 | *sub_res = *std_res; |
478 | request_resource(res, sub_res); | 490 | sub_res->end = res->end; |
479 | } | 491 | std_res->start = res->end + 1; |
480 | 492 | request_resource(res, sub_res); | |
481 | if (code_resource.start >= res->start && | 493 | } else { |
482 | code_resource.start <= res->end && | 494 | request_resource(res, std_res); |
483 | code_resource.end <= res->end) | 495 | } |
484 | request_resource(res, &code_resource); | ||
485 | |||
486 | if (data_resource.start >= res->start && | ||
487 | data_resource.start <= res->end && | ||
488 | data_resource.end > res->end) { | ||
489 | sub_res = alloc_bootmem_low(sizeof(struct resource)); | ||
490 | memcpy(sub_res, &data_resource, | ||
491 | sizeof(struct resource)); | ||
492 | sub_res->end = res->end; | ||
493 | data_resource.start = res->end + 1; | ||
494 | request_resource(res, sub_res); | ||
495 | } | 496 | } |
496 | |||
497 | if (data_resource.start >= res->start && | ||
498 | data_resource.start <= res->end && | ||
499 | data_resource.end <= res->end) | ||
500 | request_resource(res, &data_resource); | ||
501 | } | 497 | } |
502 | } | 498 | } |
503 | 499 | ||
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index a8fee1b14395..9c65fd4ddce0 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -343,3 +343,7 @@ SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper) | |||
343 | SYSCALL(sys_fanotify_init,sys_fanotify_init,sys_fanotify_init_wrapper) | 343 | SYSCALL(sys_fanotify_init,sys_fanotify_init,sys_fanotify_init_wrapper) |
344 | SYSCALL(sys_fanotify_mark,sys_fanotify_mark,sys_fanotify_mark_wrapper) | 344 | SYSCALL(sys_fanotify_mark,sys_fanotify_mark,sys_fanotify_mark_wrapper) |
345 | SYSCALL(sys_prlimit64,sys_prlimit64,sys_prlimit64_wrapper) | 345 | SYSCALL(sys_prlimit64,sys_prlimit64,sys_prlimit64_wrapper) |
346 | SYSCALL(sys_name_to_handle_at,sys_name_to_handle_at,sys_name_to_handle_at_wrapper) /* 335 */ | ||
347 | SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at_wrapper) | ||
348 | SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper) | ||
349 | SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper) | ||
diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile index d698cddcfbdd..524c4b615821 100644 --- a/arch/s390/oprofile/Makefile +++ b/arch/s390/oprofile/Makefile | |||
@@ -6,4 +6,5 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ | |||
6 | oprofilefs.o oprofile_stats.o \ | 6 | oprofilefs.o oprofile_stats.o \ |
7 | timer_int.o ) | 7 | timer_int.o ) |
8 | 8 | ||
9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o hwsampler.o | 9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o |
10 | oprofile-$(CONFIG_64BIT) += hwsampler.o | ||
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 16c76def4a9d..c63d7e58352b 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c | |||
@@ -18,6 +18,11 @@ | |||
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | 19 | ||
20 | #include "../../../drivers/oprofile/oprof.h" | 20 | #include "../../../drivers/oprofile/oprof.h" |
21 | |||
22 | extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
23 | |||
24 | #ifdef CONFIG_64BIT | ||
25 | |||
21 | #include "hwsampler.h" | 26 | #include "hwsampler.h" |
22 | 27 | ||
23 | #define DEFAULT_INTERVAL 4096 | 28 | #define DEFAULT_INTERVAL 4096 |
@@ -37,8 +42,6 @@ static int hwsampler_running; /* start_mutex must be held to change */ | |||
37 | 42 | ||
38 | static struct oprofile_operations timer_ops; | 43 | static struct oprofile_operations timer_ops; |
39 | 44 | ||
40 | extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
41 | |||
42 | static int oprofile_hwsampler_start(void) | 45 | static int oprofile_hwsampler_start(void) |
43 | { | 46 | { |
44 | int retval; | 47 | int retval; |
@@ -172,14 +175,22 @@ static void oprofile_hwsampler_exit(void) | |||
172 | hwsampler_shutdown(); | 175 | hwsampler_shutdown(); |
173 | } | 176 | } |
174 | 177 | ||
178 | #endif /* CONFIG_64BIT */ | ||
179 | |||
175 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 180 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
176 | { | 181 | { |
177 | ops->backtrace = s390_backtrace; | 182 | ops->backtrace = s390_backtrace; |
178 | 183 | ||
184 | #ifdef CONFIG_64BIT | ||
179 | return oprofile_hwsampler_init(ops); | 185 | return oprofile_hwsampler_init(ops); |
186 | #else | ||
187 | return -ENODEV; | ||
188 | #endif | ||
180 | } | 189 | } |
181 | 190 | ||
182 | void oprofile_arch_exit(void) | 191 | void oprofile_arch_exit(void) |
183 | { | 192 | { |
193 | #ifdef CONFIG_64BIT | ||
184 | oprofile_hwsampler_exit(); | 194 | oprofile_hwsampler_exit(); |
195 | #endif | ||
185 | } | 196 | } |
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 8237dd4dfeb4..4e236391b635 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c | |||
@@ -145,6 +145,10 @@ static int __devinit clock_probe(struct platform_device *op) | |||
145 | if (!model) | 145 | if (!model) |
146 | return -ENODEV; | 146 | return -ENODEV; |
147 | 147 | ||
148 | /* Only the primary RTC has an address property */ | ||
149 | if (!of_find_property(dp, "address", NULL)) | ||
150 | return -ENODEV; | ||
151 | |||
148 | m48t59_rtc.resource = &op->resource[0]; | 152 | m48t59_rtc.resource = &op->resource[0]; |
149 | if (!strcmp(model, "mk48t02")) { | 153 | if (!strcmp(model, "mk48t02")) { |
150 | /* Map the clock register io area read-only */ | 154 | /* Map the clock register io area read-only */ |
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index 6d0e02c4fe09..4c31e2b6e71b 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c | |||
@@ -75,7 +75,7 @@ void __init kmap_init(void) | |||
75 | kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); | 75 | kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); |
76 | } | 76 | } |
77 | 77 | ||
78 | void show_mem(void) | 78 | void show_mem(unsigned int filter) |
79 | { | 79 | { |
80 | printk("Mem-info:\n"); | 80 | printk("Mem-info:\n"); |
81 | show_free_areas(); | 81 | show_free_areas(); |
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 1a2b36f8866d..de7d8e21e01d 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c | |||
@@ -41,7 +41,7 @@ | |||
41 | * The normal show_free_areas() is too verbose on Tile, with dozens | 41 | * The normal show_free_areas() is too verbose on Tile, with dozens |
42 | * of processors and often four NUMA zones each with high and lowmem. | 42 | * of processors and often four NUMA zones each with high and lowmem. |
43 | */ | 43 | */ |
44 | void show_mem(void) | 44 | void show_mem(unsigned int filter) |
45 | { | 45 | { |
46 | struct zone *zone; | 46 | struct zone *zone; |
47 | 47 | ||
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 1e78940218c0..109ddc0071c6 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common | |||
@@ -8,6 +8,7 @@ config UML | |||
8 | default y | 8 | default y |
9 | select HAVE_GENERIC_HARDIRQS | 9 | select HAVE_GENERIC_HARDIRQS |
10 | select GENERIC_HARDIRQS_NO_DEPRECATED | 10 | select GENERIC_HARDIRQS_NO_DEPRECATED |
11 | select GENERIC_IRQ_SHOW | ||
11 | 12 | ||
12 | config MMU | 13 | config MMU |
13 | bool | 14 | bool |
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 64cfea80cfe2..9e485c770308 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -18,52 +18,6 @@ | |||
18 | #include "os.h" | 18 | #include "os.h" |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Generic, controller-independent functions: | ||
22 | */ | ||
23 | |||
24 | int show_interrupts(struct seq_file *p, void *v) | ||
25 | { | ||
26 | int i = *(loff_t *) v, j; | ||
27 | struct irqaction * action; | ||
28 | unsigned long flags; | ||
29 | |||
30 | if (i == 0) { | ||
31 | seq_printf(p, " "); | ||
32 | for_each_online_cpu(j) | ||
33 | seq_printf(p, "CPU%d ",j); | ||
34 | seq_putc(p, '\n'); | ||
35 | } | ||
36 | |||
37 | if (i < NR_IRQS) { | ||
38 | struct irq_desc *desc = irq_to_desc(i); | ||
39 | |||
40 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
41 | action = desc->action; | ||
42 | if (!action) | ||
43 | goto skip; | ||
44 | seq_printf(p, "%3d: ",i); | ||
45 | #ifndef CONFIG_SMP | ||
46 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
47 | #else | ||
48 | for_each_online_cpu(j) | ||
49 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | ||
50 | #endif | ||
51 | seq_printf(p, " %14s", get_irq_desc_chip(desc)->name); | ||
52 | seq_printf(p, " %s", action->name); | ||
53 | |||
54 | for (action=action->next; action; action = action->next) | ||
55 | seq_printf(p, ", %s", action->name); | ||
56 | |||
57 | seq_putc(p, '\n'); | ||
58 | skip: | ||
59 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
60 | } else if (i == NR_IRQS) | ||
61 | seq_putc(p, '\n'); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * This list is accessed under irq_lock, except in sigio_handler, | 21 | * This list is accessed under irq_lock, except in sigio_handler, |
68 | * where it is safe from being modified. IRQ handlers won't change it - | 22 | * where it is safe from being modified. IRQ handlers won't change it - |
69 | * if an IRQ source has vanished, it will be freed by free_irqs just | 23 | * if an IRQ source has vanished, it will be freed by free_irqs just |
@@ -390,11 +344,10 @@ void __init init_IRQ(void) | |||
390 | { | 344 | { |
391 | int i; | 345 | int i; |
392 | 346 | ||
393 | set_irq_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); | 347 | irq_set_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); |
394 | 348 | ||
395 | for (i = 1; i < NR_IRQS; i++) { | 349 | for (i = 1; i < NR_IRQS; i++) |
396 | set_irq_chip_and_handler(i, &normal_irq_type, handle_edge_irq); | 350 | irq_set_chip_and_handler(i, &normal_irq_type, handle_edge_irq); |
397 | } | ||
398 | } | 351 | } |
399 | 352 | ||
400 | /* | 353 | /* |
diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c index 3dbe3709b69d..1fc02633f700 100644 --- a/arch/unicore32/mm/init.c +++ b/arch/unicore32/mm/init.c | |||
@@ -55,7 +55,7 @@ early_param("initrd", early_initrd); | |||
55 | */ | 55 | */ |
56 | struct meminfo meminfo; | 56 | struct meminfo meminfo; |
57 | 57 | ||
58 | void show_mem(void) | 58 | void show_mem(unsigned int filter) |
59 | { | 59 | { |
60 | int free = 0, total = 0, reserved = 0; | 60 | int free = 0, total = 0, reserved = 0; |
61 | int shared = 0, cached = 0, slab = 0, i; | 61 | int shared = 0, cached = 0, slab = 0, i; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 140e254fe546..cc6c53a95bfd 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -71,6 +71,7 @@ config X86 | |||
71 | select GENERIC_IRQ_SHOW | 71 | select GENERIC_IRQ_SHOW |
72 | select IRQ_FORCED_THREADING | 72 | select IRQ_FORCED_THREADING |
73 | select USE_GENERIC_SMP_HELPERS if SMP | 73 | select USE_GENERIC_SMP_HELPERS if SMP |
74 | select ARCH_NO_SYSDEV_OPS | ||
74 | 75 | ||
75 | config INSTRUCTION_DECODER | 76 | config INSTRUCTION_DECODER |
76 | def_bool (KPROBES || PERF_EVENTS) | 77 | def_bool (KPROBES || PERF_EVENTS) |
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index a09e1f052d84..d68fca61ad91 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <linux/stringify.h> | 45 | #include <linux/stringify.h> |
46 | 46 | ||
47 | #ifdef CONFIG_SMP | 47 | #ifdef CONFIG_SMP |
48 | #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x | 48 | #define __percpu_prefix "%%"__stringify(__percpu_seg)":" |
49 | #define __my_cpu_offset percpu_read(this_cpu_off) | 49 | #define __my_cpu_offset percpu_read(this_cpu_off) |
50 | 50 | ||
51 | /* | 51 | /* |
@@ -62,9 +62,11 @@ | |||
62 | (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \ | 62 | (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \ |
63 | }) | 63 | }) |
64 | #else | 64 | #else |
65 | #define __percpu_arg(x) "%P" #x | 65 | #define __percpu_prefix "" |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | #define __percpu_arg(x) __percpu_prefix "%P" #x | ||
69 | |||
68 | /* | 70 | /* |
69 | * Initialized pointers to per-cpu variables needed for the boot | 71 | * Initialized pointers to per-cpu variables needed for the boot |
70 | * processor need to use these macros to get the proper address | 72 | * processor need to use these macros to get the proper address |
@@ -507,6 +509,11 @@ do { \ | |||
507 | * it in software. The address used in the cmpxchg16 instruction must be | 509 | * it in software. The address used in the cmpxchg16 instruction must be |
508 | * aligned to a 16 byte boundary. | 510 | * aligned to a 16 byte boundary. |
509 | */ | 511 | */ |
512 | #ifdef CONFIG_SMP | ||
513 | #define CMPXCHG16B_EMU_CALL "call this_cpu_cmpxchg16b_emu\n\t" P6_NOP3 | ||
514 | #else | ||
515 | #define CMPXCHG16B_EMU_CALL "call this_cpu_cmpxchg16b_emu\n\t" P6_NOP2 | ||
516 | #endif | ||
510 | #define percpu_cmpxchg16b_double(pcp1, o1, o2, n1, n2) \ | 517 | #define percpu_cmpxchg16b_double(pcp1, o1, o2, n1, n2) \ |
511 | ({ \ | 518 | ({ \ |
512 | char __ret; \ | 519 | char __ret; \ |
@@ -515,12 +522,12 @@ do { \ | |||
515 | typeof(o2) __o2 = o2; \ | 522 | typeof(o2) __o2 = o2; \ |
516 | typeof(o2) __n2 = n2; \ | 523 | typeof(o2) __n2 = n2; \ |
517 | typeof(o2) __dummy; \ | 524 | typeof(o2) __dummy; \ |
518 | alternative_io("call this_cpu_cmpxchg16b_emu\n\t" P6_NOP4, \ | 525 | alternative_io(CMPXCHG16B_EMU_CALL, \ |
519 | "cmpxchg16b %%gs:(%%rsi)\n\tsetz %0\n\t", \ | 526 | "cmpxchg16b " __percpu_prefix "(%%rsi)\n\tsetz %0\n\t", \ |
520 | X86_FEATURE_CX16, \ | 527 | X86_FEATURE_CX16, \ |
521 | ASM_OUTPUT2("=a"(__ret), "=d"(__dummy)), \ | 528 | ASM_OUTPUT2("=a"(__ret), "=d"(__dummy)), \ |
522 | "S" (&pcp1), "b"(__n1), "c"(__n2), \ | 529 | "S" (&pcp1), "b"(__n1), "c"(__n2), \ |
523 | "a"(__o1), "d"(__o2)); \ | 530 | "a"(__o1), "d"(__o2) : "memory"); \ |
524 | __ret; \ | 531 | __ret; \ |
525 | }) | 532 | }) |
526 | 533 | ||
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 6e11c8134158..246d727b65b7 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/acpi.h> | 21 | #include <linux/acpi.h> |
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/sysdev.h> | 24 | #include <linux/syscore_ops.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/msi.h> | 26 | #include <linux/msi.h> |
27 | #include <asm/pci-direct.h> | 27 | #include <asm/pci-direct.h> |
@@ -1260,7 +1260,7 @@ static void disable_iommus(void) | |||
1260 | * disable suspend until real resume implemented | 1260 | * disable suspend until real resume implemented |
1261 | */ | 1261 | */ |
1262 | 1262 | ||
1263 | static int amd_iommu_resume(struct sys_device *dev) | 1263 | static void amd_iommu_resume(void) |
1264 | { | 1264 | { |
1265 | struct amd_iommu *iommu; | 1265 | struct amd_iommu *iommu; |
1266 | 1266 | ||
@@ -1276,11 +1276,9 @@ static int amd_iommu_resume(struct sys_device *dev) | |||
1276 | */ | 1276 | */ |
1277 | amd_iommu_flush_all_devices(); | 1277 | amd_iommu_flush_all_devices(); |
1278 | amd_iommu_flush_all_domains(); | 1278 | amd_iommu_flush_all_domains(); |
1279 | |||
1280 | return 0; | ||
1281 | } | 1279 | } |
1282 | 1280 | ||
1283 | static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state) | 1281 | static int amd_iommu_suspend(void) |
1284 | { | 1282 | { |
1285 | /* disable IOMMUs to go out of the way for BIOS */ | 1283 | /* disable IOMMUs to go out of the way for BIOS */ |
1286 | disable_iommus(); | 1284 | disable_iommus(); |
@@ -1288,17 +1286,11 @@ static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state) | |||
1288 | return 0; | 1286 | return 0; |
1289 | } | 1287 | } |
1290 | 1288 | ||
1291 | static struct sysdev_class amd_iommu_sysdev_class = { | 1289 | static struct syscore_ops amd_iommu_syscore_ops = { |
1292 | .name = "amd_iommu", | ||
1293 | .suspend = amd_iommu_suspend, | 1290 | .suspend = amd_iommu_suspend, |
1294 | .resume = amd_iommu_resume, | 1291 | .resume = amd_iommu_resume, |
1295 | }; | 1292 | }; |
1296 | 1293 | ||
1297 | static struct sys_device device_amd_iommu = { | ||
1298 | .id = 0, | ||
1299 | .cls = &amd_iommu_sysdev_class, | ||
1300 | }; | ||
1301 | |||
1302 | /* | 1294 | /* |
1303 | * This is the core init function for AMD IOMMU hardware in the system. | 1295 | * This is the core init function for AMD IOMMU hardware in the system. |
1304 | * This function is called from the generic x86 DMA layer initialization | 1296 | * This function is called from the generic x86 DMA layer initialization |
@@ -1415,14 +1407,6 @@ static int __init amd_iommu_init(void) | |||
1415 | goto free; | 1407 | goto free; |
1416 | } | 1408 | } |
1417 | 1409 | ||
1418 | ret = sysdev_class_register(&amd_iommu_sysdev_class); | ||
1419 | if (ret) | ||
1420 | goto free; | ||
1421 | |||
1422 | ret = sysdev_register(&device_amd_iommu); | ||
1423 | if (ret) | ||
1424 | goto free; | ||
1425 | |||
1426 | ret = amd_iommu_init_devices(); | 1410 | ret = amd_iommu_init_devices(); |
1427 | if (ret) | 1411 | if (ret) |
1428 | goto free; | 1412 | goto free; |
@@ -1441,6 +1425,8 @@ static int __init amd_iommu_init(void) | |||
1441 | 1425 | ||
1442 | amd_iommu_init_notifier(); | 1426 | amd_iommu_init_notifier(); |
1443 | 1427 | ||
1428 | register_syscore_ops(&amd_iommu_syscore_ops); | ||
1429 | |||
1444 | if (iommu_pass_through) | 1430 | if (iommu_pass_through) |
1445 | goto out; | 1431 | goto out; |
1446 | 1432 | ||
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 966673f44141..fabf01eff771 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/ftrace.h> | 24 | #include <linux/ftrace.h> |
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/sysdev.h> | 27 | #include <linux/syscore_ops.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/timex.h> | 29 | #include <linux/timex.h> |
30 | #include <linux/dmar.h> | 30 | #include <linux/dmar.h> |
@@ -2046,7 +2046,7 @@ static struct { | |||
2046 | unsigned int apic_thmr; | 2046 | unsigned int apic_thmr; |
2047 | } apic_pm_state; | 2047 | } apic_pm_state; |
2048 | 2048 | ||
2049 | static int lapic_suspend(struct sys_device *dev, pm_message_t state) | 2049 | static int lapic_suspend(void) |
2050 | { | 2050 | { |
2051 | unsigned long flags; | 2051 | unsigned long flags; |
2052 | int maxlvt; | 2052 | int maxlvt; |
@@ -2084,23 +2084,21 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) | |||
2084 | return 0; | 2084 | return 0; |
2085 | } | 2085 | } |
2086 | 2086 | ||
2087 | static int lapic_resume(struct sys_device *dev) | 2087 | static void lapic_resume(void) |
2088 | { | 2088 | { |
2089 | unsigned int l, h; | 2089 | unsigned int l, h; |
2090 | unsigned long flags; | 2090 | unsigned long flags; |
2091 | int maxlvt; | 2091 | int maxlvt, ret; |
2092 | int ret = 0; | ||
2093 | struct IO_APIC_route_entry **ioapic_entries = NULL; | 2092 | struct IO_APIC_route_entry **ioapic_entries = NULL; |
2094 | 2093 | ||
2095 | if (!apic_pm_state.active) | 2094 | if (!apic_pm_state.active) |
2096 | return 0; | 2095 | return; |
2097 | 2096 | ||
2098 | local_irq_save(flags); | 2097 | local_irq_save(flags); |
2099 | if (intr_remapping_enabled) { | 2098 | if (intr_remapping_enabled) { |
2100 | ioapic_entries = alloc_ioapic_entries(); | 2099 | ioapic_entries = alloc_ioapic_entries(); |
2101 | if (!ioapic_entries) { | 2100 | if (!ioapic_entries) { |
2102 | WARN(1, "Alloc ioapic_entries in lapic resume failed."); | 2101 | WARN(1, "Alloc ioapic_entries in lapic resume failed."); |
2103 | ret = -ENOMEM; | ||
2104 | goto restore; | 2102 | goto restore; |
2105 | } | 2103 | } |
2106 | 2104 | ||
@@ -2162,8 +2160,6 @@ static int lapic_resume(struct sys_device *dev) | |||
2162 | } | 2160 | } |
2163 | restore: | 2161 | restore: |
2164 | local_irq_restore(flags); | 2162 | local_irq_restore(flags); |
2165 | |||
2166 | return ret; | ||
2167 | } | 2163 | } |
2168 | 2164 | ||
2169 | /* | 2165 | /* |
@@ -2171,17 +2167,11 @@ restore: | |||
2171 | * are needed on every CPU up until machine_halt/restart/poweroff. | 2167 | * are needed on every CPU up until machine_halt/restart/poweroff. |
2172 | */ | 2168 | */ |
2173 | 2169 | ||
2174 | static struct sysdev_class lapic_sysclass = { | 2170 | static struct syscore_ops lapic_syscore_ops = { |
2175 | .name = "lapic", | ||
2176 | .resume = lapic_resume, | 2171 | .resume = lapic_resume, |
2177 | .suspend = lapic_suspend, | 2172 | .suspend = lapic_suspend, |
2178 | }; | 2173 | }; |
2179 | 2174 | ||
2180 | static struct sys_device device_lapic = { | ||
2181 | .id = 0, | ||
2182 | .cls = &lapic_sysclass, | ||
2183 | }; | ||
2184 | |||
2185 | static void __cpuinit apic_pm_activate(void) | 2175 | static void __cpuinit apic_pm_activate(void) |
2186 | { | 2176 | { |
2187 | apic_pm_state.active = 1; | 2177 | apic_pm_state.active = 1; |
@@ -2189,16 +2179,11 @@ static void __cpuinit apic_pm_activate(void) | |||
2189 | 2179 | ||
2190 | static int __init init_lapic_sysfs(void) | 2180 | static int __init init_lapic_sysfs(void) |
2191 | { | 2181 | { |
2192 | int error; | ||
2193 | |||
2194 | if (!cpu_has_apic) | ||
2195 | return 0; | ||
2196 | /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ | 2182 | /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ |
2183 | if (cpu_has_apic) | ||
2184 | register_syscore_ops(&lapic_syscore_ops); | ||
2197 | 2185 | ||
2198 | error = sysdev_class_register(&lapic_sysclass); | 2186 | return 0; |
2199 | if (!error) | ||
2200 | error = sysdev_register(&device_lapic); | ||
2201 | return error; | ||
2202 | } | 2187 | } |
2203 | 2188 | ||
2204 | /* local apic needs to resume before other devices access its registers. */ | 2189 | /* local apic needs to resume before other devices access its registers. */ |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 180ca240e03c..68df09bba92e 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/compiler.h> | 30 | #include <linux/compiler.h> |
31 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/sysdev.h> | 33 | #include <linux/syscore_ops.h> |
34 | #include <linux/msi.h> | 34 | #include <linux/msi.h> |
35 | #include <linux/htirq.h> | 35 | #include <linux/htirq.h> |
36 | #include <linux/freezer.h> | 36 | #include <linux/freezer.h> |
@@ -2918,89 +2918,84 @@ static int __init io_apic_bug_finalize(void) | |||
2918 | 2918 | ||
2919 | late_initcall(io_apic_bug_finalize); | 2919 | late_initcall(io_apic_bug_finalize); |
2920 | 2920 | ||
2921 | struct sysfs_ioapic_data { | 2921 | static struct IO_APIC_route_entry *ioapic_saved_data[MAX_IO_APICS]; |
2922 | struct sys_device dev; | ||
2923 | struct IO_APIC_route_entry entry[0]; | ||
2924 | }; | ||
2925 | static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; | ||
2926 | 2922 | ||
2927 | static int ioapic_suspend(struct sys_device *dev, pm_message_t state) | 2923 | static void suspend_ioapic(int ioapic_id) |
2928 | { | 2924 | { |
2929 | struct IO_APIC_route_entry *entry; | 2925 | struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id]; |
2930 | struct sysfs_ioapic_data *data; | ||
2931 | int i; | 2926 | int i; |
2932 | 2927 | ||
2933 | data = container_of(dev, struct sysfs_ioapic_data, dev); | 2928 | if (!saved_data) |
2934 | entry = data->entry; | 2929 | return; |
2935 | for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) | 2930 | |
2936 | *entry = ioapic_read_entry(dev->id, i); | 2931 | for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++) |
2932 | saved_data[i] = ioapic_read_entry(ioapic_id, i); | ||
2933 | } | ||
2934 | |||
2935 | static int ioapic_suspend(void) | ||
2936 | { | ||
2937 | int ioapic_id; | ||
2938 | |||
2939 | for (ioapic_id = 0; ioapic_id < nr_ioapics; ioapic_id++) | ||
2940 | suspend_ioapic(ioapic_id); | ||
2937 | 2941 | ||
2938 | return 0; | 2942 | return 0; |
2939 | } | 2943 | } |
2940 | 2944 | ||
2941 | static int ioapic_resume(struct sys_device *dev) | 2945 | static void resume_ioapic(int ioapic_id) |
2942 | { | 2946 | { |
2943 | struct IO_APIC_route_entry *entry; | 2947 | struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id]; |
2944 | struct sysfs_ioapic_data *data; | ||
2945 | unsigned long flags; | 2948 | unsigned long flags; |
2946 | union IO_APIC_reg_00 reg_00; | 2949 | union IO_APIC_reg_00 reg_00; |
2947 | int i; | 2950 | int i; |
2948 | 2951 | ||
2949 | data = container_of(dev, struct sysfs_ioapic_data, dev); | 2952 | if (!saved_data) |
2950 | entry = data->entry; | 2953 | return; |
2951 | 2954 | ||
2952 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 2955 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
2953 | reg_00.raw = io_apic_read(dev->id, 0); | 2956 | reg_00.raw = io_apic_read(ioapic_id, 0); |
2954 | if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) { | 2957 | if (reg_00.bits.ID != mp_ioapics[ioapic_id].apicid) { |
2955 | reg_00.bits.ID = mp_ioapics[dev->id].apicid; | 2958 | reg_00.bits.ID = mp_ioapics[ioapic_id].apicid; |
2956 | io_apic_write(dev->id, 0, reg_00.raw); | 2959 | io_apic_write(ioapic_id, 0, reg_00.raw); |
2957 | } | 2960 | } |
2958 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 2961 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
2959 | for (i = 0; i < nr_ioapic_registers[dev->id]; i++) | 2962 | for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++) |
2960 | ioapic_write_entry(dev->id, i, entry[i]); | 2963 | ioapic_write_entry(ioapic_id, i, saved_data[i]); |
2964 | } | ||
2961 | 2965 | ||
2962 | return 0; | 2966 | static void ioapic_resume(void) |
2967 | { | ||
2968 | int ioapic_id; | ||
2969 | |||
2970 | for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--) | ||
2971 | resume_ioapic(ioapic_id); | ||
2963 | } | 2972 | } |
2964 | 2973 | ||
2965 | static struct sysdev_class ioapic_sysdev_class = { | 2974 | static struct syscore_ops ioapic_syscore_ops = { |
2966 | .name = "ioapic", | ||
2967 | .suspend = ioapic_suspend, | 2975 | .suspend = ioapic_suspend, |
2968 | .resume = ioapic_resume, | 2976 | .resume = ioapic_resume, |
2969 | }; | 2977 | }; |
2970 | 2978 | ||
2971 | static int __init ioapic_init_sysfs(void) | 2979 | static int __init ioapic_init_ops(void) |
2972 | { | 2980 | { |
2973 | struct sys_device * dev; | 2981 | int i; |
2974 | int i, size, error; | ||
2975 | 2982 | ||
2976 | error = sysdev_class_register(&ioapic_sysdev_class); | 2983 | for (i = 0; i < nr_ioapics; i++) { |
2977 | if (error) | 2984 | unsigned int size; |
2978 | return error; | ||
2979 | 2985 | ||
2980 | for (i = 0; i < nr_ioapics; i++ ) { | 2986 | size = nr_ioapic_registers[i] |
2981 | size = sizeof(struct sys_device) + nr_ioapic_registers[i] | ||
2982 | * sizeof(struct IO_APIC_route_entry); | 2987 | * sizeof(struct IO_APIC_route_entry); |
2983 | mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL); | 2988 | ioapic_saved_data[i] = kzalloc(size, GFP_KERNEL); |
2984 | if (!mp_ioapic_data[i]) { | 2989 | if (!ioapic_saved_data[i]) |
2985 | printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); | 2990 | pr_err("IOAPIC %d: suspend/resume impossible!\n", i); |
2986 | continue; | ||
2987 | } | ||
2988 | dev = &mp_ioapic_data[i]->dev; | ||
2989 | dev->id = i; | ||
2990 | dev->cls = &ioapic_sysdev_class; | ||
2991 | error = sysdev_register(dev); | ||
2992 | if (error) { | ||
2993 | kfree(mp_ioapic_data[i]); | ||
2994 | mp_ioapic_data[i] = NULL; | ||
2995 | printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); | ||
2996 | continue; | ||
2997 | } | ||
2998 | } | 2991 | } |
2999 | 2992 | ||
2993 | register_syscore_ops(&ioapic_syscore_ops); | ||
2994 | |||
3000 | return 0; | 2995 | return 0; |
3001 | } | 2996 | } |
3002 | 2997 | ||
3003 | device_initcall(ioapic_init_sysfs); | 2998 | device_initcall(ioapic_init_ops); |
3004 | 2999 | ||
3005 | /* | 3000 | /* |
3006 | * Dynamic irq allocate and deallocation | 3001 | * Dynamic irq allocate and deallocation |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index ab1122998dba..5a05ef63eb4a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/percpu.h> | 21 | #include <linux/percpu.h> |
22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
23 | #include <linux/sysdev.h> | 23 | #include <linux/sysdev.h> |
24 | #include <linux/syscore_ops.h> | ||
24 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
25 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
26 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
@@ -1749,14 +1750,14 @@ static int mce_disable_error_reporting(void) | |||
1749 | return 0; | 1750 | return 0; |
1750 | } | 1751 | } |
1751 | 1752 | ||
1752 | static int mce_suspend(struct sys_device *dev, pm_message_t state) | 1753 | static int mce_suspend(void) |
1753 | { | 1754 | { |
1754 | return mce_disable_error_reporting(); | 1755 | return mce_disable_error_reporting(); |
1755 | } | 1756 | } |
1756 | 1757 | ||
1757 | static int mce_shutdown(struct sys_device *dev) | 1758 | static void mce_shutdown(void) |
1758 | { | 1759 | { |
1759 | return mce_disable_error_reporting(); | 1760 | mce_disable_error_reporting(); |
1760 | } | 1761 | } |
1761 | 1762 | ||
1762 | /* | 1763 | /* |
@@ -1764,14 +1765,18 @@ static int mce_shutdown(struct sys_device *dev) | |||
1764 | * Only one CPU is active at this time, the others get re-added later using | 1765 | * Only one CPU is active at this time, the others get re-added later using |
1765 | * CPU hotplug: | 1766 | * CPU hotplug: |
1766 | */ | 1767 | */ |
1767 | static int mce_resume(struct sys_device *dev) | 1768 | static void mce_resume(void) |
1768 | { | 1769 | { |
1769 | __mcheck_cpu_init_generic(); | 1770 | __mcheck_cpu_init_generic(); |
1770 | __mcheck_cpu_init_vendor(__this_cpu_ptr(&cpu_info)); | 1771 | __mcheck_cpu_init_vendor(__this_cpu_ptr(&cpu_info)); |
1771 | |||
1772 | return 0; | ||
1773 | } | 1772 | } |
1774 | 1773 | ||
1774 | static struct syscore_ops mce_syscore_ops = { | ||
1775 | .suspend = mce_suspend, | ||
1776 | .shutdown = mce_shutdown, | ||
1777 | .resume = mce_resume, | ||
1778 | }; | ||
1779 | |||
1775 | static void mce_cpu_restart(void *data) | 1780 | static void mce_cpu_restart(void *data) |
1776 | { | 1781 | { |
1777 | del_timer_sync(&__get_cpu_var(mce_timer)); | 1782 | del_timer_sync(&__get_cpu_var(mce_timer)); |
@@ -1808,9 +1813,6 @@ static void mce_enable_ce(void *all) | |||
1808 | } | 1813 | } |
1809 | 1814 | ||
1810 | static struct sysdev_class mce_sysclass = { | 1815 | static struct sysdev_class mce_sysclass = { |
1811 | .suspend = mce_suspend, | ||
1812 | .shutdown = mce_shutdown, | ||
1813 | .resume = mce_resume, | ||
1814 | .name = "machinecheck", | 1816 | .name = "machinecheck", |
1815 | }; | 1817 | }; |
1816 | 1818 | ||
@@ -2139,6 +2141,7 @@ static __init int mcheck_init_device(void) | |||
2139 | return err; | 2141 | return err; |
2140 | } | 2142 | } |
2141 | 2143 | ||
2144 | register_syscore_ops(&mce_syscore_ops); | ||
2142 | register_hotcpu_notifier(&mce_cpu_notifier); | 2145 | register_hotcpu_notifier(&mce_cpu_notifier); |
2143 | misc_register(&mce_log_device); | 2146 | misc_register(&mce_log_device); |
2144 | 2147 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index bebabec5b448..307dfbbf4a8e 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/cpu.h> | 45 | #include <linux/cpu.h> |
46 | #include <linux/pci.h> | 46 | #include <linux/pci.h> |
47 | #include <linux/smp.h> | 47 | #include <linux/smp.h> |
48 | #include <linux/syscore_ops.h> | ||
48 | 49 | ||
49 | #include <asm/processor.h> | 50 | #include <asm/processor.h> |
50 | #include <asm/e820.h> | 51 | #include <asm/e820.h> |
@@ -630,7 +631,7 @@ struct mtrr_value { | |||
630 | 631 | ||
631 | static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; | 632 | static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; |
632 | 633 | ||
633 | static int mtrr_save(struct sys_device *sysdev, pm_message_t state) | 634 | static int mtrr_save(void) |
634 | { | 635 | { |
635 | int i; | 636 | int i; |
636 | 637 | ||
@@ -642,7 +643,7 @@ static int mtrr_save(struct sys_device *sysdev, pm_message_t state) | |||
642 | return 0; | 643 | return 0; |
643 | } | 644 | } |
644 | 645 | ||
645 | static int mtrr_restore(struct sys_device *sysdev) | 646 | static void mtrr_restore(void) |
646 | { | 647 | { |
647 | int i; | 648 | int i; |
648 | 649 | ||
@@ -653,12 +654,11 @@ static int mtrr_restore(struct sys_device *sysdev) | |||
653 | mtrr_value[i].ltype); | 654 | mtrr_value[i].ltype); |
654 | } | 655 | } |
655 | } | 656 | } |
656 | return 0; | ||
657 | } | 657 | } |
658 | 658 | ||
659 | 659 | ||
660 | 660 | ||
661 | static struct sysdev_driver mtrr_sysdev_driver = { | 661 | static struct syscore_ops mtrr_syscore_ops = { |
662 | .suspend = mtrr_save, | 662 | .suspend = mtrr_save, |
663 | .resume = mtrr_restore, | 663 | .resume = mtrr_restore, |
664 | }; | 664 | }; |
@@ -839,7 +839,7 @@ static int __init mtrr_init_finialize(void) | |||
839 | * TBD: is there any system with such CPU which supports | 839 | * TBD: is there any system with such CPU which supports |
840 | * suspend/resume? If no, we should remove the code. | 840 | * suspend/resume? If no, we should remove the code. |
841 | */ | 841 | */ |
842 | sysdev_driver_register(&cpu_sysdev_class, &mtrr_sysdev_driver); | 842 | register_syscore_ops(&mtrr_syscore_ops); |
843 | 843 | ||
844 | return 0; | 844 | return 0; |
845 | } | 845 | } |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 87eab4a27dfc..eed3673a8656 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -500,12 +500,17 @@ static bool check_hw_exists(void) | |||
500 | return true; | 500 | return true; |
501 | 501 | ||
502 | bios_fail: | 502 | bios_fail: |
503 | printk(KERN_CONT "Broken BIOS detected, using software events only.\n"); | 503 | /* |
504 | * We still allow the PMU driver to operate: | ||
505 | */ | ||
506 | printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n"); | ||
504 | printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg, val); | 507 | printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg, val); |
505 | return false; | 508 | |
509 | return true; | ||
506 | 510 | ||
507 | msr_fail: | 511 | msr_fail: |
508 | printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); | 512 | printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); |
513 | |||
509 | return false; | 514 | return false; |
510 | } | 515 | } |
511 | 516 | ||
@@ -912,7 +917,7 @@ static inline void x86_assign_hw_event(struct perf_event *event, | |||
912 | hwc->event_base = 0; | 917 | hwc->event_base = 0; |
913 | } else if (hwc->idx >= X86_PMC_IDX_FIXED) { | 918 | } else if (hwc->idx >= X86_PMC_IDX_FIXED) { |
914 | hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; | 919 | hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; |
915 | hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0; | 920 | hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - X86_PMC_IDX_FIXED); |
916 | } else { | 921 | } else { |
917 | hwc->config_base = x86_pmu_config_addr(hwc->idx); | 922 | hwc->config_base = x86_pmu_config_addr(hwc->idx); |
918 | hwc->event_base = x86_pmu_event_addr(hwc->idx); | 923 | hwc->event_base = x86_pmu_event_addr(hwc->idx); |
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 0811f5ebfba6..c2520e178d32 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -777,6 +777,7 @@ static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) | |||
777 | * the counter has reached zero value and continued counting before | 777 | * the counter has reached zero value and continued counting before |
778 | * real NMI signal was received: | 778 | * real NMI signal was received: |
779 | */ | 779 | */ |
780 | rdmsrl(hwc->event_base, v); | ||
780 | if (!(v & ARCH_P4_UNFLAGGED_BIT)) | 781 | if (!(v & ARCH_P4_UNFLAGGED_BIT)) |
781 | return 1; | 782 | return 1; |
782 | 783 | ||
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 7a8cebc9ff29..706a9fb46a58 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c | |||
@@ -65,12 +65,10 @@ unsigned int irq_create_of_mapping(struct device_node *controller, | |||
65 | return 0; | 65 | return 0; |
66 | ret = ih->xlate(ih, intspec, intsize, &virq, &type); | 66 | ret = ih->xlate(ih, intspec, intsize, &virq, &type); |
67 | if (ret) | 67 | if (ret) |
68 | return ret; | 68 | return 0; |
69 | if (type == IRQ_TYPE_NONE) | 69 | if (type == IRQ_TYPE_NONE) |
70 | return virq; | 70 | return virq; |
71 | /* set the mask if it is different from current */ | 71 | irq_set_irq_type(virq, type); |
72 | if (type == (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK)) | ||
73 | set_irq_type(virq, type); | ||
74 | return virq; | 72 | return virq; |
75 | } | 73 | } |
76 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | 74 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 81ac6c78c01c..e2a3f0606da4 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -27,7 +27,7 @@ static int die_counter; | |||
27 | 27 | ||
28 | void printk_address(unsigned long address, int reliable) | 28 | void printk_address(unsigned long address, int reliable) |
29 | { | 29 | { |
30 | printk(" [<%p>] %s%pS\n", (void *) address, | 30 | printk(" [<%p>] %s%pB\n", (void *) address, |
31 | reliable ? "" : "? ", (void *) address); | 31 | reliable ? "" : "? ", (void *) address); |
32 | } | 32 | } |
33 | 33 | ||
diff --git a/arch/x86/kernel/i8237.c b/arch/x86/kernel/i8237.c index b42ca694dc68..8eeaa81de066 100644 --- a/arch/x86/kernel/i8237.c +++ b/arch/x86/kernel/i8237.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/sysdev.h> | 13 | #include <linux/syscore_ops.h> |
14 | 14 | ||
15 | #include <asm/dma.h> | 15 | #include <asm/dma.h> |
16 | 16 | ||
@@ -21,7 +21,7 @@ | |||
21 | * in asm/dma.h. | 21 | * in asm/dma.h. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | static int i8237A_resume(struct sys_device *dev) | 24 | static void i8237A_resume(void) |
25 | { | 25 | { |
26 | unsigned long flags; | 26 | unsigned long flags; |
27 | int i; | 27 | int i; |
@@ -41,31 +41,15 @@ static int i8237A_resume(struct sys_device *dev) | |||
41 | enable_dma(4); | 41 | enable_dma(4); |
42 | 42 | ||
43 | release_dma_lock(flags); | 43 | release_dma_lock(flags); |
44 | |||
45 | return 0; | ||
46 | } | 44 | } |
47 | 45 | ||
48 | static int i8237A_suspend(struct sys_device *dev, pm_message_t state) | 46 | static struct syscore_ops i8237_syscore_ops = { |
49 | { | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static struct sysdev_class i8237_sysdev_class = { | ||
54 | .name = "i8237", | ||
55 | .suspend = i8237A_suspend, | ||
56 | .resume = i8237A_resume, | 47 | .resume = i8237A_resume, |
57 | }; | 48 | }; |
58 | 49 | ||
59 | static struct sys_device device_i8237A = { | 50 | static int __init i8237A_init_ops(void) |
60 | .id = 0, | ||
61 | .cls = &i8237_sysdev_class, | ||
62 | }; | ||
63 | |||
64 | static int __init i8237A_init_sysfs(void) | ||
65 | { | 51 | { |
66 | int error = sysdev_class_register(&i8237_sysdev_class); | 52 | register_syscore_ops(&i8237_syscore_ops); |
67 | if (!error) | 53 | return 0; |
68 | error = sysdev_register(&device_i8237A); | ||
69 | return error; | ||
70 | } | 54 | } |
71 | device_initcall(i8237A_init_sysfs); | 55 | device_initcall(i8237A_init_ops); |
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index d9ca749c123b..65b8f5c2eebf 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c | |||
@@ -8,7 +8,7 @@ | |||
8 | #include <linux/random.h> | 8 | #include <linux/random.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/kernel_stat.h> | 10 | #include <linux/kernel_stat.h> |
11 | #include <linux/sysdev.h> | 11 | #include <linux/syscore_ops.h> |
12 | #include <linux/bitops.h> | 12 | #include <linux/bitops.h> |
13 | #include <linux/acpi.h> | 13 | #include <linux/acpi.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
@@ -245,20 +245,19 @@ static void save_ELCR(char *trigger) | |||
245 | trigger[1] = inb(0x4d1) & 0xDE; | 245 | trigger[1] = inb(0x4d1) & 0xDE; |
246 | } | 246 | } |
247 | 247 | ||
248 | static int i8259A_resume(struct sys_device *dev) | 248 | static void i8259A_resume(void) |
249 | { | 249 | { |
250 | init_8259A(i8259A_auto_eoi); | 250 | init_8259A(i8259A_auto_eoi); |
251 | restore_ELCR(irq_trigger); | 251 | restore_ELCR(irq_trigger); |
252 | return 0; | ||
253 | } | 252 | } |
254 | 253 | ||
255 | static int i8259A_suspend(struct sys_device *dev, pm_message_t state) | 254 | static int i8259A_suspend(void) |
256 | { | 255 | { |
257 | save_ELCR(irq_trigger); | 256 | save_ELCR(irq_trigger); |
258 | return 0; | 257 | return 0; |
259 | } | 258 | } |
260 | 259 | ||
261 | static int i8259A_shutdown(struct sys_device *dev) | 260 | static void i8259A_shutdown(void) |
262 | { | 261 | { |
263 | /* Put the i8259A into a quiescent state that | 262 | /* Put the i8259A into a quiescent state that |
264 | * the kernel initialization code can get it | 263 | * the kernel initialization code can get it |
@@ -266,21 +265,14 @@ static int i8259A_shutdown(struct sys_device *dev) | |||
266 | */ | 265 | */ |
267 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ | 266 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ |
268 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ | 267 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ |
269 | return 0; | ||
270 | } | 268 | } |
271 | 269 | ||
272 | static struct sysdev_class i8259_sysdev_class = { | 270 | static struct syscore_ops i8259_syscore_ops = { |
273 | .name = "i8259", | ||
274 | .suspend = i8259A_suspend, | 271 | .suspend = i8259A_suspend, |
275 | .resume = i8259A_resume, | 272 | .resume = i8259A_resume, |
276 | .shutdown = i8259A_shutdown, | 273 | .shutdown = i8259A_shutdown, |
277 | }; | 274 | }; |
278 | 275 | ||
279 | static struct sys_device device_i8259A = { | ||
280 | .id = 0, | ||
281 | .cls = &i8259_sysdev_class, | ||
282 | }; | ||
283 | |||
284 | static void mask_8259A(void) | 276 | static void mask_8259A(void) |
285 | { | 277 | { |
286 | unsigned long flags; | 278 | unsigned long flags; |
@@ -399,17 +391,12 @@ struct legacy_pic default_legacy_pic = { | |||
399 | 391 | ||
400 | struct legacy_pic *legacy_pic = &default_legacy_pic; | 392 | struct legacy_pic *legacy_pic = &default_legacy_pic; |
401 | 393 | ||
402 | static int __init i8259A_init_sysfs(void) | 394 | static int __init i8259A_init_ops(void) |
403 | { | 395 | { |
404 | int error; | 396 | if (legacy_pic == &default_legacy_pic) |
405 | 397 | register_syscore_ops(&i8259_syscore_ops); | |
406 | if (legacy_pic != &default_legacy_pic) | ||
407 | return 0; | ||
408 | 398 | ||
409 | error = sysdev_class_register(&i8259_sysdev_class); | 399 | return 0; |
410 | if (!error) | ||
411 | error = sysdev_register(&device_i8259A); | ||
412 | return error; | ||
413 | } | 400 | } |
414 | 401 | ||
415 | device_initcall(i8259A_init_sysfs); | 402 | device_initcall(i8259A_init_ops); |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index dba0b36941a5..5f9ecff328b5 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -121,8 +121,8 @@ char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) | |||
121 | memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, | 121 | memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, |
122 | dbg_reg_def[regno].size); | 122 | dbg_reg_def[regno].size); |
123 | 123 | ||
124 | switch (regno) { | ||
125 | #ifdef CONFIG_X86_32 | 124 | #ifdef CONFIG_X86_32 |
125 | switch (regno) { | ||
126 | case GDB_SS: | 126 | case GDB_SS: |
127 | if (!user_mode_vm(regs)) | 127 | if (!user_mode_vm(regs)) |
128 | *(unsigned long *)mem = __KERNEL_DS; | 128 | *(unsigned long *)mem = __KERNEL_DS; |
@@ -135,8 +135,8 @@ char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) | |||
135 | case GDB_FS: | 135 | case GDB_FS: |
136 | *(unsigned long *)mem = 0xFFFF; | 136 | *(unsigned long *)mem = 0xFFFF; |
137 | break; | 137 | break; |
138 | #endif | ||
139 | } | 138 | } |
139 | #endif | ||
140 | return dbg_reg_def[regno].name; | 140 | return dbg_reg_def[regno].name; |
141 | } | 141 | } |
142 | 142 | ||
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 87af68e0e1e1..5ed0ab549eb8 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
@@ -82,6 +82,7 @@ | |||
82 | #include <linux/cpu.h> | 82 | #include <linux/cpu.h> |
83 | #include <linux/fs.h> | 83 | #include <linux/fs.h> |
84 | #include <linux/mm.h> | 84 | #include <linux/mm.h> |
85 | #include <linux/syscore_ops.h> | ||
85 | 86 | ||
86 | #include <asm/microcode.h> | 87 | #include <asm/microcode.h> |
87 | #include <asm/processor.h> | 88 | #include <asm/processor.h> |
@@ -438,33 +439,25 @@ static int mc_sysdev_remove(struct sys_device *sys_dev) | |||
438 | return 0; | 439 | return 0; |
439 | } | 440 | } |
440 | 441 | ||
441 | static int mc_sysdev_resume(struct sys_device *dev) | 442 | static struct sysdev_driver mc_sysdev_driver = { |
443 | .add = mc_sysdev_add, | ||
444 | .remove = mc_sysdev_remove, | ||
445 | }; | ||
446 | |||
447 | /** | ||
448 | * mc_bp_resume - Update boot CPU microcode during resume. | ||
449 | */ | ||
450 | static void mc_bp_resume(void) | ||
442 | { | 451 | { |
443 | int cpu = dev->id; | 452 | int cpu = smp_processor_id(); |
444 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 453 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
445 | 454 | ||
446 | if (!cpu_online(cpu)) | ||
447 | return 0; | ||
448 | |||
449 | /* | ||
450 | * All non-bootup cpus are still disabled, | ||
451 | * so only CPU 0 will apply ucode here. | ||
452 | * | ||
453 | * Moreover, there can be no concurrent | ||
454 | * updates from any other places at this point. | ||
455 | */ | ||
456 | WARN_ON(cpu != 0); | ||
457 | |||
458 | if (uci->valid && uci->mc) | 455 | if (uci->valid && uci->mc) |
459 | microcode_ops->apply_microcode(cpu); | 456 | microcode_ops->apply_microcode(cpu); |
460 | |||
461 | return 0; | ||
462 | } | 457 | } |
463 | 458 | ||
464 | static struct sysdev_driver mc_sysdev_driver = { | 459 | static struct syscore_ops mc_syscore_ops = { |
465 | .add = mc_sysdev_add, | 460 | .resume = mc_bp_resume, |
466 | .remove = mc_sysdev_remove, | ||
467 | .resume = mc_sysdev_resume, | ||
468 | }; | 461 | }; |
469 | 462 | ||
470 | static __cpuinit int | 463 | static __cpuinit int |
@@ -542,6 +535,7 @@ static int __init microcode_init(void) | |||
542 | if (error) | 535 | if (error) |
543 | return error; | 536 | return error; |
544 | 537 | ||
538 | register_syscore_ops(&mc_syscore_ops); | ||
545 | register_hotcpu_notifier(&mc_cpu_notifier); | 539 | register_hotcpu_notifier(&mc_cpu_notifier); |
546 | 540 | ||
547 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION | 541 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 6f789a887c06..5a532ce646bf 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -714,10 +714,6 @@ static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) | |||
714 | *nr_m_spare += 1; | 714 | *nr_m_spare += 1; |
715 | } | 715 | } |
716 | } | 716 | } |
717 | #else /* CONFIG_X86_IO_APIC */ | ||
718 | static | ||
719 | inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} | ||
720 | #endif /* CONFIG_X86_IO_APIC */ | ||
721 | 717 | ||
722 | static int | 718 | static int |
723 | check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count) | 719 | check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count) |
@@ -731,6 +727,10 @@ check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count) | |||
731 | 727 | ||
732 | return ret; | 728 | return ret; |
733 | } | 729 | } |
730 | #else /* CONFIG_X86_IO_APIC */ | ||
731 | static | ||
732 | inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} | ||
733 | #endif /* CONFIG_X86_IO_APIC */ | ||
734 | 734 | ||
735 | static int __init replace_intsrc_all(struct mpc_table *mpc, | 735 | static int __init replace_intsrc_all(struct mpc_table *mpc, |
736 | unsigned long mpc_new_phys, | 736 | unsigned long mpc_new_phys, |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index c01ffa5b9b87..82ada01625b9 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
28 | #include <linux/scatterlist.h> | 28 | #include <linux/scatterlist.h> |
29 | #include <linux/iommu-helper.h> | 29 | #include <linux/iommu-helper.h> |
30 | #include <linux/sysdev.h> | 30 | #include <linux/syscore_ops.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
33 | #include <asm/atomic.h> | 33 | #include <asm/atomic.h> |
@@ -589,7 +589,7 @@ void set_up_gart_resume(u32 aper_order, u32 aper_alloc) | |||
589 | aperture_alloc = aper_alloc; | 589 | aperture_alloc = aper_alloc; |
590 | } | 590 | } |
591 | 591 | ||
592 | static void gart_fixup_northbridges(struct sys_device *dev) | 592 | static void gart_fixup_northbridges(void) |
593 | { | 593 | { |
594 | int i; | 594 | int i; |
595 | 595 | ||
@@ -613,33 +613,20 @@ static void gart_fixup_northbridges(struct sys_device *dev) | |||
613 | } | 613 | } |
614 | } | 614 | } |
615 | 615 | ||
616 | static int gart_resume(struct sys_device *dev) | 616 | static void gart_resume(void) |
617 | { | 617 | { |
618 | pr_info("PCI-DMA: Resuming GART IOMMU\n"); | 618 | pr_info("PCI-DMA: Resuming GART IOMMU\n"); |
619 | 619 | ||
620 | gart_fixup_northbridges(dev); | 620 | gart_fixup_northbridges(); |
621 | 621 | ||
622 | enable_gart_translations(); | 622 | enable_gart_translations(); |
623 | |||
624 | return 0; | ||
625 | } | 623 | } |
626 | 624 | ||
627 | static int gart_suspend(struct sys_device *dev, pm_message_t state) | 625 | static struct syscore_ops gart_syscore_ops = { |
628 | { | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static struct sysdev_class gart_sysdev_class = { | ||
633 | .name = "gart", | ||
634 | .suspend = gart_suspend, | ||
635 | .resume = gart_resume, | 626 | .resume = gart_resume, |
636 | 627 | ||
637 | }; | 628 | }; |
638 | 629 | ||
639 | static struct sys_device device_gart = { | ||
640 | .cls = &gart_sysdev_class, | ||
641 | }; | ||
642 | |||
643 | /* | 630 | /* |
644 | * Private Northbridge GATT initialization in case we cannot use the | 631 | * Private Northbridge GATT initialization in case we cannot use the |
645 | * AGP driver for some reason. | 632 | * AGP driver for some reason. |
@@ -650,7 +637,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info) | |||
650 | unsigned aper_base, new_aper_base; | 637 | unsigned aper_base, new_aper_base; |
651 | struct pci_dev *dev; | 638 | struct pci_dev *dev; |
652 | void *gatt; | 639 | void *gatt; |
653 | int i, error; | 640 | int i; |
654 | 641 | ||
655 | pr_info("PCI-DMA: Disabling AGP.\n"); | 642 | pr_info("PCI-DMA: Disabling AGP.\n"); |
656 | 643 | ||
@@ -685,12 +672,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info) | |||
685 | 672 | ||
686 | agp_gatt_table = gatt; | 673 | agp_gatt_table = gatt; |
687 | 674 | ||
688 | error = sysdev_class_register(&gart_sysdev_class); | 675 | register_syscore_ops(&gart_syscore_ops); |
689 | if (!error) | ||
690 | error = sysdev_register(&device_gart); | ||
691 | if (error) | ||
692 | panic("Could not register gart_sysdev -- " | ||
693 | "would corrupt data on next suspend"); | ||
694 | 676 | ||
695 | flush_gart(); | 677 | flush_gart(); |
696 | 678 | ||
diff --git a/arch/x86/lib/cmpxchg16b_emu.S b/arch/x86/lib/cmpxchg16b_emu.S index 3e8b08a6de2b..1e572c507d06 100644 --- a/arch/x86/lib/cmpxchg16b_emu.S +++ b/arch/x86/lib/cmpxchg16b_emu.S | |||
@@ -10,6 +10,12 @@ | |||
10 | #include <asm/frame.h> | 10 | #include <asm/frame.h> |
11 | #include <asm/dwarf2.h> | 11 | #include <asm/dwarf2.h> |
12 | 12 | ||
13 | #ifdef CONFIG_SMP | ||
14 | #define SEG_PREFIX %gs: | ||
15 | #else | ||
16 | #define SEG_PREFIX | ||
17 | #endif | ||
18 | |||
13 | .text | 19 | .text |
14 | 20 | ||
15 | /* | 21 | /* |
@@ -37,13 +43,13 @@ this_cpu_cmpxchg16b_emu: | |||
37 | pushf | 43 | pushf |
38 | cli | 44 | cli |
39 | 45 | ||
40 | cmpq %gs:(%rsi), %rax | 46 | cmpq SEG_PREFIX(%rsi), %rax |
41 | jne not_same | 47 | jne not_same |
42 | cmpq %gs:8(%rsi), %rdx | 48 | cmpq SEG_PREFIX 8(%rsi), %rdx |
43 | jne not_same | 49 | jne not_same |
44 | 50 | ||
45 | movq %rbx, %gs:(%rsi) | 51 | movq %rbx, SEG_PREFIX(%rsi) |
46 | movq %rcx, %gs:8(%rsi) | 52 | movq %rcx, SEG_PREFIX 8(%rsi) |
47 | 53 | ||
48 | popf | 54 | popf |
49 | mov $1, %al | 55 | mov $1, %al |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index e2b7b0c06cdf..8dace181c88e 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/notifier.h> | 15 | #include <linux/notifier.h> |
16 | #include <linux/smp.h> | 16 | #include <linux/smp.h> |
17 | #include <linux/oprofile.h> | 17 | #include <linux/oprofile.h> |
18 | #include <linux/sysdev.h> | 18 | #include <linux/syscore_ops.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/moduleparam.h> | 20 | #include <linux/moduleparam.h> |
21 | #include <linux/kdebug.h> | 21 | #include <linux/kdebug.h> |
@@ -536,7 +536,7 @@ static void nmi_shutdown(void) | |||
536 | 536 | ||
537 | #ifdef CONFIG_PM | 537 | #ifdef CONFIG_PM |
538 | 538 | ||
539 | static int nmi_suspend(struct sys_device *dev, pm_message_t state) | 539 | static int nmi_suspend(void) |
540 | { | 540 | { |
541 | /* Only one CPU left, just stop that one */ | 541 | /* Only one CPU left, just stop that one */ |
542 | if (nmi_enabled == 1) | 542 | if (nmi_enabled == 1) |
@@ -544,49 +544,31 @@ static int nmi_suspend(struct sys_device *dev, pm_message_t state) | |||
544 | return 0; | 544 | return 0; |
545 | } | 545 | } |
546 | 546 | ||
547 | static int nmi_resume(struct sys_device *dev) | 547 | static void nmi_resume(void) |
548 | { | 548 | { |
549 | if (nmi_enabled == 1) | 549 | if (nmi_enabled == 1) |
550 | nmi_cpu_start(NULL); | 550 | nmi_cpu_start(NULL); |
551 | return 0; | ||
552 | } | 551 | } |
553 | 552 | ||
554 | static struct sysdev_class oprofile_sysclass = { | 553 | static struct syscore_ops oprofile_syscore_ops = { |
555 | .name = "oprofile", | ||
556 | .resume = nmi_resume, | 554 | .resume = nmi_resume, |
557 | .suspend = nmi_suspend, | 555 | .suspend = nmi_suspend, |
558 | }; | 556 | }; |
559 | 557 | ||
560 | static struct sys_device device_oprofile = { | 558 | static void __init init_suspend_resume(void) |
561 | .id = 0, | ||
562 | .cls = &oprofile_sysclass, | ||
563 | }; | ||
564 | |||
565 | static int __init init_sysfs(void) | ||
566 | { | 559 | { |
567 | int error; | 560 | register_syscore_ops(&oprofile_syscore_ops); |
568 | |||
569 | error = sysdev_class_register(&oprofile_sysclass); | ||
570 | if (error) | ||
571 | return error; | ||
572 | |||
573 | error = sysdev_register(&device_oprofile); | ||
574 | if (error) | ||
575 | sysdev_class_unregister(&oprofile_sysclass); | ||
576 | |||
577 | return error; | ||
578 | } | 561 | } |
579 | 562 | ||
580 | static void exit_sysfs(void) | 563 | static void exit_suspend_resume(void) |
581 | { | 564 | { |
582 | sysdev_unregister(&device_oprofile); | 565 | unregister_syscore_ops(&oprofile_syscore_ops); |
583 | sysdev_class_unregister(&oprofile_sysclass); | ||
584 | } | 566 | } |
585 | 567 | ||
586 | #else | 568 | #else |
587 | 569 | ||
588 | static inline int init_sysfs(void) { return 0; } | 570 | static inline void init_suspend_resume(void) { } |
589 | static inline void exit_sysfs(void) { } | 571 | static inline void exit_suspend_resume(void) { } |
590 | 572 | ||
591 | #endif /* CONFIG_PM */ | 573 | #endif /* CONFIG_PM */ |
592 | 574 | ||
@@ -789,9 +771,7 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
789 | 771 | ||
790 | mux_init(ops); | 772 | mux_init(ops); |
791 | 773 | ||
792 | ret = init_sysfs(); | 774 | init_suspend_resume(); |
793 | if (ret) | ||
794 | return ret; | ||
795 | 775 | ||
796 | printk(KERN_INFO "oprofile: using NMI interrupt.\n"); | 776 | printk(KERN_INFO "oprofile: using NMI interrupt.\n"); |
797 | return 0; | 777 | return 0; |
@@ -799,5 +779,5 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
799 | 779 | ||
800 | void op_nmi_exit(void) | 780 | void op_nmi_exit(void) |
801 | { | 781 | { |
802 | exit_sysfs(); | 782 | exit_suspend_resume(); |
803 | } | 783 | } |
diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c index 99513642a0e6..ab81fb271760 100644 --- a/arch/x86/platform/olpc/olpc-xo1.c +++ b/arch/x86/platform/olpc/olpc-xo1.c | |||
@@ -72,9 +72,9 @@ static int __devinit olpc_xo1_probe(struct platform_device *pdev) | |||
72 | dev_err(&pdev->dev, "can't fetch device resource info\n"); | 72 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
73 | return -EIO; | 73 | return -EIO; |
74 | } | 74 | } |
75 | if (strcmp(pdev->name, "olpc-xo1-pms") == 0) | 75 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
76 | pms_base = res->start; | 76 | pms_base = res->start; |
77 | else if (strcmp(pdev->name, "olpc-xo1-ac-acpi") == 0) | 77 | else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) |
78 | acpi_base = res->start; | 78 | acpi_base = res->start; |
79 | 79 | ||
80 | /* If we have both addresses, we can override the poweroff hook */ | 80 | /* If we have both addresses, we can override the poweroff hook */ |
@@ -90,9 +90,9 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev) | |||
90 | { | 90 | { |
91 | mfd_cell_disable(pdev); | 91 | mfd_cell_disable(pdev); |
92 | 92 | ||
93 | if (strcmp(pdev->name, "olpc-xo1-pms") == 0) | 93 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
94 | pms_base = 0; | 94 | pms_base = 0; |
95 | else if (strcmp(pdev->name, "olpc-xo1-acpi") == 0) | 95 | else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0) |
96 | acpi_base = 0; | 96 | acpi_base = 0; |
97 | 97 | ||
98 | pm_power_off = NULL; | 98 | pm_power_off = NULL; |
@@ -101,7 +101,7 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev) | |||
101 | 101 | ||
102 | static struct platform_driver cs5535_pms_drv = { | 102 | static struct platform_driver cs5535_pms_drv = { |
103 | .driver = { | 103 | .driver = { |
104 | .name = "olpc-xo1-pms", | 104 | .name = "cs5535-pms", |
105 | .owner = THIS_MODULE, | 105 | .owner = THIS_MODULE, |
106 | }, | 106 | }, |
107 | .probe = olpc_xo1_probe, | 107 | .probe = olpc_xo1_probe, |
@@ -110,7 +110,7 @@ static struct platform_driver cs5535_pms_drv = { | |||
110 | 110 | ||
111 | static struct platform_driver cs5535_acpi_drv = { | 111 | static struct platform_driver cs5535_acpi_drv = { |
112 | .driver = { | 112 | .driver = { |
113 | .name = "olpc-xo1-acpi", | 113 | .name = "olpc-xo1-pm-acpi", |
114 | .owner = THIS_MODULE, | 114 | .owner = THIS_MODULE, |
115 | }, | 115 | }, |
116 | .probe = olpc_xo1_probe, | 116 | .probe = olpc_xo1_probe, |
@@ -121,22 +121,21 @@ static int __init olpc_xo1_init(void) | |||
121 | { | 121 | { |
122 | int r; | 122 | int r; |
123 | 123 | ||
124 | r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms"); | 124 | r = platform_driver_register(&cs5535_pms_drv); |
125 | if (r) | 125 | if (r) |
126 | return r; | 126 | return r; |
127 | 127 | ||
128 | r = mfd_shared_platform_driver_register(&cs5535_acpi_drv, | 128 | r = platform_driver_register(&cs5535_acpi_drv); |
129 | "cs5535-acpi"); | ||
130 | if (r) | 129 | if (r) |
131 | mfd_shared_platform_driver_unregister(&cs5535_pms_drv); | 130 | platform_driver_unregister(&cs5535_pms_drv); |
132 | 131 | ||
133 | return r; | 132 | return r; |
134 | } | 133 | } |
135 | 134 | ||
136 | static void __exit olpc_xo1_exit(void) | 135 | static void __exit olpc_xo1_exit(void) |
137 | { | 136 | { |
138 | mfd_shared_platform_driver_unregister(&cs5535_acpi_drv); | 137 | platform_driver_unregister(&cs5535_acpi_drv); |
139 | mfd_shared_platform_driver_unregister(&cs5535_pms_drv); | 138 | platform_driver_unregister(&cs5535_pms_drv); |
140 | } | 139 | } |
141 | 140 | ||
142 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); | 141 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 72839190f503..1d730b5579a0 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -7,6 +7,9 @@ config ZONE_DMA | |||
7 | config XTENSA | 7 | config XTENSA |
8 | def_bool y | 8 | def_bool y |
9 | select HAVE_IDE | 9 | select HAVE_IDE |
10 | select HAVE_GENERIC_HARDIRQS | ||
11 | select GENERIC_IRQ_SHOW | ||
12 | select GENERIC_HARDIRQS_NO_DEPRECATED | ||
10 | help | 13 | help |
11 | Xtensa processors are 32-bit RISC machines designed by Tensilica | 14 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
12 | primarily for embedded systems. These processors are both | 15 | primarily for embedded systems. These processors are both |
@@ -27,9 +30,6 @@ config GENERIC_FIND_BIT_LE | |||
27 | config GENERIC_HWEIGHT | 30 | config GENERIC_HWEIGHT |
28 | def_bool y | 31 | def_bool y |
29 | 32 | ||
30 | config GENERIC_HARDIRQS | ||
31 | def_bool y | ||
32 | |||
33 | config GENERIC_GPIO | 33 | config GENERIC_GPIO |
34 | def_bool y | 34 | def_bool y |
35 | 35 | ||
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 87508886cbbd..d77089df412e 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
@@ -35,7 +35,6 @@ atomic_t irq_err_count; | |||
35 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs) | 35 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs) |
36 | { | 36 | { |
37 | struct pt_regs *old_regs = set_irq_regs(regs); | 37 | struct pt_regs *old_regs = set_irq_regs(regs); |
38 | struct irq_desc *desc = irq_desc + irq; | ||
39 | 38 | ||
40 | if (irq >= NR_IRQS) { | 39 | if (irq >= NR_IRQS) { |
41 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", | 40 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", |
@@ -57,104 +56,69 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) | |||
57 | sp - sizeof(struct thread_info)); | 56 | sp - sizeof(struct thread_info)); |
58 | } | 57 | } |
59 | #endif | 58 | #endif |
60 | desc->handle_irq(irq, desc); | 59 | generic_handle_irq(irq); |
61 | 60 | ||
62 | irq_exit(); | 61 | irq_exit(); |
63 | set_irq_regs(old_regs); | 62 | set_irq_regs(old_regs); |
64 | } | 63 | } |
65 | 64 | ||
66 | /* | 65 | int arch_show_interrupts(struct seq_file *p, int prec) |
67 | * Generic, controller-independent functions: | ||
68 | */ | ||
69 | |||
70 | int show_interrupts(struct seq_file *p, void *v) | ||
71 | { | 66 | { |
72 | int i = *(loff_t *) v, j; | 67 | int j; |
73 | struct irqaction * action; | 68 | |
74 | unsigned long flags; | 69 | seq_printf(p, "%*s: ", prec, "NMI"); |
75 | 70 | for_each_online_cpu(j) | |
76 | if (i == 0) { | 71 | seq_printf(p, "%10u ", nmi_count(j)); |
77 | seq_printf(p, " "); | 72 | seq_putc(p, '\n'); |
78 | for_each_online_cpu(j) | 73 | seq_printf(p, "%*s: ", prec, "ERR"); |
79 | seq_printf(p, "CPU%d ",j); | 74 | seq_printf(p, "%10u\n", atomic_read(&irq_err_count)); |
80 | seq_putc(p, '\n'); | ||
81 | } | ||
82 | |||
83 | if (i < NR_IRQS) { | ||
84 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
85 | action = irq_desc[i].action; | ||
86 | if (!action) | ||
87 | goto skip; | ||
88 | seq_printf(p, "%3d: ",i); | ||
89 | #ifndef CONFIG_SMP | ||
90 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
91 | #else | ||
92 | for_each_online_cpu(j) | ||
93 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | ||
94 | #endif | ||
95 | seq_printf(p, " %14s", irq_desc[i].chip->name); | ||
96 | seq_printf(p, " %s", action->name); | ||
97 | |||
98 | for (action=action->next; action; action = action->next) | ||
99 | seq_printf(p, ", %s", action->name); | ||
100 | |||
101 | seq_putc(p, '\n'); | ||
102 | skip: | ||
103 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
104 | } else if (i == NR_IRQS) { | ||
105 | seq_printf(p, "NMI: "); | ||
106 | for_each_online_cpu(j) | ||
107 | seq_printf(p, "%10u ", nmi_count(j)); | ||
108 | seq_putc(p, '\n'); | ||
109 | seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); | ||
110 | } | ||
111 | return 0; | 75 | return 0; |
112 | } | 76 | } |
113 | 77 | ||
114 | static void xtensa_irq_mask(unsigned int irq) | 78 | static void xtensa_irq_mask(struct irq_chip *d) |
115 | { | 79 | { |
116 | cached_irq_mask &= ~(1 << irq); | 80 | cached_irq_mask &= ~(1 << d->irq); |
117 | set_sr (cached_irq_mask, INTENABLE); | 81 | set_sr (cached_irq_mask, INTENABLE); |
118 | } | 82 | } |
119 | 83 | ||
120 | static void xtensa_irq_unmask(unsigned int irq) | 84 | static void xtensa_irq_unmask(struct irq_chip *d) |
121 | { | 85 | { |
122 | cached_irq_mask |= 1 << irq; | 86 | cached_irq_mask |= 1 << d->irq; |
123 | set_sr (cached_irq_mask, INTENABLE); | 87 | set_sr (cached_irq_mask, INTENABLE); |
124 | } | 88 | } |
125 | 89 | ||
126 | static void xtensa_irq_enable(unsigned int irq) | 90 | static void xtensa_irq_enable(struct irq_chip *d) |
127 | { | 91 | { |
128 | variant_irq_enable(irq); | 92 | variant_irq_enable(d->irq); |
129 | xtensa_irq_unmask(irq); | 93 | xtensa_irq_unmask(d->irq); |
130 | } | 94 | } |
131 | 95 | ||
132 | static void xtensa_irq_disable(unsigned int irq) | 96 | static void xtensa_irq_disable(struct irq_chip *d) |
133 | { | 97 | { |
134 | xtensa_irq_mask(irq); | 98 | xtensa_irq_mask(d->irq); |
135 | variant_irq_disable(irq); | 99 | variant_irq_disable(d->irq); |
136 | } | 100 | } |
137 | 101 | ||
138 | static void xtensa_irq_ack(unsigned int irq) | 102 | static void xtensa_irq_ack(struct irq_chip *d) |
139 | { | 103 | { |
140 | set_sr(1 << irq, INTCLEAR); | 104 | set_sr(1 << d->irq, INTCLEAR); |
141 | } | 105 | } |
142 | 106 | ||
143 | static int xtensa_irq_retrigger(unsigned int irq) | 107 | static int xtensa_irq_retrigger(struct irq_chip *d) |
144 | { | 108 | { |
145 | set_sr (1 << irq, INTSET); | 109 | set_sr (1 << d->irq, INTSET); |
146 | return 1; | 110 | return 1; |
147 | } | 111 | } |
148 | 112 | ||
149 | 113 | ||
150 | static struct irq_chip xtensa_irq_chip = { | 114 | static struct irq_chip xtensa_irq_chip = { |
151 | .name = "xtensa", | 115 | .name = "xtensa", |
152 | .enable = xtensa_irq_enable, | 116 | .irq_enable = xtensa_irq_enable, |
153 | .disable = xtensa_irq_disable, | 117 | .irq_disable = xtensa_irq_disable, |
154 | .mask = xtensa_irq_mask, | 118 | .irq_mask = xtensa_irq_mask, |
155 | .unmask = xtensa_irq_unmask, | 119 | .irq_unmask = xtensa_irq_unmask, |
156 | .ack = xtensa_irq_ack, | 120 | .irq_ack = xtensa_irq_ack, |
157 | .retrigger = xtensa_irq_retrigger, | 121 | .irq_retrigger = xtensa_irq_retrigger, |
158 | }; | 122 | }; |
159 | 123 | ||
160 | void __init init_IRQ(void) | 124 | void __init init_IRQ(void) |
@@ -165,25 +129,25 @@ void __init init_IRQ(void) | |||
165 | int mask = 1 << index; | 129 | int mask = 1 << index; |
166 | 130 | ||
167 | if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) | 131 | if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) |
168 | set_irq_chip_and_handler(index, &xtensa_irq_chip, | 132 | irq_set_chip_and_handler(index, &xtensa_irq_chip, |
169 | handle_simple_irq); | 133 | handle_simple_irq); |
170 | 134 | ||
171 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) | 135 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) |
172 | set_irq_chip_and_handler(index, &xtensa_irq_chip, | 136 | irq_set_chip_and_handler(index, &xtensa_irq_chip, |
173 | handle_edge_irq); | 137 | handle_edge_irq); |
174 | 138 | ||
175 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) | 139 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) |
176 | set_irq_chip_and_handler(index, &xtensa_irq_chip, | 140 | irq_set_chip_and_handler(index, &xtensa_irq_chip, |
177 | handle_level_irq); | 141 | handle_level_irq); |
178 | 142 | ||
179 | else if (mask & XCHAL_INTTYPE_MASK_TIMER) | 143 | else if (mask & XCHAL_INTTYPE_MASK_TIMER) |
180 | set_irq_chip_and_handler(index, &xtensa_irq_chip, | 144 | irq_set_chip_and_handler(index, &xtensa_irq_chip, |
181 | handle_edge_irq); | 145 | handle_edge_irq); |
182 | 146 | ||
183 | else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ | 147 | else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ |
184 | /* XCHAL_INTTYPE_MASK_NMI */ | 148 | /* XCHAL_INTTYPE_MASK_NMI */ |
185 | 149 | ||
186 | set_irq_chip_and_handler(index, &xtensa_irq_chip, | 150 | irq_set_chip_and_handler(index, &xtensa_irq_chip, |
187 | handle_level_irq); | 151 | handle_level_irq); |
188 | } | 152 | } |
189 | 153 | ||
diff --git a/arch/xtensa/platforms/s6105/device.c b/arch/xtensa/platforms/s6105/device.c index 65333ffefb07..4f4fc971042f 100644 --- a/arch/xtensa/platforms/s6105/device.c +++ b/arch/xtensa/platforms/s6105/device.c | |||
@@ -120,7 +120,7 @@ static int __init prepare_phy_irq(int pin) | |||
120 | irq = gpio_to_irq(pin); | 120 | irq = gpio_to_irq(pin); |
121 | if (irq < 0) | 121 | if (irq < 0) |
122 | goto free; | 122 | goto free; |
123 | if (set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0) | 123 | if (irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0) |
124 | goto free; | 124 | goto free; |
125 | return irq; | 125 | return irq; |
126 | free: | 126 | free: |
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c index 380a70fff756..7af0757e001b 100644 --- a/arch/xtensa/variants/s6000/gpio.c +++ b/arch/xtensa/variants/s6000/gpio.c | |||
@@ -85,30 +85,29 @@ int s6_gpio_init(u32 afsel) | |||
85 | return gpiochip_add(&gpiochip); | 85 | return gpiochip_add(&gpiochip); |
86 | } | 86 | } |
87 | 87 | ||
88 | static void ack(unsigned int irq) | 88 | static void ack(struct irq_data *d) |
89 | { | 89 | { |
90 | writeb(1 << (irq - IRQ_BASE), S6_REG_GPIO + S6_GPIO_IC); | 90 | writeb(1 << (d->irq - IRQ_BASE), S6_REG_GPIO + S6_GPIO_IC); |
91 | } | 91 | } |
92 | 92 | ||
93 | static void mask(unsigned int irq) | 93 | static void mask(struct irq_data *d) |
94 | { | 94 | { |
95 | u8 r = readb(S6_REG_GPIO + S6_GPIO_IE); | 95 | u8 r = readb(S6_REG_GPIO + S6_GPIO_IE); |
96 | r &= ~(1 << (irq - IRQ_BASE)); | 96 | r &= ~(1 << (d->irq - IRQ_BASE)); |
97 | writeb(r, S6_REG_GPIO + S6_GPIO_IE); | 97 | writeb(r, S6_REG_GPIO + S6_GPIO_IE); |
98 | } | 98 | } |
99 | 99 | ||
100 | static void unmask(unsigned int irq) | 100 | static void unmask(struct irq_data *d) |
101 | { | 101 | { |
102 | u8 m = readb(S6_REG_GPIO + S6_GPIO_IE); | 102 | u8 m = readb(S6_REG_GPIO + S6_GPIO_IE); |
103 | m |= 1 << (irq - IRQ_BASE); | 103 | m |= 1 << (d->irq - IRQ_BASE); |
104 | writeb(m, S6_REG_GPIO + S6_GPIO_IE); | 104 | writeb(m, S6_REG_GPIO + S6_GPIO_IE); |
105 | } | 105 | } |
106 | 106 | ||
107 | static int set_type(unsigned int irq, unsigned int type) | 107 | static int set_type(struct irq_data *d, unsigned int type) |
108 | { | 108 | { |
109 | const u8 m = 1 << (irq - IRQ_BASE); | 109 | const u8 m = 1 << (d->irq - IRQ_BASE); |
110 | irq_flow_handler_t handler; | 110 | irq_flow_handler_t handler; |
111 | struct irq_desc *desc; | ||
112 | u8 reg; | 111 | u8 reg; |
113 | 112 | ||
114 | if (type == IRQ_TYPE_PROBE) { | 113 | if (type == IRQ_TYPE_PROBE) { |
@@ -129,8 +128,7 @@ static int set_type(unsigned int irq, unsigned int type) | |||
129 | handler = handle_edge_irq; | 128 | handler = handle_edge_irq; |
130 | } | 129 | } |
131 | writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS); | 130 | writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS); |
132 | desc = irq_to_desc(irq); | 131 | __irq_set_handler_locked(irq, handler); |
133 | desc->handle_irq = handler; | ||
134 | 132 | ||
135 | reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV); | 133 | reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV); |
136 | if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)) | 134 | if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)) |
@@ -150,22 +148,23 @@ static int set_type(unsigned int irq, unsigned int type) | |||
150 | 148 | ||
151 | static struct irq_chip gpioirqs = { | 149 | static struct irq_chip gpioirqs = { |
152 | .name = "GPIO", | 150 | .name = "GPIO", |
153 | .ack = ack, | 151 | .irq_ack = ack, |
154 | .mask = mask, | 152 | .irq_mask = mask, |
155 | .unmask = unmask, | 153 | .irq_unmask = unmask, |
156 | .set_type = set_type, | 154 | .irq_set_type = set_type, |
157 | }; | 155 | }; |
158 | 156 | ||
159 | static u8 demux_masks[4]; | 157 | static u8 demux_masks[4]; |
160 | 158 | ||
161 | static void demux_irqs(unsigned int irq, struct irq_desc *desc) | 159 | static void demux_irqs(unsigned int irq, struct irq_desc *desc) |
162 | { | 160 | { |
163 | u8 *mask = get_irq_desc_data(desc); | 161 | struct irq_chip *chip = irq_desc_get_chip(desc); |
162 | u8 *mask = irq_desc_get_handler_data(desc); | ||
164 | u8 pending; | 163 | u8 pending; |
165 | int cirq; | 164 | int cirq; |
166 | 165 | ||
167 | desc->chip->mask(irq); | 166 | chip->irq_mask(&desc->irq_data); |
168 | desc->chip->ack(irq); | 167 | chip->irq_ack(&desc->irq_data)); |
169 | pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; | 168 | pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; |
170 | cirq = IRQ_BASE - 1; | 169 | cirq = IRQ_BASE - 1; |
171 | while (pending) { | 170 | while (pending) { |
@@ -174,7 +173,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) | |||
174 | pending >>= n; | 173 | pending >>= n; |
175 | generic_handle_irq(cirq); | 174 | generic_handle_irq(cirq); |
176 | } | 175 | } |
177 | desc->chip->unmask(irq); | 176 | chip->irq_unmask(&desc->irq_data)); |
178 | } | 177 | } |
179 | 178 | ||
180 | extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; | 179 | extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; |
@@ -219,11 +218,11 @@ void __init variant_init_irq(void) | |||
219 | i = ffs(mask); | 218 | i = ffs(mask); |
220 | cirq += i; | 219 | cirq += i; |
221 | mask >>= i; | 220 | mask >>= i; |
222 | set_irq_chip(cirq, &gpioirqs); | 221 | irq_set_chip(cirq, &gpioirqs); |
223 | set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); | 222 | irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); |
224 | } while (mask); | 223 | } while (mask); |
225 | set_irq_data(irq, demux_masks + n); | 224 | irq_set_handler_data(irq, demux_masks + n); |
226 | set_irq_chained_handler(irq, demux_irqs); | 225 | irq_set_chained_handler(irq, demux_irqs); |
227 | if (++n == ARRAY_SIZE(demux_masks)) | 226 | if (++n == ARRAY_SIZE(demux_masks)) |
228 | break; | 227 | break; |
229 | } | 228 | } |