Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-06-13 21:55:05 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-06-13 21:55:05 -0700
commit07de07defc8c727f287bf20d200b0cfeedfbfa51 (patch)
tree66945be3404e70c5cc6186e2e287fcf61909c70a
parent4d6b10c540d0c058c1c650bb1cac25cd61d5d6d9 (diff)
parent2eb80fd261bb3f37b76284e516422f79cb5b5331 (diff)
Merge http://linux-isdn.bkbits.net/linux-2.5.make
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r--Documentation/cpu-freq/user-guide.txt5
-rw-r--r--arch/alpha/vmlinux.lds.S3
-rw-r--r--arch/arm/vmlinux-armo.lds.in1
-rw-r--r--arch/arm/vmlinux-armv.lds.in1
-rw-r--r--arch/cris/vmlinux.lds.S7
-rw-r--r--arch/h8300/platform/h8300h/generic/rom.ld1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/Kconfig38
-rw-r--r--arch/i386/kernel/cpu/cpufreq/Makefile3
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c8
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c377
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-ich.c (renamed from arch/i386/kernel/cpu/cpufreq/speedstep.c)15
-rw-r--r--arch/i386/vmlinux.lds.S1
-rw-r--r--arch/ia64/vmlinux.lds.S4
-rw-r--r--arch/m68k/vmlinux-std.lds1
-rw-r--r--arch/m68k/vmlinux-sun3.lds1
-rw-r--r--arch/m68knommu/vmlinux.lds.S4
-rw-r--r--arch/mips/vmlinux.lds.S1
-rw-r--r--arch/mips64/vmlinux.lds.S1
-rw-r--r--arch/parisc/vmlinux.lds.S1
-rw-r--r--arch/ppc/vmlinux.lds.S2
-rw-r--r--arch/ppc64/boot/zlib.c27
-rw-r--r--arch/ppc64/kernel/Makefile8
-rw-r--r--arch/ppc64/kernel/align.c12
-rw-r--r--arch/ppc64/kernel/asm-offsets.c8
-rw-r--r--arch/ppc64/kernel/chrp_setup.c31
-rw-r--r--arch/ppc64/kernel/cputable.c127
-rw-r--r--arch/ppc64/kernel/head.S18
-rw-r--r--arch/ppc64/kernel/htab.c7
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c4
-rw-r--r--arch/ppc64/kernel/ioctl32.c3101
-rw-r--r--arch/ppc64/kernel/irq.c1
-rw-r--r--arch/ppc64/kernel/misc.S90
-rw-r--r--arch/ppc64/kernel/module.c42
-rw-r--r--arch/ppc64/kernel/pSeries_htab.c7
-rw-r--r--arch/ppc64/kernel/process.c3
-rw-r--r--arch/ppc64/kernel/ras.c7
-rw-r--r--arch/ppc64/kernel/smp.c3
-rw-r--r--arch/ppc64/kernel/stab.c11
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c28
-rw-r--r--arch/ppc64/kernel/traps.c55
-rw-r--r--arch/ppc64/lib/copyuser.S2
-rw-r--r--arch/ppc64/lib/string.S9
-rw-r--r--arch/ppc64/mm/init.c10
-rw-r--r--arch/ppc64/mm/numa.c43
-rw-r--r--arch/ppc64/vmlinux.lds.S9
-rw-r--r--arch/s390/vmlinux.lds.S1
-rw-r--r--arch/sh/Kconfig608
-rw-r--r--arch/sh/Makefile124
-rw-r--r--arch/sh/boards/adx/Makefile10
-rw-r--r--arch/sh/boards/adx/io.c (renamed from arch/sh/kernel/io_adx.c)3
-rw-r--r--arch/sh/boards/adx/irq.c31
-rw-r--r--arch/sh/boards/adx/irq_maskreg.c (renamed from arch/sh/kernel/irq_maskreg.c)8
-rw-r--r--arch/sh/boards/adx/mach.c66
-rw-r--r--arch/sh/boards/adx/setup.c24
-rw-r--r--arch/sh/boards/bigsur/Makefile12
-rw-r--r--arch/sh/boards/bigsur/io.c (renamed from arch/sh/kernel/io_bigsur.c)2
-rw-r--r--arch/sh/boards/bigsur/irq.c348
-rw-r--r--arch/sh/boards/bigsur/led.c (renamed from arch/sh/kernel/led_bigsur.c)2
-rw-r--r--arch/sh/boards/bigsur/mach.c72
-rw-r--r--arch/sh/boards/bigsur/pci.c (renamed from arch/sh/kernel/pci-bigsur.c)2
-rw-r--r--arch/sh/boards/bigsur/setup.c94
-rw-r--r--arch/sh/boards/cat68701/Makefile10
-rw-r--r--arch/sh/boards/cat68701/io.c (renamed from arch/sh/kernel/io_cat68701.c)46
-rw-r--r--arch/sh/boards/cat68701/irq.c28
-rw-r--r--arch/sh/boards/cat68701/mach.c66
-rw-r--r--arch/sh/boards/cat68701/setup.c51
-rw-r--r--arch/sh/boards/cqreek/Makefile10
-rw-r--r--arch/sh/boards/cqreek/io.c14
-rw-r--r--arch/sh/boards/cqreek/irq.c128
-rw-r--r--arch/sh/boards/cqreek/mach.c66
-rw-r--r--arch/sh/boards/cqreek/setup.c69
-rw-r--r--arch/sh/boards/dmida/Makefile11
-rw-r--r--arch/sh/boards/dmida/mach.c73
-rw-r--r--arch/sh/boards/dreamcast/Makefile12
-rw-r--r--arch/sh/boards/dreamcast/io.c (renamed from arch/sh/kernel/io_dc.c)2
-rw-r--r--arch/sh/boards/dreamcast/irq.c160
-rw-r--r--arch/sh/boards/dreamcast/mach.c62
-rw-r--r--arch/sh/boards/dreamcast/pci.c (renamed from arch/sh/kernel/pci-dc.c)64
-rw-r--r--arch/sh/boards/dreamcast/rtc.c (renamed from arch/sh/kernel/rtc-aica.c)29
-rw-r--r--arch/sh/boards/dreamcast/setup.c64
-rw-r--r--arch/sh/boards/ec3104/Makefile10
-rw-r--r--arch/sh/boards/ec3104/io.c (renamed from arch/sh/kernel/io_ec3104.c)2
-rw-r--r--arch/sh/boards/ec3104/irq.c196
-rw-r--r--arch/sh/boards/ec3104/mach.c69
-rw-r--r--arch/sh/boards/ec3104/setup.c57
-rw-r--r--arch/sh/boards/harp/Makefile12
-rw-r--r--arch/sh/boards/harp/irq.c (renamed from arch/sh/stboards/irq.c)11
-rw-r--r--arch/sh/boards/harp/led.c (renamed from arch/sh/stboards/led.c)2
-rw-r--r--arch/sh/boards/harp/mach.c72
-rw-r--r--arch/sh/boards/harp/pcidma.c (renamed from arch/sh/stboards/pcidma.c)2
-rw-r--r--arch/sh/boards/harp/setup.c (renamed from arch/sh/stboards/setup.c)10
-rw-r--r--arch/sh/boards/hp6xx/hp620/Makefile10
-rw-r--r--arch/sh/boards/hp6xx/hp620/mach.c68
-rw-r--r--arch/sh/boards/hp6xx/hp680/Makefile10
-rw-r--r--arch/sh/boards/hp6xx/hp680/mach.c64
-rw-r--r--arch/sh/boards/hp6xx/hp690/Makefile10
-rw-r--r--arch/sh/boards/hp6xx/hp690/mach.c64
-rw-r--r--arch/sh/boards/overdrive/Makefile12
-rw-r--r--arch/sh/boards/overdrive/fpga.c134
-rw-r--r--arch/sh/boards/overdrive/galileo.c594
-rw-r--r--arch/sh/boards/overdrive/io.c173
-rw-r--r--arch/sh/boards/overdrive/irq.c192
-rw-r--r--arch/sh/boards/overdrive/led.c59
-rw-r--r--arch/sh/boards/overdrive/mach.c74
-rw-r--r--arch/sh/boards/overdrive/pcidma.c46
-rw-r--r--arch/sh/boards/overdrive/setup.c41
-rw-r--r--arch/sh/boards/overdrive/time.c119
-rw-r--r--arch/sh/boards/saturn/Makefile12
-rw-r--r--arch/sh/boards/saturn/io.c26
-rw-r--r--arch/sh/boards/saturn/irq.c119
-rw-r--r--arch/sh/boards/saturn/mach.c61
-rw-r--r--arch/sh/boards/saturn/setup.c22
-rw-r--r--arch/sh/boards/saturn/smp.c68
-rw-r--r--arch/sh/boards/se/770x/Makefile10
-rw-r--r--arch/sh/boards/se/770x/io.c (renamed from arch/sh/kernel/io_se.c)4
-rw-r--r--arch/sh/boards/se/770x/irq.c53
-rw-r--r--arch/sh/boards/se/770x/led.c (renamed from arch/sh/kernel/led_se.c)2
-rw-r--r--arch/sh/boards/se/770x/mach.c77
-rw-r--r--arch/sh/boards/se/770x/setup.c (renamed from arch/sh/kernel/setup_se.c)48
-rw-r--r--arch/sh/boards/se/7751/Makefile12
-rw-r--r--arch/sh/boards/se/7751/io.c (renamed from arch/sh/kernel/io_7751se.c)4
-rw-r--r--arch/sh/boards/se/7751/irq.c67
-rw-r--r--arch/sh/boards/se/7751/led.c (renamed from arch/sh/kernel/led_7751se.c)2
-rw-r--r--arch/sh/boards/se/7751/mach.c70
-rw-r--r--arch/sh/boards/se/7751/pci.c (renamed from arch/sh/kernel/pci-7751se.c)0
-rw-r--r--arch/sh/boards/se/7751/setup.c228
-rw-r--r--arch/sh/boards/sh2000/Makefile10
-rw-r--r--arch/sh/boards/sh2000/io.c (renamed from arch/sh/kernel/io_sh2000.c)0
-rw-r--r--arch/sh/boards/sh2000/mach.c59
-rw-r--r--arch/sh/boards/sh2000/setup.c46
-rw-r--r--arch/sh/boards/unknown/Makefile10
-rw-r--r--arch/sh/boards/unknown/io.c (renamed from arch/sh/kernel/io_unknown.c)0
-rw-r--r--arch/sh/boards/unknown/mach.c67
-rw-r--r--arch/sh/boards/unknown/setup.c23
-rw-r--r--arch/sh/boot/compressed/Makefile42
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/Makefile10
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/io.c (renamed from arch/sh/kernel/io_hd64461.c)4
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/setup.c (renamed from arch/sh/kernel/setup_hd64461.c)12
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/Makefile10
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/gpio.c (renamed from arch/sh/kernel/hd64465_gpio.c)29
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/io.c (renamed from arch/sh/kernel/io_hd64465.c)4
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/setup.c (renamed from arch/sh/kernel/setup_hd64465.c)26
-rw-r--r--arch/sh/kernel/Makefile69
-rw-r--r--arch/sh/kernel/io_generic.c4
-rw-r--r--arch/sh/kernel/irq_imask.c116
-rw-r--r--arch/sh/kernel/irq_intc2.c127
-rw-r--r--arch/sh/kernel/irq_ipr.c309
-rw-r--r--arch/sh/kernel/mach_7751se.c78
-rw-r--r--arch/sh/kernel/mach_adx.c73
-rw-r--r--arch/sh/kernel/mach_bigsur.c77
-rw-r--r--arch/sh/kernel/mach_cat68701.c72
-rw-r--r--arch/sh/kernel/mach_dc.c73
-rw-r--r--arch/sh/kernel/mach_dmida.c73
-rw-r--r--arch/sh/kernel/mach_ec3104.c69
-rw-r--r--arch/sh/kernel/mach_hp600.c158
-rw-r--r--arch/sh/kernel/mach_se.c84
-rw-r--r--arch/sh/kernel/mach_unknown.c72
-rw-r--r--arch/sh/kernel/pci-sh7751.c510
-rw-r--r--arch/sh/kernel/pci_st40.c423
-rw-r--r--arch/sh/kernel/pci_st40.h66
-rw-r--r--arch/sh/kernel/setup_7751se.c136
-rw-r--r--arch/sh/kernel/setup_adx.c40
-rw-r--r--arch/sh/kernel/setup_bigsur.c383
-rw-r--r--arch/sh/kernel/setup_cqreek.c252
-rw-r--r--arch/sh/kernel/setup_dc.c213
-rw-r--r--arch/sh/kernel/setup_ec3104.c242
-rw-r--r--arch/sh/kernel/setup_sh2000.c95
-rw-r--r--arch/sh/stboards/Makefile5
-rw-r--r--arch/sh/stboards/harp.h43
-rw-r--r--arch/sh/stboards/mach.c77
-rw-r--r--arch/sh/vmlinux.lds.S51
-rw-r--r--arch/sparc/vmlinux.lds.S1
-rw-r--r--arch/sparc64/vmlinux.lds.S1
-rw-r--r--arch/x86_64/Kconfig12
-rw-r--r--arch/x86_64/ia32/ia32entry.S1
-rw-r--r--arch/x86_64/kernel/acpi/boot.c6
-rw-r--r--arch/x86_64/kernel/apic.c8
-rw-r--r--arch/x86_64/kernel/bluesmoke.c14
-rw-r--r--arch/x86_64/kernel/pci-gart.c15
-rw-r--r--arch/x86_64/kernel/process.c6
-rw-r--r--arch/x86_64/kernel/smpboot.c11
-rw-r--r--arch/x86_64/kernel/time.c258
-rw-r--r--arch/x86_64/kernel/traps.c2
-rw-r--r--arch/x86_64/kernel/vsyscall.c18
-rw-r--r--arch/x86_64/lib/clear_page.S32
-rw-r--r--arch/x86_64/lib/copy_page.S149
-rw-r--r--arch/x86_64/lib/csum-copy.S294
-rw-r--r--arch/x86_64/lib/csum-partial.c100
-rw-r--r--arch/x86_64/lib/csum-wrappers.c62
-rw-r--r--arch/x86_64/lib/memcpy.S95
-rw-r--r--arch/x86_64/lib/memset.S57
-rw-r--r--arch/x86_64/vmlinux.lds.S7
-rw-r--r--drivers/char/agp/intel-agp.c2
-rw-r--r--drivers/char/rocket.c287
-rw-r--r--drivers/char/rocket.h24
-rw-r--r--drivers/char/rocket_int.h46
-rw-r--r--drivers/ieee1394/dv1394.c7
-rw-r--r--drivers/ieee1394/eth1394.c8
-rw-r--r--drivers/ieee1394/ohci1394.c2
-rw-r--r--drivers/net/acenic.c16
-rw-r--r--drivers/net/dummy.c41
-rw-r--r--drivers/net/net_init.c3
-rw-r--r--drivers/net/ppp_deflate.c4
-rw-r--r--drivers/net/slip.c18
-rw-r--r--drivers/net/sungem.c2
-rw-r--r--drivers/net/sungem.h30
-rw-r--r--drivers/net/tg3.c67
-rw-r--r--drivers/net/tun.c90
-rw-r--r--drivers/pci/pci.ids2
-rw-r--r--drivers/scsi/scsi_scan.c4
-rw-r--r--drivers/serial/8250.c6
-rw-r--r--drivers/serial/8250_acpi.c110
-rw-r--r--drivers/serial/8250_hcdp.c249
-rw-r--r--drivers/serial/8250_hcdp.h79
-rw-r--r--drivers/serial/Kconfig9
-rw-r--r--drivers/serial/Makefile3
-rw-r--r--fs/fs-writeback.c15
-rw-r--r--fs/namei.c2
-rw-r--r--include/asm-generic/vmlinux.lds.h6
-rw-r--r--include/asm-i386/cpufeature.h1
-rw-r--r--include/asm-i386/fixmap.h8
-rw-r--r--include/asm-i386/msr.h3
-rw-r--r--include/asm-ppc64/bug.h57
-rw-r--r--include/asm-ppc64/cputable.h152
-rw-r--r--include/asm-ppc64/machdep.h1
-rw-r--r--include/asm-ppc64/module.h10
-rw-r--r--include/asm-ppc64/processor.h12
-rw-r--r--include/asm-ppc64/uaccess.h217
-rw-r--r--include/asm-ppc64/unistd.h98
-rw-r--r--include/asm-x86_64/checksum.h12
-rw-r--r--include/asm-x86_64/fixmap.h2
-rw-r--r--include/asm-x86_64/mc146818rtc.h5
-rw-r--r--include/asm-x86_64/processor.h2
-rw-r--r--include/asm-x86_64/proto.h2
-rw-r--r--include/asm-x86_64/timex.h30
-rw-r--r--include/asm-x86_64/vsyscall.h18
-rw-r--r--include/linux/acpi_serial.h2
-rw-r--r--include/linux/etherdevice.h1
-rw-r--r--include/linux/highmem.h7
-rw-r--r--include/linux/if_tun.h2
-rw-r--r--include/linux/init.h6
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/netfilter_arp/arp_tables.h2
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/linux/ppp-comp.h2
-rw-r--r--include/linux/security.h39
-rw-r--r--include/linux/serial.h11
-rw-r--r--include/net/flow.h2
-rw-r--r--include/net/sctp/sctp.h43
-rw-r--r--include/net/sctp/structs.h76
-rw-r--r--include/net/sctp/user.h5
-rw-r--r--init/main.c2
-rw-r--r--kernel/sched.c1
-rw-r--r--kernel/sys.c20
-rw-r--r--mm/highmem.c17
-rw-r--r--mm/memory.c14
-rw-r--r--net/8021q/vlan.c90
-rw-r--r--net/8021q/vlan.h2
-rw-r--r--net/8021q/vlan_dev.c22
-rw-r--r--net/bridge/br_device.c9
-rw-r--r--net/bridge/br_if.c21
-rw-r--r--net/bridge/br_input.c6
-rw-r--r--net/bridge/br_netfilter.c2
-rw-r--r--net/bridge/br_notify.c4
-rw-r--r--net/bridge/br_private.h2
-rw-r--r--net/bridge/br_stp.c10
-rw-r--r--net/bridge/br_stp_bpdu.c2
-rw-r--r--net/bridge/br_stp_if.c4
-rw-r--r--net/bridge/br_stp_timer.c16
-rw-r--r--net/bridge/netfilter/ebt_redirect.c2
-rw-r--r--net/bridge/netfilter/ebtables.c4
-rw-r--r--net/core/dev.c45
-rw-r--r--net/core/flow.c139
-rw-r--r--net/core/neighbour.c7
-rw-r--r--net/core/net-sysfs.c163
-rw-r--r--net/ipv4/devinet.c4
-rw-r--r--net/ipv4/ip_gre.c110
-rw-r--r--net/ipv4/ipip.c112
-rw-r--r--net/ipv4/netfilter/iptable_filter.c4
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c4
-rw-r--r--net/ipv4/xfrm4_policy.c3
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/mcast.c4
-rw-r--r--net/ipv6/ndisc.c3
-rw-r--r--net/ipv6/reassembly.c13
-rw-r--r--net/ipv6/sit.c117
-rw-r--r--net/ipv6/udp.c2
-rw-r--r--net/ipv6/xfrm6_policy.c1
-rw-r--r--net/llc/llc_proc.c2
-rw-r--r--net/netsyms.c1
-rw-r--r--net/sctp/associola.c35
-rw-r--r--net/sctp/bind_addr.c4
-rw-r--r--net/sctp/input.c34
-rw-r--r--net/sctp/ipv6.c9
-rw-r--r--net/sctp/objcnt.c2
-rw-r--r--net/sctp/proc.c159
-rw-r--r--net/sctp/protocol.c206
-rw-r--r--net/sctp/sm_make_chunk.c26
-rw-r--r--net/sctp/sm_sideeffect.c3
-rw-r--r--net/sctp/sm_statefuns.c71
-rw-r--r--net/sctp/sm_statetable.c57
-rw-r--r--net/sctp/socket.c410
-rw-r--r--net/sctp/sysctl.c26
-rw-r--r--net/sctp/transport.c18
-rw-r--r--net/xfrm/xfrm_policy.c2
-rw-r--r--security/capability.c10
-rw-r--r--security/dummy.c12
-rw-r--r--security/root_plug.c3
-rw-r--r--security/security.c13
310 files changed, 9438 insertions, 9614 deletions
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
index b1820ebc6d8e..dd93fb46bda1 100644
--- a/Documentation/cpu-freq/user-guide.txt
+++ b/Documentation/cpu-freq/user-guide.txt
@@ -53,9 +53,12 @@ The following processors for the x86 architecture are supported by cpufreq:
AMD Elan - SC400, SC410
AMD mobile K6-2+
AMD mobile K6-3+
+AMD mobile Duron
+AMD mobile Athlon
Cyrix Media GXm
Intel mobile PIII [*] and Intel mobile PIII-M on certain chipsets
Intel Pentium 4, Intel Xeon
+Intel Pentium M (Centrino)
National Semiconductors Geode GX
Transmeta Crusoe
VIA Cyrix 3 / C3
@@ -117,7 +120,7 @@ the processor shall run at.
The preferred interface is located in the sysfs filesystem. If you
mounted it at /sys, the cpufreq interface is located in a subdirectory
"cpufreq" within the cpu-device directory
-(e.g. /sys/devices/sys/cpu0/cpufreq/ for the first CPU).
+(e.g. /sys/class/cpu/cpu0/cpufreq/ for the first CPU).
cpuinfo_min_freq : this file shows the minimum operating
frequency the processor can run at(in kHz)
diff --git a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S
index 863e60644e83..7afd00d5d46b 100644
--- a/arch/alpha/vmlinux.lds.S
+++ b/arch/alpha/vmlinux.lds.S
@@ -74,6 +74,9 @@ SECTIONS
__con_initcall_end = .;
}
+ . = ALIGN(8);
+ SECURITY_INIT
+
. = ALIGN(64);
__per_cpu_start = .;
.data.percpu : { *(.data.percpu) }
diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in
index 18e100b67d67..7fc51a94a942 100644
--- a/arch/arm/vmlinux-armo.lds.in
+++ b/arch/arm/vmlinux-armo.lds.in
@@ -43,6 +43,7 @@ SECTIONS
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(32768);
__init_end = .;
}
diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
index d43fee522ecf..0c84ec532647 100644
--- a/arch/arm/vmlinux-armv.lds.in
+++ b/arch/arm/vmlinux-armv.lds.in
@@ -53,6 +53,7 @@ SECTIONS
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(32);
__initramfs_start = .;
usr/built-in.o(.init.ramfs)
diff --git a/arch/cris/vmlinux.lds.S b/arch/cris/vmlinux.lds.S
index 541857dd070d..3a5f1a36da38 100644
--- a/arch/cris/vmlinux.lds.S
+++ b/arch/cris/vmlinux.lds.S
@@ -74,7 +74,12 @@ SECTIONS
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
-
+ }
+ .security_initcall.init : {
+ __security_initcall_start = .;
+ *(.security_initcall.init)
+ __security_initcall_end = .;
+
/* We fill to the next page, so we can discard all init
pages without needing to consider what payload might be
appended to the kernel image. */
diff --git a/arch/h8300/platform/h8300h/generic/rom.ld b/arch/h8300/platform/h8300h/generic/rom.ld
index 5453fe42b586..412d9006f2ea 100644
--- a/arch/h8300/platform/h8300h/generic/rom.ld
+++ b/arch/h8300/platform/h8300h/generic/rom.ld
@@ -83,6 +83,7 @@ SECTIONS
___con_initcall_start = .;
*(.con_initcall.init)
___con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4);
___initramfs_start = .;
*(.init.ramfs)
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
index 71f31ab0ed73..da2447779055 100644
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig
@@ -11,7 +11,7 @@ config CPU_FREQ
fly. This is a nice method to save battery power on notebooks,
because the lower the clock speed, the less power the CPU consumes.
- For more information, take a look at linux/Documentation/cpufreq or
+ For more information, take a look at linux/Documentation/cpu-freq or
at <http://www.brodo.de/cpufreq/>
If in doubt, say N.
@@ -38,7 +38,7 @@ config X86_ACPI_CPUFREQ
This driver adds a CPUFreq driver which utilizes the ACPI
Processor Performance States.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
@@ -63,7 +63,7 @@ config ELAN_CPUFREQ
parameter: elanfreq=maxspeed (in kHz) or as module
parameter "max_freq".
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
@@ -74,7 +74,7 @@ config X86_POWERNOW_K6
This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
AMD K6-3+ processors.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
@@ -84,7 +84,7 @@ config X86_POWERNOW_K7
help
This adds the CPUFreq driver for mobile AMD K7 mobile processors.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
@@ -95,22 +95,34 @@ config X86_GX_SUSPMOD
This add the CPUFreq driver for NatSemi Geode processors which
support suspend modulation.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
-config X86_SPEEDSTEP
+config X86_SPEEDSTEP_ICH
tristate "Intel Speedstep"
depends on CPU_FREQ_TABLE
help
This adds the CPUFreq driver for certain mobile Intel Pentium III
- (Coppermine), all mobile Intel Pentium III-M (Tulatin) and all
- mobile Intel Pentium 4 P4-Ms.
+ (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all
+ mobile Intel Pentium 4 P4-Ms, with an Intel ICH2, ICH3,
+ or ICH4 southbridge.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
+config X86_SPEEDSTEP_CENTRINO
+ tristate "Intel Enhanced SpeedStep"
+ depends on CPU_FREQ_TABLE
+ help
+ This adds the CPUFreq driver for Enhanced SpeedStep enabled
+ mobile CPUs. This means Intel Pentium M (Centrino) CPUs.
+
+ For details, take a look at linux/Documentation/cpu-freq.
+
+ If in doubt, say N.
+
config X86_P4_CLOCKMOD
tristate "Intel Pentium 4 clock modulation"
depends on CPU_FREQ_TABLE
@@ -118,7 +130,7 @@ config X86_P4_CLOCKMOD
This adds the CPUFreq driver for Intel Pentium 4 / XEON
processors.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
@@ -129,7 +141,7 @@ config X86_LONGRUN
This adds the CPUFreq driver for Transmeta Crusoe processors which
support LongRun.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
@@ -141,7 +153,7 @@ config X86_LONGHAUL
VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
processors.
- For details, take a look at linux/Documentation/cpufreq.
+ For details, take a look at linux/Documentation/cpu-freq.
If in doubt, say N.
diff --git a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile
index 06cfab86c990..89b2a63a7581 100644
--- a/arch/i386/kernel/cpu/cpufreq/Makefile
+++ b/arch/i386/kernel/cpu/cpufreq/Makefile
@@ -1,12 +1,13 @@
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
-obj-$(CONFIG_X86_SPEEDSTEP) += speedstep.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
obj-$(CONFIG_X86_LONGRUN) += longrun.o
obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi.o
+obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
+obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
ifdef CONFIG_X86_ACPI_CPUFREQ
ifdef CONFIG_ACPI_DEBUG
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index 29f210384f0e..5482dc9523c8 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -10,7 +10,6 @@
*
* Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
* - We cli/sti on stepping A0 CPUs around the FID/VID transition.
- * (ADDENDUM: This seems to be needed on more systems, so we do it unconditionally now).
* Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
* - We disable half multipliers if ACPI is used on A0 stepping CPUs.
*/
@@ -260,7 +259,8 @@ static void change_speed (unsigned int index)
/* Now do the magic poking into the MSRs. */
- __asm__("\tcli\n");
+ if (have_a0 == 1) /* A0 errata 5 */
+ __asm__("\tcli\n");
if (freqs.old > freqs.new) {
/* Going down, so change FID first */
@@ -272,7 +272,9 @@ static void change_speed (unsigned int index)
change_FID(vid);
}
- __asm__("\tsti\n");
+
+ if (have_a0 == 1)
+ __asm__("\tsti\n");
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
new file mode 100644
index 000000000000..470ece754595
--- /dev/null
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -0,0 +1,377 @@
+/*
+ * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium
+ * M (part of the Centrino chipset).
+ *
+ * Despite the "SpeedStep" in the name, this is almost entirely unlike
+ * traditional SpeedStep.
+ *
+ * Modelled on speedstep.c
+ *
+ * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
+ *
+ * WARNING WARNING WARNING
+ *
+ * This driver manipulates the PERF_CTL MSR, which is only somewhat
+ * documented. While it seems to work on my laptop, it has not been
+ * tested anywhere else, and it may not work for you, do strange
+ * things or simply crash.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+
+#define PFX "speedstep-centrino: "
+#define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>"
+
+#define CENTRINO_DEBUG
+
+#ifdef CENTRINO_DEBUG
+#define dprintk(msg...) printk(msg)
+#else
+#define dprintk(msg...) do { } while(0)
+#endif
+
+struct cpu_model
+{
+ const char *model_name;
+ unsigned max_freq; /* max clock in kHz */
+
+ struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
+};
+
+/* Operating points for current CPU */
+static const struct cpu_model *centrino_model;
+
+/* Computes the correct form for IA32_PERF_CTL MSR for a particular
+ frequency/voltage operating point; frequency in MHz, volts in mV.
+ This is stored as "index" in the structure. */
+#define OP(mhz, mv) \
+ { \
+ .frequency = (mhz) * 1000, \
+ .index = (((mhz)/100) << 8) | ((mv - 700) / 16) \
+ }
+
+/*
+ * These voltage tables were derived from the Intel Pentium M
+ * datasheet, document 25261202.pdf, Table 5. I have verified they
+ * are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
+ * M.
+ */
+
+/* Ultra Low Voltage Intel Pentium M processor 900MHz */
+static struct cpufreq_frequency_table op_900[] =
+{
+ OP(600, 844),
+ OP(800, 988),
+ OP(900, 1004),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Low Voltage Intel Pentium M processor 1.10GHz */
+static struct cpufreq_frequency_table op_1100[] =
+{
+ OP( 600, 956),
+ OP( 800, 1020),
+ OP( 900, 1100),
+ OP(1000, 1164),
+ OP(1100, 1180),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+
+
+/* Low Voltage Intel Pentium M processor 1.20GHz */
+static struct cpufreq_frequency_table op_1200[] =
+{
+ OP( 600, 956),
+ OP( 800, 1004),
+ OP( 900, 1020),
+ OP(1000, 1100),
+ OP(1100, 1164),
+ OP(1200, 1180),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.30GHz */
+static struct cpufreq_frequency_table op_1300[] =
+{
+ OP( 600, 956),
+ OP( 800, 1260),
+ OP(1000, 1292),
+ OP(1200, 1356),
+ OP(1300, 1388),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.40GHz */
+static struct cpufreq_frequency_table op_1400[] =
+{
+ OP( 600, 956),
+ OP( 800, 1180),
+ OP(1000, 1308),
+ OP(1200, 1436),
+ OP(1400, 1484),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.50GHz */
+static struct cpufreq_frequency_table op_1500[] =
+{
+ OP( 600, 956),
+ OP( 800, 1116),
+ OP(1000, 1228),
+ OP(1200, 1356),
+ OP(1400, 1452),
+ OP(1500, 1484),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.60GHz */
+static struct cpufreq_frequency_table op_1600[] =
+{
+ OP( 600, 956),
+ OP( 800, 1036),
+ OP(1000, 1164),
+ OP(1200, 1276),
+ OP(1400, 1420),
+ OP(1600, 1484),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.70GHz */
+static struct cpufreq_frequency_table op_1700[] =
+{
+ OP( 600, 956),
+ OP( 800, 1004),
+ OP(1000, 1116),
+ OP(1200, 1228),
+ OP(1400, 1308),
+ OP(1700, 1484),
+ { .frequency = CPUFREQ_TABLE_END }
+};
+#undef OP
+
+#define CPU(max) \
+ { "Intel(R) Pentium(R) M processor " #max "MHz", (max)*1000, op_##max }
+
+/* CPU models, their operating frequency range, and freq/voltage
+ operating points */
+static const struct cpu_model models[] =
+{
+ CPU( 900),
+ CPU(1100),
+ CPU(1200),
+ CPU(1300),
+ CPU(1400),
+ CPU(1500),
+ CPU(1600),
+ CPU(1700),
+ { 0, }
+};
+#undef CPU
+
+/* Extract clock in kHz from PERF_CTL value */
+static unsigned extract_clock(unsigned msr)
+{
+ msr = (msr >> 8) & 0xff;
+ return msr * 100000;
+}
+
+/* Return the current CPU frequency in kHz */
+static unsigned get_cur_freq(void)
+{
+ unsigned l, h;
+
+ rdmsr(MSR_IA32_PERF_STATUS, l, h);
+ return extract_clock(l);
+}
+
+static int centrino_cpu_init(struct cpufreq_policy *policy)
+{
+ unsigned freq;
+
+ if (policy->cpu != 0 || centrino_model == NULL)
+ return -ENODEV;
+
+ freq = get_cur_freq();
+
+ policy->policy = (freq == centrino_model->max_freq) ?
+ CPUFREQ_POLICY_PERFORMANCE :
+ CPUFREQ_POLICY_POWERSAVE;
+ policy->cpuinfo.transition_latency = 10; /* 10uS transition latency */
+ policy->cur = freq;
+
+ dprintk(KERN_INFO PFX "centrino_cpu_init: policy=%d cur=%dkHz\n",
+ policy->policy, policy->cur);
+
+ return cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
+}
+
+/**
+ * centrino_verify - verifies a new CPUFreq policy
+ * @freq: new policy
+ *
+ * Limit must be within this model's frequency range at least one
+ * border included.
+ */
+static int centrino_verify (struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, centrino_model->op_points);
+}
+
+/**
+ * centrino_setpolicy - set a new CPUFreq policy
+ * @policy: new policy
+ *
+ * Sets a new CPUFreq policy.
+ */
+static int centrino_target (struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int newstate = 0;
+ unsigned int msr, oldmsr, h;
+ struct cpufreq_freqs freqs;
+
+ if (centrino_model == NULL)
+ return -ENODEV;
+
+ if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
+ relation, &newstate))
+ return -EINVAL;
+
+ msr = centrino_model->op_points[newstate].index;
+ rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
+
+ if (msr == (oldmsr & 0xffff))
+ return 0;
+
+ /* Hm, old frequency can either be the last value we put in
+ PERF_CTL, or whatever it is now. The trouble is that TM2
+ can change it behind our back, which means we never get to
+ see the speed change. Reading back the current speed would
+ tell us something happened, but it may leave the things on
+ the notifier chain confused; we therefore stick to using
+ the last programmed speed rather than the current speed for
+ "old".
+
+ TODO: work out how the TCC interrupts work, and try to
+ catch the CPU changing things under us.
+ */
+ freqs.cpu = 0;
+ freqs.old = extract_clock(oldmsr);
+ freqs.new = extract_clock(msr);
+
+ dprintk(KERN_INFO PFX "target=%dkHz old=%d new=%d msr=%04x\n",
+ target_freq, freqs.old, freqs.new, msr);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* all but 16 LSB are "reserved", so treat them with
+ care */
+ oldmsr &= ~0xffff;
+ msr &= 0xffff;
+ oldmsr |= msr;
+
+ wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+static struct cpufreq_driver centrino_driver = {
+ .name = "centrino", /* should be speedstep-centrino,
+ but there's a 16 char limit */
+ .init = centrino_cpu_init,
+ .verify = centrino_verify,
+ .target = centrino_target,
+ .owner = THIS_MODULE,
+};
+
+
+/**
+ * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
+ *
+ * Initializes the Enhanced SpeedStep support. Returns -ENODEV on
+ * unsupported devices, -ENOENT if there's no voltage table for this
+ * particular CPU model, -EINVAL on problems during initiatization,
+ * and zero on success.
+ *
+ * This is quite picky. Not only does the CPU have to advertise the
+ * "est" flag in the cpuid capability flags, we look for a specific
+ * CPU model and stepping, and we need to have the exact model name in
+ * our voltage tables. That is, be paranoid about not releasing
+ * someone's valuable magic smoke.
+ */
+static int __init centrino_init(void)
+{
+ struct cpuinfo_x86 *cpu = cpu_data;
+ const struct cpu_model *model;
+ unsigned l, h;
+
+ if (!cpu_has(cpu, X86_FEATURE_EST))
+ return -ENODEV;
+
+ /* Only Intel Pentium M stepping 5 for now - add new CPUs as
+ they appear after making sure they use PERF_CTL in the same
+ way. */
+ if (cpu->x86_vendor != X86_VENDOR_INTEL ||
+ cpu->x86 != 6 ||
+ cpu->x86_model != 9 ||
+ cpu->x86_mask != 5) {
+ printk(KERN_INFO PFX "found unsupported CPU with Enhanced SpeedStep: "
+ "send /proc/cpuinfo to " MAINTAINER "\n");
+ return -ENODEV;
+ }
+
+ /* Check to see if Enhanced SpeedStep is enabled, and try to
+ enable it if not. */
+ rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+
+ if (!(l & (1<<16))) {
+ l |= (1<<16);
+ wrmsr(MSR_IA32_MISC_ENABLE, l, h);
+
+ /* check to see if it stuck */
+ rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+ if (!(l & (1<<16))) {
+ printk(KERN_INFO PFX "couldn't enable Enhanced SpeedStep\n");
+ return -ENODEV;
+ }
+ }
+
+ for(model = models; model->model_name != NULL; model++)
+ if (strcmp(cpu->x86_model_id, model->model_name) == 0)
+ break;
+ if (model->model_name == NULL) {
+ printk(KERN_INFO PFX "no support for CPU model \"%s\": "
+ "send /proc/cpuinfo to " MAINTAINER "\n",
+ cpu->x86_model_id);
+ return -ENOENT;
+ }
+
+ centrino_model = model;
+
+ printk(KERN_INFO PFX "found \"%s\": max frequency: %dkHz\n",
+ model->model_name, model->max_freq);
+
+ return cpufreq_register_driver(&centrino_driver);
+}
+
+static void __exit centrino_exit(void)
+{
+ cpufreq_unregister_driver(&centrino_driver);
+}
+
+MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>");
+MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors.");
+MODULE_LICENSE ("GPL");
+
+module_init(centrino_init);
+module_exit(centrino_exit);
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
index 65137016e293..18957e60af0d 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
@@ -503,6 +503,17 @@ static unsigned int speedstep_detect_processor (void)
if (speedstep_coppermine)
return SPEEDSTEP_PROCESSOR_PIII_C;
+ /*
+ * If the processor is a mobile version,
+ * platform ID has bit 50 set
+ * it has SpeedStep technology if either
+ * bit 56 or 57 is set
+ */
+ rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
+ dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi);
+ if ((msr_hi & (1<<18)) && (msr_hi & (3<<24)))
+ return SPEEDSTEP_PROCESSOR_PIII_C;
+
printk(KERN_INFO "cpufreq: in case this is a SpeedStep-capable Intel Pentium III Coppermine\n");
printk(KERN_INFO "cpufreq: processor, please pass the boot option or module parameter\n");
printk(KERN_INFO "cpufreq: `speedstep_coppermine=1` to the kernel. Thanks!\n");
@@ -538,8 +549,10 @@ static int speedstep_detect_speeds (void)
for (i=0; i<2; i++) {
/* read the current state */
result = speedstep_get_state(&state);
- if (result)
+ if (result) {
+ local_irq_restore(flags);
return result;
+ }
/* save the correct value, and switch to other */
if (state == SPEEDSTEP_LOW) {
diff --git a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S
index 5f024651c44a..fb1ef98b8c25 100644
--- a/arch/i386/vmlinux.lds.S
+++ b/arch/i386/vmlinux.lds.S
@@ -81,6 +81,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4);
__alt_instructions = .;
.altinstructions : { *(.altinstructions) }
diff --git a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
index fc52b7b57626..3d9f69fefaa3 100644
--- a/arch/ia64/vmlinux.lds.S
+++ b/arch/ia64/vmlinux.lds.S
@@ -141,6 +141,10 @@ SECTIONS
.con_initcall.init : AT(ADDR(.con_initcall.init) - PAGE_OFFSET)
{ *(.con_initcall.init) }
__con_initcall_end = .;
+ __security_initcall_start = .;
+ .security_initcall.init : AT(ADDR(.security_initcall.init) - PAGE_OFFSET)
+ { *(.security_initcall.init) }
+ __security_initcall_end = .;
. = ALIGN(PAGE_SIZE);
__init_end = .;
diff --git a/arch/m68k/vmlinux-std.lds b/arch/m68k/vmlinux-std.lds
index 959c6ae41430..bd41fc992169 100644
--- a/arch/m68k/vmlinux-std.lds
+++ b/arch/m68k/vmlinux-std.lds
@@ -67,6 +67,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(8192);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff --git a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds
index 03ada554c074..2e81cde14987 100644
--- a/arch/m68k/vmlinux-sun3.lds
+++ b/arch/m68k/vmlinux-sun3.lds
@@ -61,6 +61,7 @@ __init_begin = .;
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(8192);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff --git a/arch/m68knommu/vmlinux.lds.S b/arch/m68knommu/vmlinux.lds.S
index 1ab8a31ef964..fa2004ada4ba 100644
--- a/arch/m68knommu/vmlinux.lds.S
+++ b/arch/m68knommu/vmlinux.lds.S
@@ -277,9 +277,7 @@ SECTIONS {
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
- __security_initcall_start = .;
- *(.security_initcall.init)
- __security_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4);
__initramfs_start = .;
*(.init.ramfs)
diff --git a/arch/mips/vmlinux.lds.S b/arch/mips/vmlinux.lds.S
index edf922683c41..328e87a5face 100644
--- a/arch/mips/vmlinux.lds.S
+++ b/arch/mips/vmlinux.lds.S
@@ -54,6 +54,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096); /* Align double page for init_task_union */
__init_end = .;
diff --git a/arch/mips64/vmlinux.lds.S b/arch/mips64/vmlinux.lds.S
index fe42ea894f53..89bf58aa67bd 100644
--- a/arch/mips64/vmlinux.lds.S
+++ b/arch/mips64/vmlinux.lds.S
@@ -53,6 +53,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096); /* Align double page for init_task_union */
__init_end = .;
diff --git a/arch/parisc/vmlinux.lds.S b/arch/parisc/vmlinux.lds.S
index 99db5cb1cc56..32c089a36c9c 100644
--- a/arch/parisc/vmlinux.lds.S
+++ b/arch/parisc/vmlinux.lds.S
@@ -80,6 +80,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff --git a/arch/ppc/vmlinux.lds.S b/arch/ppc/vmlinux.lds.S
index a682eccfa0dd..467b859c4266 100644
--- a/arch/ppc/vmlinux.lds.S
+++ b/arch/ppc/vmlinux.lds.S
@@ -119,6 +119,8 @@ SECTIONS
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
+
__start___ftr_fixup = .;
__ftr_fixup : { *(__ftr_fixup) }
__stop___ftr_fixup = .;
diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c
index 14f9e81b6474..4616aadfa430 100644
--- a/arch/ppc64/boot/zlib.c
+++ b/arch/ppc64/boot/zlib.c
@@ -1545,10 +1545,11 @@ local inflate_huft *fixed_tl;
local inflate_huft *fixed_td;
-local voidpf falloc(q, n, s)
-voidpf q; /* opaque pointer (not used) */
-uInt n; /* number of items */
-uInt s; /* size of item */
+local voidpf falloc(
+ voidpf q, /* opaque pointer (not used) */
+ uInt n, /* number of items */
+ uInt s /* size of item */
+)
{
Assert(s == sizeof(inflate_huft) && n <= fixed_left,
"inflate_trees falloc overflow");
@@ -1558,10 +1559,11 @@ uInt s; /* size of item */
}
-local void ffree(q, p, n)
-voidpf q;
-voidpf p;
-uInt n;
+local void ffree(
+ voidpf q,
+ voidpf p,
+ uInt n
+)
{
Assert(0, "inflate_trees ffree called!");
if (q) q = p; /* to make some compilers happy */
@@ -2164,10 +2166,11 @@ char *z_errmsg[] = {
#define DO16(buf) DO8(buf); DO8(buf);
/* ========================================================================= */
-uLong adler32(adler, buf, len)
- uLong adler;
- Bytef *buf;
- uInt len;
+uLong adler32(
+ uLong adler,
+ Bytef *buf,
+ uInt len
+)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index a0cd5e999c2c..f50669841002 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -9,7 +9,7 @@ obj-y := setup.o entry.o traps.o irq.o idle.o \
align.o semaphore.o bitops.o stab.o htab.o pacaData.o \
udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
ptrace32.o signal32.o pmc.o rtc.o init_task.o \
- lmb.o pci.o pci_dn.o pci_dma.o
+ lmb.o pci.o pci_dn.o pci_dma.o cputable.o
obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o \
iSeries_IoMmTable.o iSeries_irq.o \
@@ -19,11 +19,11 @@ obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o \
mf.o HvLpEvent.o iSeries_proc.o
obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
- eeh.o rtasd.o nvram.o
+ eeh.o rtasd.o nvram.o ras.o
# Change this to pSeries only once we've got iSeries up to date
obj-y += open_pic.o xics.o pSeries_htab.o rtas.o \
- chrp_setup.o i8259.o ras.o prom.o
+ chrp_setup.o i8259.o prom.o
obj-$(CONFIG_PROC_FS) += proc_ppc64.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
@@ -31,3 +31,5 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_PPC_RTAS) += rtas-proc.o
obj-$(CONFIG_SCANLOG) += scanlog.o
+
+CFLAGS_ioctl32.o += -Ifs/
diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
index 37932d7c6b52..dc455830dd3d 100644
--- a/arch/ppc64/kernel/align.c
+++ b/arch/ppc64/kernel/align.c
@@ -20,6 +20,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/cache.h>
+#include <asm/cputable.h>
void disable_kernel_fp(void); /* asm function from head.S */
@@ -238,12 +239,11 @@ fix_alignment(struct pt_regs *regs)
dsisr = regs->dsisr;
- /* Power4 doesn't set DSISR for an alignment interrupt */
- if (!cpu_alignexc_sets_dsisr()) {
- unsigned int real_instr;
- if (__get_user(real_instr, (unsigned int *)regs->nip))
- return 0;
- dsisr = make_dsisr(real_instr);
+ if (cur_cpu_spec->cpu_features & CPU_FTR_NODSISRALIGN) {
+ unsigned int real_instr;
+ if (__get_user(real_instr, (unsigned int *)regs->nip))
+ return 0;
+ dsisr = make_dsisr(*((unsigned *)regs->nip));
}
/* extract the operation and registers from the dsisr */
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index b5797dda4c63..1bc9b089757b 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -34,6 +34,7 @@
#include <asm/iSeries/HvLpEvent.h>
#include <asm/prom.h>
#include <asm/rtas.h>
+#include <asm/cputable.h>
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -159,5 +160,12 @@ int main(void)
DEFINE(CLONE_VM, CLONE_VM);
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
+ /* About the CPU features table */
+ DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
+ DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
+ DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
+ DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
+ DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+
return 0;
}
diff --git a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c
index 4c65ab34cde3..f8b48d41809e 100644
--- a/arch/ppc64/kernel/chrp_setup.c
+++ b/arch/ppc64/kernel/chrp_setup.c
@@ -62,13 +62,13 @@
#include "open_pic.h"
#include <asm/xics.h>
#include <asm/ppcdebug.h>
+#include <asm/cputable.h>
extern volatile unsigned char *chrp_int_ack_special;
void chrp_progress(char *, unsigned short);
extern void openpic_init_IRQ(void);
-extern void init_ras_IRQ(void);
extern void find_and_init_phbs(void);
@@ -238,7 +238,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.init_IRQ = xics_init_IRQ;
ppc_md.get_irq = xics_get_irq;
}
- ppc_md.init_ras_IRQ = init_ras_IRQ;
ppc_md.init = chrp_init2;
@@ -253,6 +252,34 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.progress = chrp_progress;
+ /* build up the firmware_features bitmask field
+ * using contents of device-tree/ibm,hypertas-functions.
+ * Ultimately this functionality may be moved into prom.c prom_init().
+ */
+ struct device_node * dn;
+ char * hypertas;
+ unsigned int len;
+ dn = find_path_device("/rtas");
+ cur_cpu_spec->firmware_features = 0;
+ hypertas = get_property(dn, "ibm,hypertas-functions", &len);
+ if (hypertas) {
+ while (len > 0){
+ int i;
+ /* check value against table of strings */
+ for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) {
+ if ((firmware_features_table[i].name) && (strcmp(firmware_features_table[i].name,hypertas))==0) {
+ /* we have a match */
+ cur_cpu_spec->firmware_features |= (1UL << firmware_features_table[i].val);
+ break;
+ }
+ }
+ int hypertas_len = strlen(hypertas);
+ len -= hypertas_len +1;
+ hypertas+= hypertas_len +1;
+ }
+ }
+ udbg_printf("firmware_features bitmask: 0x%x \n",
+ cur_cpu_spec->firmware_features);
}
void
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
new file mode 100644
index 000000000000..3a31562c7018
--- /dev/null
+++ b/arch/ppc64/kernel/cputable.c
@@ -0,0 +1,127 @@
+/*
+ * arch/ppc64/kernel/cputable.c
+ *
+ * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
+ *
+ * Modifications for ppc64:
+ * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/init.h>
+#include <asm/cputable.h>
+
+struct cpu_spec* cur_cpu_spec = NULL;
+
+extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
+
+
+/* We only set the altivec features if the kernel was compiled with altivec
+ * support
+ */
+#ifdef CONFIG_ALTIVEC
+#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
+#else
+#define CPU_FTR_ALTIVEC_COMP 0
+#endif
+
+struct cpu_spec cpu_specs[] = {
+ { /* Power3 */
+ 0xffff0000, 0x00400000, "Power3 (630)",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power3,
+ COMMON_PPC64_FW
+ },
+ { /* Power3+ */
+ 0xffff0000, 0x00410000, "Power3 (630+)",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power3,
+ COMMON_PPC64_FW
+ },
+ { /* Northstar */
+ 0xffff0000, 0x00330000, "Northstar",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power3,
+ COMMON_PPC64_FW
+ },
+ { /* Pulsar */
+ 0xffff0000, 0x00340000, "Pulsar",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power3,
+ COMMON_PPC64_FW
+ },
+ { /* I-star */
+ 0xffff0000, 0x00360000, "I-star",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power3,
+ COMMON_PPC64_FW
+ },
+ { /* S-star */
+ 0xffff0000, 0x00370000, "S-star",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power3,
+ COMMON_PPC64_FW
+ },
+ { /* Power4 */
+ 0xffff0000, 0x00350000, "Power4",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_PPCAS_ARCH_V2,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power4,
+ COMMON_PPC64_FW
+ },
+ { /* Power4+ */
+ 0xffff0000, 0x00380000, "Power4+",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_PPCAS_ARCH_V2,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power4,
+ COMMON_PPC64_FW
+ },
+ { /* default match */
+ 0x00000000, 0x00000000, "(Power4-Compatible)",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+ CPU_FTR_PPCAS_ARCH_V2,
+ COMMON_USER_PPC64,
+ 128, 128,
+ __setup_cpu_power4,
+ COMMON_PPC64_FW
+ }
+};
+
+firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
+ {FW_FEATURE_PFT, "hcall-pft"},
+ {FW_FEATURE_TCE, "hcall-tce"},
+ {FW_FEATURE_SPRG0, "hcall-sprg0"},
+ {FW_FEATURE_DABR, "hcall-dabr"},
+ {FW_FEATURE_COPY, "hcall-copy"},
+ {FW_FEATURE_ASR, "hcall-asr"},
+ {FW_FEATURE_DEBUG, "hcall-debug"},
+ {FW_FEATURE_PERF, "hcall-perf"},
+ {FW_FEATURE_DUMP, "hcall-dump"},
+ {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
+ {FW_FEATURE_MIGRATE, "hcall-migrate"},
+};
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index af07d47095b8..ed6010a60ab6 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -34,6 +34,7 @@
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
#include <asm/bug.h>
+#include <asm/cputable.h>
#ifdef CONFIG_PPC_ISERIES
#define DO_SOFT_DISABLE
@@ -1267,6 +1268,11 @@ _GLOBAL(__start_initialization_iSeries)
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
+ LOADADDR(r3,cpu_specs)
+ LOADADDR(r4,cur_cpu_spec)
+ li r5,0
+ bl .identify_cpu
+
LOADADDR(r2,__toc_start)
addi r2,r2,0x4000
addi r2,r2,0x4000
@@ -1730,6 +1736,13 @@ _STATIC(start_here_pSeries)
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
+ LOADADDR(r3,cpu_specs)
+ sub r3,r3,r26
+ LOADADDR(r4,cur_cpu_spec)
+ sub r4,r4,r26
+ mr r5,r26
+ bl .identify_cpu
+
/* set up the TOC (physical address) */
LOADADDR(r2,__toc_start)
addi r2,r2,0x4000
@@ -1888,6 +1901,11 @@ _STATIC(start_here_common)
bl .start_kernel
+_GLOBAL(__setup_cpu_power3)
+ blr
+_GLOBAL(__setup_cpu_power4)
+ blr
+
_GLOBAL(hmt_init)
#ifdef CONFIG_HMT
LOADADDR(r5, hmt_thread_data)
diff --git a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c
index effd5bed4d9b..51a2f7c96950 100644
--- a/arch/ppc64/kernel/htab.c
+++ b/arch/ppc64/kernel/htab.c
@@ -46,6 +46,7 @@
#include <asm/eeh.h>
#include <asm/tlb.h>
#include <asm/cacheflush.h>
+#include <asm/cputable.h>
/*
* Note: pte --> Linux PTE
@@ -165,7 +166,8 @@ htab_initialize(void)
mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
/* XXX we currently map kernel text rw, should fix this */
- if (cpu_has_largepage() && systemcfg->physicalMemorySize > 256*MB) {
+ if ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
+ && systemcfg->physicalMemorySize > 256*MB) {
create_pte_mapping((unsigned long)KERNELBASE,
KERNELBASE + 256*MB, mode_rw, 0);
create_pte_mapping((unsigned long)KERNELBASE + 256*MB,
@@ -279,7 +281,8 @@ int __hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
#define PPC64_HWNOEXEC (1 << 2)
/* We do lazy icache flushing on cpus that support it */
- if (unlikely(cpu_has_noexecute() && pfn_valid(pte_pfn(new_pte)))) {
+ if (unlikely((cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)
+ && pfn_valid(pte_pfn(new_pte)))) {
struct page *page = pte_page(new_pte);
/* page is dirty */
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index 759674b044a4..b4d54e1c8337 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -33,6 +33,7 @@
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
+#include <asm/cputable.h>
#include <asm/time.h>
#include "iSeries_setup.h"
@@ -254,7 +255,7 @@ unsigned long iSeries_process_mainstore_vpd( struct MemoryBlock *mb_array, unsig
{
unsigned long i;
unsigned long mem_blocks = 0;
- if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+ if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
mem_blocks = iSeries_process_Regatta_mainstore_vpd( mb_array, max_entries );
else
mem_blocks = iSeries_process_Condor_mainstore_vpd( mb_array, max_entries );
@@ -311,7 +312,6 @@ iSeries_init_early(void)
ppc_md.setup_residual = iSeries_setup_residual;
ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
ppc_md.init_IRQ = iSeries_init_IRQ;
- ppc_md.init_ras_IRQ = NULL;
ppc_md.get_irq = iSeries_get_irq;
ppc_md.init = NULL;
diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
index 3cd971a895b6..5a5aed4c1890 100644
--- a/arch/ppc64/kernel/ioctl32.c
+++ b/arch/ppc64/kernel/ioctl32.c
@@ -20,852 +20,13 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/compat.h>
-#include <linux/ioctl32.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/ioctl.h>
-#include <linux/if.h>
-#include <linux/slab.h>
-#include <linux/hdreg.h>
-#include <linux/raid/md.h>
-#include <linux/kd.h>
-#include <linux/route.h>
-#include <linux/in6.h>
-#include <linux/ipv6_route.h>
-#include <linux/skbuff.h>
-#include <linux/netlink.h>
-#include <linux/vt.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/fd.h>
-#include <linux/ppp_defs.h>
-#include <linux/if_ppp.h>
-#include <linux/if_pppox.h>
-#include <linux/if_tun.h>
-#include <linux/mtio.h>
-#include <linux/cdrom.h>
-#include <linux/loop.h>
-#include <linux/auto_fs.h>
-#include <linux/auto_fs4.h>
-#include <linux/devfs_fs.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>
-#include <linux/fb.h>
-#include <linux/ext2_fs.h>
-#include <linux/videodev.h>
-#include <linux/netdevice.h>
-#include <linux/raw.h>
-#include <linux/smb_fs.h>
+#define INCLUDES
+#include "compat_ioctl.c"
#include <linux/ncp_fs.h>
-#include <linux/blkpg.h>
-#include <linux/blk.h>
-#include <linux/elevator.h>
-#include <linux/rtc.h>
-#include <linux/pci.h>
-#include <linux/dm-ioctl.h>
-
-#include <scsi/scsi.h>
-/* Ugly hack. */
-#undef __KERNEL__
-#include <scsi/scsi_ioctl.h>
-#define __KERNEL__
-#include <scsi/sg.h>
-
-#include <asm/types.h>
-#include <asm/uaccess.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/if_bonding.h>
-#include <asm/module.h>
-#include <linux/soundcard.h>
-#include <linux/watchdog.h>
-#include <linux/lp.h>
-
-#include <linux/atm.h>
-#include <linux/atmarp.h>
-#include <linux/atmclip.h>
-#include <linux/atmdev.h>
-#include <linux/atmioc.h>
-#include <linux/atmlec.h>
-#include <linux/atmmpc.h>
-#include <linux/atmsvc.h>
-#include <linux/atm_tcp.h>
-#include <linux/sonet.h>
-#include <linux/atm_suni.h>
-#include <linux/mtd/mtd.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci.h>
-#include <net/bluetooth/rfcomm.h>
-
-#include <linux/usb.h>
-#include <linux/usbdevice_fs.h>
-#include <linux/nbd.h>
-#include <linux/random.h>
#include <asm/ppc32.h>
-#include <asm/ppcdebug.h>
-/* Aiee. Someone does not find a difference between int and long */
-#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
-#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
-#define EXT2_IOC32_GETVERSION _IOR('v', 1, int)
-#define EXT2_IOC32_SETVERSION _IOW('v', 2, int)
-
-extern asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
-
-static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- int err;
- unsigned long val;
-
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&val);
- set_fs (old_fs);
- if (!err && put_user(val, (u32 *)arg))
- return -EFAULT;
- return err;
-}
-
-static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- int err;
- unsigned long val;
-
- if (get_user(val, (u32 *)arg))
- return -EFAULT;
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&val);
- set_fs (old_fs);
- if (!err && put_user(val, (u32 *)arg))
- return -EFAULT;
- return err;
-}
-
-static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- /* These are just misnamed, they actually get/put from/to user an int */
- switch (cmd) {
- case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
- case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
- case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
- case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
- }
- return sys_ioctl(fd, cmd, arg);
-}
-
-struct video_tuner32 {
- s32 tuner;
- u8 name[32];
- u32 rangelow, rangehigh;
- u32 flags;
- u16 mode, signal;
-};
-
-static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
-{
- int i;
-
- if (get_user(kp->tuner, &up->tuner))
- return -EFAULT;
- for(i = 0; i < 32; i++)
- __get_user(kp->name[i], &up->name[i]);
- __get_user(kp->rangelow, &up->rangelow);
- __get_user(kp->rangehigh, &up->rangehigh);
- __get_user(kp->flags, &up->flags);
- __get_user(kp->mode, &up->mode);
- __get_user(kp->signal, &up->signal);
- return 0;
-}
-
-static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
-{
- int i;
-
- if (put_user(kp->tuner, &up->tuner))
- return -EFAULT;
- for(i = 0; i < 32; i++)
- __put_user(kp->name[i], &up->name[i]);
- __put_user(kp->rangelow, &up->rangelow);
- __put_user(kp->rangehigh, &up->rangehigh);
- __put_user(kp->flags, &up->flags);
- __put_user(kp->mode, &up->mode);
- __put_user(kp->signal, &up->signal);
- return 0;
-}
-
-struct video_buffer32 {
- /* void * */ u32 base;
- s32 height, width, depth, bytesperline;
-};
-
-static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
-{
- u32 tmp;
-
- if (get_user(tmp, &up->base))
- return -EFAULT;
- kp->base = (void *) ((unsigned long)tmp);
- __get_user(kp->height, &up->height);
- __get_user(kp->width, &up->width);
- __get_user(kp->depth, &up->depth);
- __get_user(kp->bytesperline, &up->bytesperline);
- return 0;
-}
-
-static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
-{
- u32 tmp = (u32)((unsigned long)kp->base);
-
- if (put_user(tmp, &up->base))
- return -EFAULT;
- __put_user(kp->height, &up->height);
- __put_user(kp->width, &up->width);
- __put_user(kp->depth, &up->depth);
- __put_user(kp->bytesperline, &up->bytesperline);
- return 0;
-}
-
-struct video_clip32 {
- s32 x, y, width, height;
- /* struct video_clip32 * */ u32 next;
-};
-
-struct video_window32 {
- u32 x, y, width, height, chromakey, flags;
- /* struct video_clip32 * */ u32 clips;
- s32 clipcount;
-};
-
-static void free_kvideo_clips(struct video_window *kp)
-{
- struct video_clip *cp;
-
- cp = kp->clips;
- if (cp != NULL)
- kfree(cp);
-}
-
-static int get_video_window32(struct video_window *kp, struct video_window32 *up)
-{
- struct video_clip32 *ucp;
- struct video_clip *kcp;
- int nclips, err, i;
- u32 tmp;
-
- if (get_user(kp->x, &up->x))
- return -EFAULT;
- __get_user(kp->y, &up->y);
- __get_user(kp->width, &up->width);
- __get_user(kp->height, &up->height);
- __get_user(kp->chromakey, &up->chromakey);
- __get_user(kp->flags, &up->flags);
- __get_user(kp->clipcount, &up->clipcount);
- __get_user(tmp, &up->clips);
- ucp = (struct video_clip32 *)A(tmp);
- kp->clips = NULL;
-
- nclips = kp->clipcount;
- if (nclips == 0)
- return 0;
-
- if (ucp == 0)
- return -EINVAL;
-
- /* Peculiar interface... */
- if (nclips < 0)
- nclips = VIDEO_CLIPMAP_SIZE;
-
- kcp = kmalloc(nclips * sizeof(struct video_clip), GFP_KERNEL);
- err = -ENOMEM;
- if (kcp == NULL)
- goto cleanup_and_err;
-
- kp->clips = kcp;
- for(i = 0; i < nclips; i++) {
- __get_user(kcp[i].x, &ucp[i].x);
- __get_user(kcp[i].y, &ucp[i].y);
- __get_user(kcp[i].width, &ucp[i].width);
- __get_user(kcp[i].height, &ucp[i].height);
- kcp[nclips].next = NULL;
- }
-
- return 0;
-
-cleanup_and_err:
- free_kvideo_clips(kp);
- return err;
-}
-
-/* You get back everything except the clips... */
-static int put_video_window32(struct video_window *kp, struct video_window32 *up)
-{
- if (put_user(kp->x, &up->x))
- return -EFAULT;
- __put_user(kp->y, &up->y);
- __put_user(kp->width, &up->width);
- __put_user(kp->height, &up->height);
- __put_user(kp->chromakey, &up->chromakey);
- __put_user(kp->flags, &up->flags);
- __put_user(kp->clipcount, &up->clipcount);
- return 0;
-}
-
-#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32)
-#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32)
-#define VIDIOCGWIN32 _IOR('v',9, struct video_window32)
-#define VIDIOCSWIN32 _IOW('v',10, struct video_window32)
-#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32)
-#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32)
-#define VIDIOCGFREQ32 _IOR('v',14, u32)
-#define VIDIOCSFREQ32 _IOW('v',15, u32)
-
-static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- union {
- struct video_tuner vt;
- struct video_buffer vb;
- struct video_window vw;
- unsigned long vx;
- } karg;
- mm_segment_t old_fs = get_fs();
- void *up = (void *)arg;
- int err = 0;
-
- /* First, convert the command. */
- switch(cmd) {
- case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
- case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
- case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
- case VIDIOCSWIN32: cmd = VIDIOCSWIN; break;
- case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
- case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
- case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
- case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
- };
-
- switch(cmd) {
- case VIDIOCSTUNER:
- case VIDIOCGTUNER:
- err = get_video_tuner32(&karg.vt, up);
- break;
-
- case VIDIOCSWIN:
- err = get_video_window32(&karg.vw, up);
- break;
-
- case VIDIOCSFBUF:
- err = get_video_buffer32(&karg.vb, up);
- break;
-
- case VIDIOCSFREQ:
- err = get_user(karg.vx, (u32 *)up);
- break;
- };
- if (err)
- goto out;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&karg);
- set_fs(old_fs);
-
- if (cmd == VIDIOCSWIN)
- free_kvideo_clips(&karg.vw);
-
- if (err == 0) {
- switch(cmd) {
- case VIDIOCGTUNER:
- err = put_video_tuner32(&karg.vt, up);
- break;
-
- case VIDIOCGWIN:
- err = put_video_window32(&karg.vw, up);
- break;
-
- case VIDIOCGFBUF:
- err = put_video_buffer32(&karg.vb, up);
- break;
-
- case VIDIOCGFREQ:
- err = put_user(((u32)karg.vx), (u32 *)up);
- break;
- };
- }
-out:
- return err;
-}
-
-static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct compat_timeval *up = (struct compat_timeval *)arg;
- struct timeval ktv;
- mm_segment_t old_fs = get_fs();
- int err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
- set_fs(old_fs);
- if (!err) {
- err = put_user(ktv.tv_sec, &up->tv_sec);
- err |= __put_user(ktv.tv_usec, &up->tv_usec);
- }
- return err;
-}
-
-struct ifmap32 {
- u32 mem_start;
- u32 mem_end;
- unsigned short base_addr;
- unsigned char irq;
- unsigned char dma;
- unsigned char port;
-};
-
-struct ifreq32 {
-#define IFHWADDRLEN 6
-#define IFNAMSIZ 16
- union {
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- } ifr_ifrn;
- union {
- struct sockaddr ifru_addr;
- struct sockaddr ifru_dstaddr;
- struct sockaddr ifru_broadaddr;
- struct sockaddr ifru_netmask;
- struct sockaddr ifru_hwaddr;
- short ifru_flags;
- int ifru_ivalue;
- int ifru_mtu;
- struct ifmap32 ifru_map;
- char ifru_slave[IFNAMSIZ]; /* Just fits the size */
- char ifru_newname[IFNAMSIZ];
- compat_caddr_t ifru_data;
- } ifr_ifru;
-};
-
-struct ifconf32 {
- int ifc_len; /* size of buffer */
- compat_caddr_t ifcbuf;
-};
-
-#ifdef CONFIG_NET
-static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct net_device *dev;
- struct ifreq32 ifr32;
- int err;
-
- if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
-
- dev = dev_get_by_index(ifr32.ifr_ifindex);
- if (!dev)
- return -ENODEV;
-
- strcpy(ifr32.ifr_name, dev->name);
- dev_put(dev);
-
- err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
- return (err ? -EFAULT : 0);
-}
-#endif
-
-static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ifconf32 ifc32;
- struct ifconf ifc;
- struct ifreq32 *ifr32;
- struct ifreq *ifr;
- mm_segment_t old_fs;
- unsigned int i, j;
- int err;
-
- if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))
- return -EFAULT;
-
- if (ifc32.ifcbuf == 0) {
- ifc32.ifc_len = 0;
- ifc.ifc_len = 0;
- ifc.ifc_buf = NULL;
- } else {
- ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
- sizeof (struct ifreq);
- ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
- if (!ifc.ifc_buf)
- return -ENOMEM;
- }
- ifr = ifc.ifc_req;
- ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
- for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
- if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
- kfree (ifc.ifc_buf);
- return -EFAULT;
- }
- }
- old_fs = get_fs(); set_fs (KERNEL_DS);
- err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
- set_fs (old_fs);
- if (!err) {
- ifr = ifc.ifc_req;
- ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
- for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
- i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
- if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
- err = -EFAULT;
- break;
- }
- }
- if (!err) {
- if (ifc32.ifcbuf == 0) {
- /* Translate from 64-bit structure multiple to
- * a 32-bit one.
- */
- i = ifc.ifc_len;
- i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
- ifc32.ifc_len = i;
- } else {
- if (i <= ifc32.ifc_len)
- ifc32.ifc_len = i;
- else
- ifc32.ifc_len = i - sizeof (struct ifreq32);
- }
- if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
- err = -EFAULT;
- }
- }
- if (ifc.ifc_buf != NULL)
- kfree (ifc.ifc_buf);
- return err;
-}
-
-static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ifreq ifr;
- mm_segment_t old_fs;
- int err, len;
- u32 data, ethcmd;
-
- if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
- ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
- if (!ifr.ifr_data)
- return -EAGAIN;
-
- __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
-
- if (get_user(ethcmd, (u32 *)A(data))) {
- err = -EFAULT;
- goto out;
- }
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO: len = sizeof(struct ethtool_drvinfo); break;
- case ETHTOOL_GMSGLVL:
- case ETHTOOL_SMSGLVL:
- case ETHTOOL_GLINK:
- case ETHTOOL_NWAY_RST: len = sizeof(struct ethtool_value); break;
- case ETHTOOL_GREGS: {
- struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
- /* darned variable size arguments */
- if (get_user(len, (u32 *)&regaddr->len)) {
- err = -EFAULT;
- goto out;
- }
- len += sizeof(struct ethtool_regs);
- break;
- }
- case ETHTOOL_GEEPROM:
- case ETHTOOL_SEEPROM: {
- struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data);
- /* darned variable size arguments */
- if (get_user(len, (u32 *)&promaddr->len)) {
- err = -EFAULT;
- goto out;
- }
- len += sizeof(struct ethtool_eeprom);
- break;
- }
- case ETHTOOL_GSET:
- case ETHTOOL_SSET: len = sizeof(struct ethtool_cmd); break;
- default:
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
- err = -EFAULT;
- goto out;
- }
-
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
- set_fs (old_fs);
- if (!err) {
- u32 data;
-
- __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
- len = copy_to_user((char *)A(data), ifr.ifr_data, len);
- if (len)
- err = -EFAULT;
- }
-
-out:
- free_page((unsigned long)ifr.ifr_data);
- return err;
-}
-
-static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
-{
- struct ifreq ifr;
- mm_segment_t old_fs;
- int err, len;
- u32 data;
-
- if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
- ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
- if (!ifr.ifr_data)
- return -EAGAIN;
-
- switch (cmd) {
- case SIOCBONDENSLAVE:
- case SIOCBONDRELEASE:
- case SIOCBONDSETHWADDR:
- case SIOCBONDCHANGEACTIVE:
- len = IFNAMSIZ * sizeof(char);
- break;
- case SIOCBONDSLAVEINFOQUERY:
- len = sizeof(struct ifslave);
- break;
- case SIOCBONDINFOQUERY:
- len = sizeof(struct ifbond);
- break;
- default:
- err = -EINVAL;
- goto out;
- };
-
- __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
- if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
- err = -EFAULT;
- goto out;
- }
-
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
- set_fs (old_fs);
- if (!err) {
- len = copy_to_user((char *)A(data), ifr.ifr_data, len);
- if (len)
- err = -EFAULT;
- }
-
-out:
- free_page((unsigned long)ifr.ifr_data);
- return err;
-}
-
-int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ifreq *u_ifreq64;
- struct ifreq32 *u_ifreq32 = (struct ifreq32 *) arg;
- char tmp_buf[IFNAMSIZ];
- void __user *data64;
- u32 data32;
-
- if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
- IFNAMSIZ))
- return -EFAULT;
- if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
- return -EFAULT;
- data64 = (void __user *)A(data32);
-
- u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
-
- /* Don't check these user accesses, just let that get trapped
- * in the ioctl handler instead.
- */
- copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
- __put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
-
- return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
-}
-
-static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct ifreq ifr;
- mm_segment_t old_fs;
- int err;
-
- switch (cmd) {
- case SIOCSIFMAP:
- err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
- err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
- err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
- err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
- err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
- err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
- err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
- if (err)
- return -EFAULT;
- break;
- default:
- if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
- break;
- }
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
- set_fs (old_fs);
- if (!err) {
- switch (cmd) {
- case SIOCGIFFLAGS:
- case SIOCGIFMETRIC:
- case SIOCGIFMTU:
- case SIOCGIFMEM:
- case SIOCGIFHWADDR:
- case SIOCGIFINDEX:
- case SIOCGIFADDR:
- case SIOCGIFBRDADDR:
- case SIOCGIFDSTADDR:
- case SIOCGIFNETMASK:
- case SIOCGIFTXQLEN:
- if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
- return -EFAULT;
- break;
- case SIOCGIFMAP:
- err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
- err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
- err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
- err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
- err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
- err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
- err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
- if (err)
- err = -EFAULT;
- break;
- }
- }
- return err;
-}
-
-struct rtentry32 {
- u32 rt_pad1;
- struct sockaddr rt_dst; /* target address */
- struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
- struct sockaddr rt_genmask; /* target network mask (IP) */
- unsigned short rt_flags;
- short rt_pad2;
- u32 rt_pad3;
- unsigned char rt_tos;
- unsigned char rt_class;
- short rt_pad4;
- short rt_metric; /* +1 for binary compatibility! */
- /* char * */ u32 rt_dev; /* forcing the device at add */
- u32 rt_mtu; /* per route MTU/Window */
- u32 rt_window; /* Window clamping */
- unsigned short rt_irtt; /* Initial RTT */
-
-};
-
-struct in6_rtmsg32 {
- struct in6_addr rtmsg_dst;
- struct in6_addr rtmsg_src;
- struct in6_addr rtmsg_gateway;
- u32 rtmsg_type;
- u16 rtmsg_dst_len;
- u16 rtmsg_src_len;
- u32 rtmsg_metric;
- u32 rtmsg_info;
- u32 rtmsg_flags;
- s32 rtmsg_ifindex;
-};
-
-static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- int ret;
- void *r = NULL;
- struct in6_rtmsg r6;
- struct rtentry r4;
- char devname[16];
- u32 rtdev;
- mm_segment_t old_fs = get_fs();
-
- struct socket *mysock = sockfd_lookup(fd, &ret);
-
- if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */
- ret = copy_from_user (&r6.rtmsg_dst, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst),
- 3 * sizeof(struct in6_addr));
- ret |= __get_user (r6.rtmsg_type, &(((struct in6_rtmsg32 *)arg)->rtmsg_type));
- ret |= __get_user (r6.rtmsg_dst_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_dst_len));
- ret |= __get_user (r6.rtmsg_src_len, &(((struct in6_rtmsg32 *)arg)->rtmsg_src_len));
- ret |= __get_user (r6.rtmsg_metric, &(((struct in6_rtmsg32 *)arg)->rtmsg_metric));
- ret |= __get_user (r6.rtmsg_info, &(((struct in6_rtmsg32 *)arg)->rtmsg_info));
- ret |= __get_user (r6.rtmsg_flags, &(((struct in6_rtmsg32 *)arg)->rtmsg_flags));
- ret |= __get_user (r6.rtmsg_ifindex, &(((struct in6_rtmsg32 *)arg)->rtmsg_ifindex));
-
- r = (void *) &r6;
- } else { /* ipv4 */
- ret = copy_from_user (&r4.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));
- ret |= __get_user (r4.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));
- ret |= __get_user (r4.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));
- ret |= __get_user (r4.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));
- ret |= __get_user (r4.rt_window, &(((struct rtentry32 *)arg)->rt_window));
- ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));
- ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));
- if (rtdev) {
- ret |= copy_from_user (devname, (char *)A(rtdev), 15);
- r4.rt_dev = devname; devname[15] = 0;
- } else
- r4.rt_dev = 0;
-
- r = (void *) &r4;
- }
-
- if (ret)
- return -EFAULT;
-
- set_fs (KERNEL_DS);
- ret = sys_ioctl (fd, cmd, (long) r);
- set_fs (old_fs);
-
- if (mysock)
- sockfd_put(mysock);
-
- return ret;
-}
-
-struct hd_geometry32 {
- unsigned char heads;
- unsigned char sectors;
- unsigned short cylinders;
- u32 start;
-};
-
-static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct hd_geometry geo;
- int err;
-
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
- set_fs (old_fs);
- if (!err) {
- if (copy_to_user ((struct hd_geometry32 *)arg, &geo, 4) ||
- __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start)))
- err = -EFAULT;
- }
- return err;
-}
+#define CODE
+#include "compat_ioctl.c"
struct hd_big_geometry32 {
unsigned char heads;
@@ -895,1210 +56,6 @@ static int hdio_getgeo_big(unsigned int fd, unsigned int cmd, unsigned long arg)
return err;
}
-static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- unsigned long kval;
- unsigned int *uvp;
- int error;
-
- set_fs(KERNEL_DS);
- error = sys_ioctl(fd, cmd, (long)&kval);
- set_fs(old_fs);
-
- if (error == 0) {
- uvp = (unsigned int *)arg;
- if (put_user(kval, uvp))
- error = -EFAULT;
- }
- return error;
-}
-
-struct floppy_struct32 {
- unsigned int size;
- unsigned int sect;
- unsigned int head;
- unsigned int track;
- unsigned int stretch;
- unsigned char gap;
- unsigned char rate;
- unsigned char spec1;
- unsigned char fmt_gap;
- const compat_caddr_t name;
-};
-
-struct floppy_drive_params32 {
- char cmos;
- u32 max_dtr;
- u32 hlt;
- u32 hut;
- u32 srt;
- u32 spinup;
- u32 spindown;
- unsigned char spindown_offset;
- unsigned char select_delay;
- unsigned char rps;
- unsigned char tracks;
- u32 timeout;
- unsigned char interleave_sect;
- struct floppy_max_errors max_errors;
- char flags;
- char read_track;
- short autodetect[8];
- int checkfreq;
- int native_format;
-};
-
-struct floppy_drive_struct32 {
- signed char flags;
- u32 spinup_date;
- u32 select_date;
- u32 first_read_date;
- short probed_format;
- short track;
- short maxblock;
- short maxtrack;
- int generation;
- int keep_data;
- int fd_ref;
- int fd_device;
- int last_checked;
- compat_caddr_t dmabuf;
- int bufblocks;
-};
-
-struct floppy_fdc_state32 {
- int spec1;
- int spec2;
- int dtr;
- unsigned char version;
- unsigned char dor;
- u32 address;
- unsigned int rawcmd:2;
- unsigned int reset:1;
- unsigned int need_configure:1;
- unsigned int perp_mode:2;
- unsigned int has_fifo:1;
- unsigned int driver_version;
- unsigned char track[4];
-};
-
-struct floppy_write_errors32 {
- unsigned int write_errors;
- u32 first_error_sector;
- int first_error_generation;
- u32 last_error_sector;
- int last_error_generation;
- unsigned int badness;
-};
-
-#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
-#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
-#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
-#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
-#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
-#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
-#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
-#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
-#define FDWERRORGET32 _IOR(2, 0x17, struct floppy_write_errors32)
-
-static struct {
- unsigned int cmd32;
- unsigned int cmd;
-} fd_ioctl_trans_table[] = {
- { FDSETPRM32, FDSETPRM },
- { FDDEFPRM32, FDDEFPRM },
- { FDGETPRM32, FDGETPRM },
- { FDSETDRVPRM32, FDSETDRVPRM },
- { FDGETDRVPRM32, FDGETDRVPRM },
- { FDGETDRVSTAT32, FDGETDRVSTAT },
- { FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
- { FDGETFDCSTAT32, FDGETFDCSTAT },
- { FDWERRORGET32, FDWERRORGET }
-};
-
-#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
-
-static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- void *karg = NULL;
- unsigned int kcmd = 0;
- int i, err;
-
- for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
- if (cmd == fd_ioctl_trans_table[i].cmd32) {
- kcmd = fd_ioctl_trans_table[i].cmd;
- break;
- }
- if (!kcmd)
- return -EINVAL;
-
- switch (cmd) {
- case FDSETPRM32:
- case FDDEFPRM32:
- case FDGETPRM32:
- {
- struct floppy_struct *f;
-
- f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- if (cmd == FDGETPRM32)
- break;
- err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size);
- err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
- err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head);
- err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track);
- err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
- err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
- err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
- err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
- err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
- err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- break;
- }
- case FDSETDRVPRM32:
- case FDGETDRVPRM32:
- {
- struct floppy_drive_params *f;
-
- f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- if (cmd == FDGETDRVPRM32)
- break;
- err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
- err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
- err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
- err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
- err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
- err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
- err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
- err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
- err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
- err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
- err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
- err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
- err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
- err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors));
- err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
- err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
- err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
- err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
- err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- break;
- }
- case FDGETDRVSTAT32:
- case FDPOLLDRVSTAT32:
- karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- break;
- case FDGETFDCSTAT32:
- karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- break;
- case FDWERRORGET32:
- karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
- if (!karg)
- return -ENOMEM;
- break;
- default:
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, kcmd, (unsigned long)karg);
- set_fs (old_fs);
- if (err)
- goto out;
- switch (cmd) {
- case FDGETPRM32:
- {
- struct floppy_struct *f = karg;
-
- err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
- err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
- err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
- err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
- err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
- err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
- err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
- err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
- err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
- err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
- break;
- }
- case FDGETDRVPRM32:
- {
- struct floppy_drive_params *f = karg;
-
- err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
- err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
- err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
- err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
- err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
- err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
- err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
- err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
- err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
- err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
- err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
- err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
- err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
- err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors));
- err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
- err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
- err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect));
- err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
- err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
- break;
- }
- case FDGETDRVSTAT32:
- case FDPOLLDRVSTAT32:
- {
- struct floppy_drive_struct *f = karg;
-
- err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags);
- err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date);
- err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date);
- err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date);
- err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format);
- err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track);
- err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock);
- err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack);
- err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation);
- err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data);
- err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref);
- err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device);
- err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked);
- err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf);
- err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks);
- break;
- }
- case FDGETFDCSTAT32:
- {
- struct floppy_fdc_state *f = karg;
-
- err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1);
- err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2);
- err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr);
- err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version);
- err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor);
- err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address);
- err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address
- + sizeof(((struct floppy_fdc_state32 *)arg)->address),
- (char *)&f->address + sizeof(f->address), sizeof(int));
- err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version);
- err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track));
- break;
- }
- case FDWERRORGET32:
- {
- struct floppy_write_errors *f = karg;
-
- err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors);
- err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector);
- err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation);
- err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector);
- err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation);
- err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness);
- break;
- }
- default:
- break;
- }
- if (err)
- err = -EFAULT;
-
-out: if (karg) kfree(karg);
- return err;
-}
-
-typedef struct sg_io_hdr32 {
- s32 interface_id; /* [i] 'S' for SCSI generic (required) */
- s32 dxfer_direction; /* [i] data transfer direction */
- u8 cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
- u8 mx_sb_len; /* [i] max length to write to sbp */
- u16 iovec_count; /* [i] 0 implies no scatter gather */
- u32 dxfer_len; /* [i] byte count of data transfer */
- u32 dxferp; /* [i], [*io] points to data transfer memory
- or scatter gather list */
- u32 cmdp; /* [i], [*i] points to command to perform */
- u32 sbp; /* [i], [*o] points to sense_buffer memory */
- u32 timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
- u32 flags; /* [i] 0 -> default, see SG_FLAG... */
- s32 pack_id; /* [i->o] unused internally (normally) */
- u32 usr_ptr; /* [i->o] unused internally */
- u8 status; /* [o] scsi status */
- u8 masked_status; /* [o] shifted, masked scsi status */
- u8 msg_status; /* [o] messaging level data (optional) */
- u8 sb_len_wr; /* [o] byte count actually written to sbp */
- u16 host_status; /* [o] errors from host adapter */
- u16 driver_status; /* [o] errors from software driver */
- s32 resid; /* [o] dxfer_len - actual_transferred */
- u32 duration; /* [o] time taken by cmd (unit: millisec) */
- u32 info; /* [o] auxiliary information */
-} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */
-
-typedef struct sg_iovec32 {
- u32 iov_base;
- u32 iov_len;
-} sg_iovec32_t;
-
-static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
-{
- sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
- sg_iovec_t *kiov;
- int i;
-
- sgp->dxferp = kmalloc(sgp->iovec_count *
- sizeof(sg_iovec_t), GFP_KERNEL);
- if (!sgp->dxferp)
- return -ENOMEM;
- memset(sgp->dxferp, 0,
- sgp->iovec_count * sizeof(sg_iovec_t));
-
- kiov = (sg_iovec_t *) sgp->dxferp;
- for (i = 0; i < sgp->iovec_count; i++) {
- u32 iov_base32;
- if (__get_user(iov_base32, &uiov->iov_base) ||
- __get_user(kiov->iov_len, &uiov->iov_len))
- return -EFAULT;
-
- kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
- if (!kiov->iov_base)
- return -ENOMEM;
- if (copy_from_user(kiov->iov_base,
- (void *) A(iov_base32),
- kiov->iov_len))
- return -EFAULT;
-
- uiov++;
- kiov++;
- }
-
- return 0;
-}
-
-static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
-{
- sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
- sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
- int i;
-
- for (i = 0; i < sgp->iovec_count; i++) {
- u32 iov_base32;
-
- if (__get_user(iov_base32, &uiov->iov_base))
- return -EFAULT;
-
- if (copy_to_user((void *) A(iov_base32),
- kiov->iov_base,
- kiov->iov_len))
- return -EFAULT;
-
- uiov++;
- kiov++;
- }
-
- return 0;
-}
-
-static void free_sg_iovec(sg_io_hdr_t *sgp)
-{
- sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
- int i;
-
- for (i = 0; i < sgp->iovec_count; i++) {
- if (kiov->iov_base) {
- kfree(kiov->iov_base);
- kiov->iov_base = NULL;
- }
- kiov++;
- }
- kfree(sgp->dxferp);
- sgp->dxferp = NULL;
-}
-
-static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- sg_io_hdr32_t *sg_io32;
- sg_io_hdr_t sg_io64;
- u32 dxferp32, cmdp32, sbp32;
- mm_segment_t old_fs;
- int err = 0;
-
- sg_io32 = (sg_io_hdr32_t *)arg;
- err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);
- err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);
- err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);
- err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);
- err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);
- err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);
- err |= __get_user(sg_io64.timeout, &sg_io32->timeout);
- err |= __get_user(sg_io64.flags, &sg_io32->flags);
- err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);
-
- sg_io64.dxferp = NULL;
- sg_io64.cmdp = NULL;
- sg_io64.sbp = NULL;
-
- err |= __get_user(cmdp32, &sg_io32->cmdp);
- sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
- if (!sg_io64.cmdp) {
- err = -ENOMEM;
- goto out;
- }
- if (copy_from_user(sg_io64.cmdp,
- (void *) A(cmdp32),
- sg_io64.cmd_len)) {
- err = -EFAULT;
- goto out;
- }
-
- err |= __get_user(sbp32, &sg_io32->sbp);
- sg_io64.sbp = kmalloc(sg_io64.mx_sb_len, GFP_KERNEL);
- if (!sg_io64.sbp) {
- err = -ENOMEM;
- goto out;
- }
- if (copy_from_user(sg_io64.sbp,
- (void *) A(sbp32),
- sg_io64.mx_sb_len)) {
- err = -EFAULT;
- goto out;
- }
-
- err |= __get_user(dxferp32, &sg_io32->dxferp);
- if (sg_io64.iovec_count) {
- int ret;
-
- if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {
- err = ret;
- goto out;
- }
- } else {
- sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
- if (!sg_io64.dxferp) {
- err = -ENOMEM;
- goto out;
- }
- if (copy_from_user(sg_io64.dxferp,
- (void *) A(dxferp32),
- sg_io64.dxfer_len)) {
- err = -EFAULT;
- goto out;
- }
- }
-
- /* Unused internally, do not even bother to copy it over. */
- sg_io64.usr_ptr = NULL;
-
- if (err)
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);
- set_fs (old_fs);
-
- if (err < 0)
- goto out;
-
- err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);
- err |= __put_user(sg_io64.status, &sg_io32->status);
- err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);
- err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);
- err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);
- err |= __put_user(sg_io64.host_status, &sg_io32->host_status);
- err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);
- err |= __put_user(sg_io64.resid, &sg_io32->resid);
- err |= __put_user(sg_io64.duration, &sg_io32->duration);
- err |= __put_user(sg_io64.info, &sg_io32->info);
- err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
- if (sg_io64.dxferp) {
- if (sg_io64.iovec_count)
- err |= copy_back_sg_iovec(&sg_io64, dxferp32);
- else
- err |= copy_to_user((void *)A(dxferp32),
- sg_io64.dxferp,
- sg_io64.dxfer_len);
- }
- if (err)
- err = -EFAULT;
-
-out:
- if (sg_io64.cmdp)
- kfree(sg_io64.cmdp);
- if (sg_io64.sbp)
- kfree(sg_io64.sbp);
- if (sg_io64.dxferp) {
- if (sg_io64.iovec_count) {
- free_sg_iovec(&sg_io64);
- } else {
- kfree(sg_io64.dxferp);
- }
- }
- return err;
-}
-
-struct ppp_option_data32 {
- compat_caddr_t ptr;
- __u32 length;
- int transmit;
-};
-#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32)
-
-struct ppp_idle32 {
- compat_time_t xmit_idle;
- compat_time_t recv_idle;
-};
-#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
-
-static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct ppp_option_data32 data32;
- struct ppp_option_data data;
- struct ppp_idle32 idle32;
- struct ppp_idle idle;
- unsigned int kcmd;
- void *karg;
- int err = 0;
-
- switch (cmd) {
- case PPPIOCGIDLE32:
- kcmd = PPPIOCGIDLE;
- karg = &idle;
- break;
- case PPPIOCSCOMPRESS32:
- if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
- return -EFAULT;
- data.ptr = kmalloc (data32.length, GFP_KERNEL);
- if (!data.ptr)
- return -ENOMEM;
- if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
- kfree(data.ptr);
- return -EFAULT;
- }
- data.length = data32.length;
- data.transmit = data32.transmit;
- kcmd = PPPIOCSCOMPRESS;
- karg = &data;
- break;
- default:
- do {
- static int count = 0;
- if (++count <= 20)
- printk("ppp_ioctl: Unknown cmd fd(%d) "
- "cmd(%08x) arg(%08x)\n",
- (int)fd, (unsigned int)cmd, (unsigned int)arg);
- } while (0);
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, kcmd, (unsigned long)karg);
- set_fs (old_fs);
- switch (cmd) {
- case PPPIOCGIDLE32:
- if (err)
- return err;
- idle32.xmit_idle = idle.xmit_idle;
- idle32.recv_idle = idle.recv_idle;
- if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))
- return -EFAULT;
- break;
- case PPPIOCSCOMPRESS32:
- kfree(data.ptr);
- break;
- default:
- break;
- }
- return err;
-}
-
-
-struct mtget32 {
- __u32 mt_type;
- __u32 mt_resid;
- __u32 mt_dsreg;
- __u32 mt_gstat;
- __u32 mt_erreg;
- compat_daddr_t mt_fileno;
- compat_daddr_t mt_blkno;
-};
-#define MTIOCGET32 _IOR('m', 2, struct mtget32)
-
-struct mtpos32 {
- __u32 mt_blkno;
-};
-#define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
-
-struct mtconfiginfo32 {
- __u32 mt_type;
- __u32 ifc_type;
- __u16 irqnr;
- __u16 dmanr;
- __u16 port;
- __u32 debug;
- __u32 have_dens:1;
- __u32 have_bsf:1;
- __u32 have_fsr:1;
- __u32 have_bsr:1;
- __u32 have_eod:1;
- __u32 have_seek:1;
- __u32 have_tell:1;
- __u32 have_ras1:1;
- __u32 have_ras2:1;
- __u32 have_ras3:1;
- __u32 have_qfa:1;
- __u32 pad1:5;
- char reserved[10];
-};
-#define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32)
-#define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32)
-
-static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct mtconfiginfo info;
- struct mtget get;
- struct mtpos pos;
- unsigned long kcmd;
- void *karg;
- int err = 0;
-
- switch(cmd) {
- case MTIOCPOS32:
- kcmd = MTIOCPOS;
- karg = &pos;
- break;
- case MTIOCGET32:
- kcmd = MTIOCGET;
- karg = &get;
- break;
- case MTIOCGETCONFIG32:
- kcmd = MTIOCGETCONFIG;
- karg = &info;
- break;
- case MTIOCSETCONFIG32:
- kcmd = MTIOCSETCONFIG;
- karg = &info;
- err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
- err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
- err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
- err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
- err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
- err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
- err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
- (char *)&((struct mtconfiginfo32 *)arg)->debug
- + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
- if (err)
- return -EFAULT;
- break;
- default:
- do {
- static int count = 0;
- if (++count <= 20)
- printk("mt_ioctl: Unknown cmd fd(%d) "
- "cmd(%08x) arg(%08x)\n",
- (int)fd, (unsigned int)cmd, (unsigned int)arg);
- } while (0);
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, kcmd, (unsigned long)karg);
- set_fs (old_fs);
- if (err)
- return err;
- switch (cmd) {
- case MTIOCPOS32:
- err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
- break;
- case MTIOCGET32:
- err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
- err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
- err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
- err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
- err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
- err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
- err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
- break;
- case MTIOCGETCONFIG32:
- err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
- err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
- err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
- err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
- err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
- err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
- err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
- + sizeof(((struct mtconfiginfo32 *)arg)->debug),
- (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
- break;
- case MTIOCSETCONFIG32:
- break;
- }
- return err ? -EFAULT: 0;
-}
-
-struct cdrom_read32 {
- int cdread_lba;
- compat_caddr_t cdread_bufaddr;
- int cdread_buflen;
-};
-
-struct cdrom_read_audio32 {
- union cdrom_addr addr;
- u_char addr_format;
- int nframes;
- compat_caddr_t buf;
-};
-
-struct cdrom_generic_command32 {
- unsigned char cmd[CDROM_PACKET_SIZE];
- compat_caddr_t buffer;
- unsigned int buflen;
- int stat;
- compat_caddr_t sense;
- compat_caddr_t reserved[3];
-};
-
-static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct cdrom_read cdread;
- struct cdrom_read_audio cdreadaudio;
- struct cdrom_generic_command cgc;
- compat_caddr_t addr;
- char *data = 0;
- void *karg;
- int err = 0;
-
- switch(cmd) {
- case CDROMREADMODE2:
- case CDROMREADMODE1:
- case CDROMREADRAW:
- case CDROMREADCOOKED:
- karg = &cdread;
- err = __get_user(cdread.cdread_lba, &((struct cdrom_read32 *)arg)->cdread_lba);
- err |= __get_user(addr, &((struct cdrom_read32 *)arg)->cdread_bufaddr);
- err |= __get_user(cdread.cdread_buflen, &((struct cdrom_read32 *)arg)->cdread_buflen);
- if (err)
- return -EFAULT;
- data = kmalloc(cdread.cdread_buflen, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- cdread.cdread_bufaddr = data;
- break;
- case CDROMREADAUDIO:
- karg = &cdreadaudio;
- err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));
- err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);
- err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes);
- err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
- if (err)
- return -EFAULT;
- data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- cdreadaudio.buf = data;
- break;
- case CDROM_SEND_PACKET:
- karg = &cgc;
- err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
- err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
- err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
- if (err)
- return -EFAULT;
- if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
- return -ENOMEM;
- cgc.buffer = data;
- break;
- default:
- do {
- static int count = 0;
- if (++count <= 20)
- printk("cdrom_ioctl: Unknown cmd fd(%d) "
- "cmd(%08x) arg(%08x)\n",
- (int)fd, (unsigned int)cmd, (unsigned int)arg);
- } while (0);
- return -EINVAL;
- }
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)karg);
- set_fs (old_fs);
- if (err)
- goto out;
- switch (cmd) {
- case CDROMREADMODE2:
- case CDROMREADMODE1:
- case CDROMREADRAW:
- case CDROMREADCOOKED:
- err = copy_to_user((char *)A(addr), data, cdread.cdread_buflen);
- break;
- case CDROMREADAUDIO:
- err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
- break;
- case CDROM_SEND_PACKET:
- err = copy_to_user((char *)A(addr), data, cgc.buflen);
- break;
- default:
- break;
- }
-out: if (data)
- kfree(data);
- return err ? -EFAULT : 0;
-}
-
-struct loop_info32 {
- int lo_number; /* ioctl r/o */
- compat_dev_t lo_device; /* ioctl r/o */
- unsigned int lo_inode; /* ioctl r/o */
- compat_dev_t lo_rdevice; /* ioctl r/o */
- int lo_offset;
- int lo_encrypt_type;
- int lo_encrypt_key_size; /* ioctl w/o */
- int lo_flags; /* ioctl r/o */
- char lo_name[LO_NAME_SIZE];
- unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
- unsigned int lo_init[2];
- char reserved[4];
-};
-
-static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct loop_info l;
- int err = -EINVAL;
-
- switch(cmd) {
- case LOOP_SET_STATUS:
- err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
- err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
- err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
- err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
- err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
- 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
- if (err) {
- err = -EFAULT;
- } else {
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&l);
- set_fs (old_fs);
- }
- break;
- case LOOP_GET_STATUS:
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&l);
- set_fs (old_fs);
- if (!err) {
- err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
- err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
- err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
- err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
- err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
- (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
- if (err)
- err = -EFAULT;
- }
- break;
- default: {
- static int count = 0;
- if (++count <= 20)
- printk("%s: Unknown loop ioctl cmd, fd(%d) "
- "cmd(%08x) arg(%08lx)\n",
- __FUNCTION__, fd, cmd, arg);
- }
- }
- return err;
-}
-
-extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
-
-#ifdef CONFIG_VT
-static int vt_check(struct file *file)
-{
- struct tty_struct *tty;
- struct inode *inode = file->f_dentry->d_inode;
-
- if (file->f_op->ioctl != tty_ioctl)
- return -EINVAL;
-
- tty = (struct tty_struct *)file->private_data;
- if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
- return -EINVAL;
-
- if (tty->driver->ioctl != vt_ioctl)
- return -EINVAL;
-
- /*
- * To have permissions to do most of the vt ioctls, we either have
- * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
- */
- if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
- return 1;
- return 0;
-}
-
-struct consolefontdesc32 {
- unsigned short charcount; /* characters in font (256 or 512) */
- unsigned short charheight; /* scan lines per character (1-32) */
- u32 chardata; /* font data in expanded form */
-};
-
-static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
-{
- struct consolefontdesc cfdarg;
- struct console_font_op op;
- int i, perm;
-
- perm = vt_check(file);
- if (perm < 0) return perm;
-
- if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
- return -EFAULT;
-
- cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
-
- switch (cmd) {
- case PIO_FONTX:
- if (!perm)
- return -EPERM;
- op.op = KD_FONT_OP_SET;
- op.flags = 0;
- op.width = 8;
- op.height = cfdarg.charheight;
- op.charcount = cfdarg.charcount;
- op.data = cfdarg.chardata;
- return con_font_op(fg_console, &op);
- case GIO_FONTX:
- if (!cfdarg.chardata)
- return 0;
- op.op = KD_FONT_OP_GET;
- op.flags = 0;
- op.width = 8;
- op.height = cfdarg.charheight;
- op.charcount = cfdarg.charcount;
- op.data = cfdarg.chardata;
- i = con_font_op(fg_console, &op);
- if (i)
- return i;
- cfdarg.charheight = op.height;
- cfdarg.charcount = op.charcount;
- ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata;
- if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
- return -EFAULT;
- return 0;
- }
- return -EINVAL;
-}
-
-struct console_font_op32 {
- unsigned int op; /* operation code KD_FONT_OP_* */
- unsigned int flags; /* KD_FONT_FLAG_* */
- unsigned int width, height; /* font size */
- unsigned int charcount;
- u32 data; /* font data with height fixed to 32 */
-};
-
-static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
-{
- struct console_font_op op;
- int perm = vt_check(file), i;
- struct vt_struct *vt;
-
- if (perm < 0) return perm;
-
- if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
- return -EFAULT;
- if (!perm && op.op != KD_FONT_OP_GET)
- return -EPERM;
- op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
- op.flags |= KD_FONT_FLAG_OLD;
- vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
- i = con_font_op(vt->vc_num, &op);
- if (i) return i;
- ((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
- if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
- return -EFAULT;
- return 0;
-}
-
-struct fb_fix_screeninfo32 {
- char id[16]; /* identification string eg "TT Builtin" */
- unsigned int smem_start; /* Start of frame buffer mem */
- /* (physical address) */
- __u32 smem_len; /* Length of frame buffer mem */
- __u32 type; /* see FB_TYPE_* */
- __u32 type_aux; /* Interleave for interleaved Planes */
- __u32 visual; /* see FB_VISUAL_* */
- __u16 xpanstep; /* zero if no hardware panning */
- __u16 ypanstep; /* zero if no hardware panning */
- __u16 ywrapstep; /* zero if no hardware ywrap */
- __u32 line_length; /* length of a line in bytes */
- unsigned int mmio_start; /* Start of Memory Mapped I/O */
- /* (physical address) */
- __u32 mmio_len; /* Length of Memory Mapped I/O */
- __u32 accel; /* Type of acceleration available */
- __u16 reserved[3]; /* Reserved for future compatibility */
-};
-
-static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct fb_fix_screeninfo fix;
- int err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (long)&fix);
- set_fs(old_fs);
-
- if (err == 0) {
- unsigned int smem_start = fix.smem_start; /* lose top 32 bits */
- unsigned int mmio_start = fix.mmio_start; /* lose top 32 bits */
- int i;
-
- err = put_user(fix.id[0], &((struct fb_fix_screeninfo32 *)arg)->id[0]);
- for (i=1; i<16; i++) {
- err |= __put_user(fix.id[i], &((struct fb_fix_screeninfo32 *)arg)->id[i]);
- }
- err |= __put_user(smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start);
- err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len);
- err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type);
- err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux);
- err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual);
- err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep);
- err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep);
- err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep);
- err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length);
- err |= __put_user(mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start);
- err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len);
- err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel);
- err |= __put_user(fix.reserved[0], &((struct fb_fix_screeninfo32 *)arg)->reserved[0]);
- err |= __put_user(fix.reserved[1], &((struct fb_fix_screeninfo32 *)arg)->reserved[1]);
- err |= __put_user(fix.reserved[2], &((struct fb_fix_screeninfo32 *)arg)->reserved[2]);
- if (err)
- err = -EFAULT;
- }
- return err;
-}
-
-struct fb_cmap32 {
- __u32 start; /* First entry */
- __u32 len; /* Number of entries */
- __u32 redptr; /* Red values */
- __u32 greenptr;
- __u32 blueptr;
- __u32 transpptr; /* transparency, can be NULL */
-};
-
-static int do_fbiogetcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct fb_cmap cmap;
- int err;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (long)&cmap);
- set_fs(old_fs);
-
- if (err == 0) {
- __u32 redptr = (__u32)(__u64)cmap.red;
- __u32 greenptr = (__u32)(__u64)cmap.green;
- __u32 blueptr = (__u32)(__u64)cmap.blue;
- __u32 transpptr = (__u32)(__u64)cmap.transp;
-
- err = put_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
- err |= __put_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
- err |= __put_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
- err |= __put_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
- err |= __put_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
- err |= __put_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
- if (err)
- err = -EFAULT;
- }
- return err;
-}
-
-static int do_fbioputcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct fb_cmap cmap;
- __u32 redptr, greenptr, blueptr, transpptr;
- int err;
-
- err = get_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
- err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
- err |= __get_user(redptr, &((struct fb_cmap32 *)arg)->redptr);
- err |= __get_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr);
- err |= __get_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr);
- err |= __get_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr);
-
- if (err) {
- err = -EFAULT;
- } else {
- cmap.red = (__u16 *)(__u64)redptr;
- cmap.green = (__u16 *)(__u64)greenptr;
- cmap.blue = (__u16 *)(__u64)blueptr;
- cmap.transp = (__u16 *)(__u64)transpptr;
- set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&cmap);
- set_fs (old_fs);
- }
- return err;
-}
-
-struct unimapdesc32 {
- unsigned short entry_ct;
- u32 entries;
-};
-
-static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
-{
- struct unimapdesc32 tmp;
- int perm = vt_check(file);
-
- if (perm < 0) return perm;
- if (copy_from_user(&tmp, user_ud, sizeof tmp))
- return -EFAULT;
- switch (cmd) {
- case PIO_UNIMAP:
- if (!perm) return -EPERM;
- return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
- case GIO_UNIMAP:
- return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
- }
- return 0;
-}
-#endif /* CONFIG_VT */
-static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- __kernel_uid_t kuid;
- int err;
-
- cmd = SMB_IOC_GETMOUNTUID;
-
- set_fs(KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
- set_fs(old_fs);
-
- if (err >= 0)
- err = put_user(kuid, (compat_uid_t *)arg);
-
- return err;
-}
-
struct ncp_ioctl_request_32 {
unsigned int function;
unsigned int size;
@@ -2399,812 +356,6 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon
return err;
}
-struct atmif_sioc32 {
- int number;
- int length;
- compat_caddr_t arg;
-};
-
-struct atm_iobuf32 {
- int length;
- compat_caddr_t buffer;
-};
-
-#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
-#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
-#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
-#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
-#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
-#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
-#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
-#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
-#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
-#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
-#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
-#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
-#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
-#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
-#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
-#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
-#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
-
-static struct {
- unsigned int cmd32;
- unsigned int cmd;
-} atm_ioctl_map[] = {
- { ATM_GETLINKRATE32, ATM_GETLINKRATE },
- { ATM_GETNAMES32, ATM_GETNAMES },
- { ATM_GETTYPE32, ATM_GETTYPE },
- { ATM_GETESI32, ATM_GETESI },
- { ATM_GETADDR32, ATM_GETADDR },
- { ATM_RSTADDR32, ATM_RSTADDR },
- { ATM_ADDADDR32, ATM_ADDADDR },
- { ATM_DELADDR32, ATM_DELADDR },
- { ATM_GETCIRANGE32, ATM_GETCIRANGE },
- { ATM_SETCIRANGE32, ATM_SETCIRANGE },
- { ATM_SETESI32, ATM_SETESI },
- { ATM_SETESIF32, ATM_SETESIF },
- { ATM_GETSTAT32, ATM_GETSTAT },
- { ATM_GETSTATZ32, ATM_GETSTATZ },
- { ATM_GETLOOP32, ATM_GETLOOP },
- { ATM_SETLOOP32, ATM_SETLOOP },
- { ATM_QUERYLOOP32, ATM_QUERYLOOP }
-};
-
-#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
-
-
-static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct atm_iobuf32 iobuf32;
- struct atm_iobuf iobuf = { 0, NULL };
- mm_segment_t old_fs;
- int err;
-
- err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg,
- sizeof(struct atm_iobuf32));
- if (err)
- return -EFAULT;
-
- iobuf.length = iobuf32.length;
-
- if (iobuf32.buffer == (compat_caddr_t) NULL || iobuf32.length == 0) {
- iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
- } else {
- iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
- if (iobuf.buffer == NULL) {
- err = -ENOMEM;
- goto out;
- }
-
- err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
-
- old_fs = get_fs(); set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);
- set_fs (old_fs);
- if (err)
- goto out;
-
- if (iobuf.buffer && iobuf.length > 0) {
- err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
- err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
-
- out:
- if (iobuf32.buffer && iobuf32.length > 0)
- kfree(iobuf.buffer);
-
- return err;
-}
-
-
-static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- struct atmif_sioc32 sioc32;
- struct atmif_sioc sioc = { 0, 0, NULL };
- mm_segment_t old_fs;
- int err;
-
- err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg,
- sizeof(struct atmif_sioc32));
- if (err)
- return -EFAULT;
-
- sioc.number = sioc32.number;
- sioc.length = sioc32.length;
-
- if (sioc32.arg == (compat_caddr_t) NULL || sioc32.length == 0) {
- sioc.arg = (void*)(unsigned long)sioc32.arg;
- } else {
- sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
- if (sioc.arg == NULL) {
- err = -ENOMEM;
- goto out;
- }
-
- err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
-
- old_fs = get_fs(); set_fs (KERNEL_DS);
- err = sys_ioctl (fd, cmd, (unsigned long)&sioc);
- set_fs (old_fs);
- if (err) {
- goto out;
- }
-
- if (sioc.arg && sioc.length > 0) {
- err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length);
- if (err) {
- err = -EFAULT;
- goto out;
- }
- }
- err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
-
- out:
- if (sioc32.arg && sioc32.length > 0)
- kfree(sioc.arg);
-
- return err;
-}
-
-
-static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
-{
- int i;
- unsigned int cmd = 0;
-
- switch (cmd32) {
- case SONET_GETSTAT:
- case SONET_GETSTATZ:
- case SONET_GETDIAG:
- case SONET_SETDIAG:
- case SONET_CLRDIAG:
- case SONET_SETFRAMING:
- case SONET_GETFRAMING:
- case SONET_GETFRSENSE:
- return do_atmif_sioc(fd, cmd32, arg);
- }
-
- for (i = 0; i < NR_ATM_IOCTL; i++) {
- if (cmd32 == atm_ioctl_map[i].cmd32) {
- cmd = atm_ioctl_map[i].cmd;
- break;
- }
- }
- if (i == NR_ATM_IOCTL) {
- return -EINVAL;
- }
-
- switch (cmd) {
- case ATM_GETNAMES:
- return do_atm_iobuf(fd, cmd, arg);
-
- case ATM_GETLINKRATE:
- case ATM_GETTYPE:
- case ATM_GETESI:
- case ATM_GETADDR:
- case ATM_RSTADDR:
- case ATM_ADDADDR:
- case ATM_DELADDR:
- case ATM_GETCIRANGE:
- case ATM_SETCIRANGE:
- case ATM_SETESI:
- case ATM_SETESIF:
- case ATM_GETSTAT:
- case ATM_GETSTATZ:
- case ATM_GETLOOP:
- case ATM_SETLOOP:
- case ATM_QUERYLOOP:
- return do_atmif_sioc(fd, cmd, arg);
- }
-
- return -EINVAL;
-}
-
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
- int version_major; /* Major version */
- int version_minor; /* Minor version */
- int version_patchlevel;/* Patch level */
- int name_len; /* Length of name buffer */
- u32 name; /* Name of driver */
- int date_len; /* Length of date buffer */
- u32 date; /* User-space buffer to hold date */
- int desc_len; /* Length of desc buffer */
- u32 desc; /* User-space buffer to hold desc */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_version_t *uversion = (drm32_version_t *)arg;
- char *name_ptr, *date_ptr, *desc_ptr;
- u32 tmp1, tmp2, tmp3;
- drm_version_t kversion;
- mm_segment_t old_fs;
- int ret;
-
- memset(&kversion, 0, sizeof(kversion));
- if (get_user(kversion.name_len, &uversion->name_len) ||
- get_user(kversion.date_len, &uversion->date_len) ||
- get_user(kversion.desc_len, &uversion->desc_len) ||
- get_user(tmp1, &uversion->name) ||
- get_user(tmp2, &uversion->date) ||
- get_user(tmp3, &uversion->desc))
- return -EFAULT;
-
- name_ptr = (char *) A(tmp1);
- date_ptr = (char *) A(tmp2);
- desc_ptr = (char *) A(tmp3);
-
- ret = -ENOMEM;
- if (kversion.name_len && name_ptr) {
- kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
- if (!kversion.name)
- goto out;
- }
- if (kversion.date_len && date_ptr) {
- kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
- if (!kversion.date)
- goto out;
- }
- if (kversion.desc_len && desc_ptr) {
- kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
- if (!kversion.desc)
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
- set_fs(old_fs);
-
- if (!ret) {
- if ((kversion.name &&
- copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
- (kversion.date &&
- copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
- (kversion.desc &&
- copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
- ret = -EFAULT;
- if (put_user(kversion.version_major, &uversion->version_major) ||
- put_user(kversion.version_minor, &uversion->version_minor) ||
- put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
- put_user(kversion.name_len, &uversion->name_len) ||
- put_user(kversion.date_len, &uversion->date_len) ||
- put_user(kversion.desc_len, &uversion->desc_len))
- ret = -EFAULT;
- }
-
-out:
- if (kversion.name)
- kfree(kversion.name);
- if (kversion.date)
- kfree(kversion.date);
- if (kversion.desc)
- kfree(kversion.desc);
- return ret;
-}
-
-typedef struct drm32_unique {
- int unique_len; /* Length of unique */
- u32 unique; /* Unique name for driver instantiation */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_unique_t *uarg = (drm32_unique_t *)arg;
- drm_unique_t karg;
- mm_segment_t old_fs;
- char *uptr;
- u32 tmp;
- int ret;
-
- if (get_user(karg.unique_len, &uarg->unique_len))
- return -EFAULT;
- karg.unique = NULL;
-
- if (get_user(tmp, &uarg->unique))
- return -EFAULT;
-
- uptr = (char *) A(tmp);
-
- if (uptr) {
- karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
- if (!karg.unique)
- return -ENOMEM;
- if (cmd == DRM32_IOCTL_SET_UNIQUE &&
- copy_from_user(karg.unique, uptr, karg.unique_len)) {
- kfree(karg.unique);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- if (cmd == DRM32_IOCTL_GET_UNIQUE)
- ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
- else
- ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (cmd == DRM32_IOCTL_GET_UNIQUE &&
- uptr != NULL &&
- copy_to_user(uptr, karg.unique, karg.unique_len))
- ret = -EFAULT;
- if (put_user(karg.unique_len, &uarg->unique_len))
- ret = -EFAULT;
- }
-
- if (karg.unique != NULL)
- kfree(karg.unique);
-
- return ret;
-}
-
-typedef struct drm32_map {
- u32 offset; /* Requested physical address (0 for SAREA)*/
- u32 size; /* Requested physical size (bytes) */
- drm_map_type_t type; /* Type of memory to map */
- drm_map_flags_t flags; /* Flags */
- u32 handle; /* User-space: "Handle" to pass to mmap */
- /* Kernel-space: kernel-virtual address */
- int mtrr; /* MTRR slot used */
- /* Private data */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_map_t *uarg = (drm32_map_t *) arg;
- drm_map_t karg;
- mm_segment_t old_fs;
- u32 tmp;
- int ret;
-
- ret = get_user(karg.offset, &uarg->offset);
- ret |= get_user(karg.size, &uarg->size);
- ret |= get_user(karg.type, &uarg->type);
- ret |= get_user(karg.flags, &uarg->flags);
- ret |= get_user(tmp, &uarg->handle);
- ret |= get_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- return -EFAULT;
-
- karg.handle = (void *) A(tmp);
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- ret = put_user(karg.offset, &uarg->offset);
- ret |= put_user(karg.size, &uarg->size);
- ret |= put_user(karg.type, &uarg->type);
- ret |= put_user(karg.flags, &uarg->flags);
- tmp = (u32) (long)karg.handle;
- ret |= put_user(tmp, &uarg->handle);
- ret |= put_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- ret = -EFAULT;
- }
-
- return ret;
-}
-
-typedef struct drm32_buf_info {
- int count; /* Entries in list */
- u32 list; /* (drm_buf_desc_t *) */
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
- drm_buf_desc_t *ulist;
- drm_buf_info_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (drm_buf_desc_t *) A(tmp);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
- if (!karg.list)
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (karg.count <= orig_count &&
- (copy_to_user(ulist, karg.list,
- karg.count * sizeof(drm_buf_desc_t))))
- ret = -EFAULT;
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- kfree(karg.list);
-
- return ret;
-}
-
-typedef struct drm32_buf_free {
- int count;
- u32 list; /* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
- drm_buf_free_t karg;
- mm_segment_t old_fs;
- int *ulist;
- int ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (int *) A(tmp);
-
- karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
- goto out;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
-out:
- kfree(karg.list);
-
- return ret;
-}
-
-typedef struct drm32_buf_pub {
- int idx; /* Index into master buflist */
- int total; /* Buffer size */
- int used; /* Amount of buffer in use (for DMA) */
- u32 address; /* Address of buffer (void *) */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
- int count; /* Length of buflist */
- u32 virtual; /* Mmaped area in user-virtual (void *) */
- u32 list; /* Buffer information (drm_buf_pub_t *) */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
- drm32_buf_pub_t *ulist;
- drm_buf_map_t karg;
- mm_segment_t old_fs;
- int orig_count, ret, i;
- u32 tmp1, tmp2;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp1, &uarg->virtual) ||
- get_user(tmp2, &uarg->list))
- return -EFAULT;
-
- karg.virtual = (void *) A(tmp1);
- ulist = (drm32_buf_pub_t *) A(tmp2);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- for (i = 0; i < karg.count; i++) {
- if (get_user(karg.list[i].idx, &ulist[i].idx) ||
- get_user(karg.list[i].total, &ulist[i].total) ||
- get_user(karg.list[i].used, &ulist[i].used) ||
- get_user(tmp1, &ulist[i].address))
- goto out;
-
- karg.list[i].address = (void *) A(tmp1);
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- for (i = 0; i < orig_count; i++) {
- tmp1 = (u32) (long) karg.list[i].address;
- if (put_user(karg.list[i].idx, &ulist[i].idx) ||
- put_user(karg.list[i].total, &ulist[i].total) ||
- put_user(karg.list[i].used, &ulist[i].used) ||
- put_user(tmp1, &ulist[i].address)) {
- ret = -EFAULT;
- goto out;
- }
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
-out:
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_dma {
- /* Indices here refer to the offset into
- buflist in drm_buf_get_t. */
- int context; /* Context handle */
- int send_count; /* Number of buffers to send */
- u32 send_indices; /* List of handles to buffers (int *) */
- u32 send_sizes; /* Lengths of data to send (int *) */
- drm_dma_flags_t flags; /* Flags */
- int request_count; /* Number of buffers requested */
- int request_size; /* Desired size for buffers */
- u32 request_indices; /* Buffer information (int *) */
- u32 request_sizes; /* (int *) */
- int granted_count; /* Number of buffers granted */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN The DRM layer blindly dereferences the send/request
- * indice/size arrays even though they are userland
- * pointers. -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_dma_t *uarg = (drm32_dma_t *) arg;
- int *u_si, *u_ss, *u_ri, *u_rs;
- drm_dma_t karg;
- mm_segment_t old_fs;
- int ret;
- u32 tmp1, tmp2, tmp3, tmp4;
-
- karg.send_indices = karg.send_sizes = NULL;
- karg.request_indices = karg.request_sizes = NULL;
-
- if (get_user(karg.context, &uarg->context) ||
- get_user(karg.send_count, &uarg->send_count) ||
- get_user(tmp1, &uarg->send_indices) ||
- get_user(tmp2, &uarg->send_sizes) ||
- get_user(karg.flags, &uarg->flags) ||
- get_user(karg.request_count, &uarg->request_count) ||
- get_user(karg.request_size, &uarg->request_size) ||
- get_user(tmp3, &uarg->request_indices) ||
- get_user(tmp4, &uarg->request_sizes) ||
- get_user(karg.granted_count, &uarg->granted_count))
- return -EFAULT;
-
- u_si = (int *) A(tmp1);
- u_ss = (int *) A(tmp2);
- u_ri = (int *) A(tmp3);
- u_rs = (int *) A(tmp4);
-
- if (karg.send_count) {
- karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
- karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.send_indices || !karg.send_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.send_indices, u_si,
- (karg.send_count * sizeof(int))) ||
- copy_from_user(karg.send_sizes, u_ss,
- (karg.send_count * sizeof(int))))
- goto out;
- }
-
- if (karg.request_count) {
- karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
- karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.request_indices || !karg.request_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.request_indices, u_ri,
- (karg.request_count * sizeof(int))) ||
- copy_from_user(karg.request_sizes, u_rs,
- (karg.request_count * sizeof(int))))
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (put_user(karg.context, &uarg->context) ||
- put_user(karg.send_count, &uarg->send_count) ||
- put_user(karg.flags, &uarg->flags) ||
- put_user(karg.request_count, &uarg->request_count) ||
- put_user(karg.request_size, &uarg->request_size) ||
- put_user(karg.granted_count, &uarg->granted_count))
- ret = -EFAULT;
-
- if (karg.send_count) {
- if (copy_to_user(u_si, karg.send_indices,
- (karg.send_count * sizeof(int))) ||
- copy_to_user(u_ss, karg.send_sizes,
- (karg.send_count * sizeof(int))))
- ret = -EFAULT;
- }
- if (karg.request_count) {
- if (copy_to_user(u_ri, karg.request_indices,
- (karg.request_count * sizeof(int))) ||
- copy_to_user(u_rs, karg.request_sizes,
- (karg.request_count * sizeof(int))))
- ret = -EFAULT;
- }
- }
-
-out:
- if (karg.send_indices)
- kfree(karg.send_indices);
- if (karg.send_sizes)
- kfree(karg.send_sizes);
- if (karg.request_indices)
- kfree(karg.request_indices);
- if (karg.request_sizes)
- kfree(karg.request_sizes);
-
- return ret;
-}
-
-typedef struct drm32_ctx_res {
- int count;
- u32 contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
- drm_ctx_t *ulist;
- drm_ctx_res_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- karg.contexts = NULL;
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->contexts))
- return -EFAULT;
-
- ulist = (drm_ctx_t *) A(tmp);
-
- orig_count = karg.count;
- if (karg.count && ulist) {
- karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
- if (!karg.contexts)
- return -ENOMEM;
- if (copy_from_user(karg.contexts, ulist,
- (karg.count * sizeof(drm_ctx_t)))) {
- kfree(karg.contexts);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (orig_count) {
- if (copy_to_user(ulist, karg.contexts,
- (orig_count * sizeof(drm_ctx_t))))
- ret = -EFAULT;
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- if (karg.contexts)
- kfree(karg.contexts);
-
- return ret;
-}
-
-#endif
-
-static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return -EINVAL;
-}
-
-static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- /* The mkswap binary hard codes it to Intel value :-((( */
- return w_long(fd, BLKGETSIZE, arg);
-}
-
-struct blkpg_ioctl_arg32 {
- int op;
- int flags;
- int datalen;
- u32 data;
-};
-
-static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
-{
- struct blkpg_ioctl_arg a;
- struct blkpg_partition p;
- int err;
- mm_segment_t old_fs = get_fs();
-
- err = get_user(a.op, &arg->op);
- err |= __get_user(a.flags, &arg->flags);
- err |= __get_user(a.datalen, &arg->datalen);
- err |= __get_user((long)a.data, &arg->data);
- if (err) return err;
- switch (a.op) {
- case BLKPG_ADD_PARTITION:
- case BLKPG_DEL_PARTITION:
- if (a.datalen < sizeof(struct blkpg_partition))
- return -EINVAL;
- if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
- return -EFAULT;
- a.data = &p;
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&a);
- set_fs (old_fs);
- default:
- return -EINVAL;
- }
- return err;
-}
-
-static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
-}
-
struct usbdevfs_ctrltransfer32 {
__u8 bRequestType;
__u8 bRequest;
@@ -3596,92 +747,6 @@ static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned lo
return err;
}
-struct mtd_oob_buf32 {
- u32 start;
- u32 length;
- u32 ptr; /* unsigned char* */
-};
-
-#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
-#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
-
-static inline int
-mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- mm_segment_t old_fs = get_fs();
- struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg;
- struct mtd_oob_buf karg;
- u32 tmp;
- char *ptr;
- int ret;
-
- if (get_user(karg.start, &uarg->start) ||
- get_user(karg.length, &uarg->length) ||
- get_user(tmp, &uarg->ptr))
- return -EFAULT;
-
- ptr = (char *)A(tmp);
- if (0 >= karg.length)
- return -EINVAL;
-
- karg.ptr = kmalloc(karg.length, GFP_KERNEL);
- if (NULL == karg.ptr)
- return -ENOMEM;
-
- if (copy_from_user(karg.ptr, ptr, karg.length)) {
- kfree(karg.ptr);
- return -EFAULT;
- }
-
- set_fs(KERNEL_DS);
- if (MEMREADOOB32 == cmd)
- ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
- else if (MEMWRITEOOB32 == cmd)
- ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
- else
- ret = -EINVAL;
- set_fs(old_fs);
-
- if (0 == ret && cmd == MEMREADOOB32) {
- ret = copy_to_user(ptr, karg.ptr, karg.length);
- ret |= put_user(karg.start, &uarg->start);
- ret |= put_user(karg.length, &uarg->length);
- }
-
- kfree(karg.ptr);
- return ((0 == ret) ? 0 : -EFAULT);
-}
-
-/* Fix sizeof(sizeof()) breakage */
-#define BLKBSZGET_32 _IOR(0x12,112,int)
-#define BLKBSZSET_32 _IOW(0x12,113,int)
-#define BLKGETSIZE64_32 _IOR(0x12,114,int)
-
-static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return sys_ioctl(fd, BLKBSZGET, arg);
-}
-
-static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return sys_ioctl(fd, BLKBSZSET, arg);
-}
-
-static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
- unsigned long arg)
-{
- return sys_ioctl(fd, BLKGETSIZE64, arg);
-}
-
-/* Bluetooth ioctls */
-#define HCIUARTSETPROTO _IOW('U', 200, int)
-#define HCIUARTGETPROTO _IOR('U', 201, int)
-
-#define BNEPCONNADD _IOW('B', 200, int)
-#define BNEPCONNDEL _IOW('B', 201, int)
-#define BNEPGETCONNLIST _IOR('B', 210, int)
-#define BNEPGETCONNINFO _IOR('B', 211, int)
-
#define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, 0 },
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
@@ -3690,11 +755,10 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
#define IOCTL_TABLE_END \
}; struct ioctl_trans ioctl_end[0];
-#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
-#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
-
IOCTL_TABLE_START
#include <linux/compat_ioctl.h>
+#define DECLARES
+#include "compat_ioctl.c"
COMPATIBLE_IOCTL(TCSBRKP)
COMPATIBLE_IOCTL(TIOCSTART)
COMPATIBLE_IOCTL(TIOCSTOP)
@@ -3709,116 +773,8 @@ COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
/* And these ioctls need translation */
-HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
-HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
-#ifdef CONFIG_NET
-HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
-#endif
-HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
-HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc)
-HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc)
-HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
-HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl)
-HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl)
-HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl)
-HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
-HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
-/* Note SIOCRTMSG is no longer, so this is safe and
- * the user would have seen just an -EINVAL anyways. */
-HANDLE_IOCTL(SIOCRTMSG, ret_einval)
-HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
-HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
HANDLE_IOCTL(HDIO_GETGEO_BIG_RAW, hdio_getgeo_big)
-HANDLE_IOCTL(BLKGETSIZE, w_long)
-HANDLE_IOCTL(BLKRAGET, w_long)
-HANDLE_IOCTL(BLKFRAGET, w_long)
-HANDLE_IOCTL(0x1260, broken_blkgetsize)
-HANDLE_IOCTL(BLKSECTGET, w_long)
-HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans)
-HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans)
-HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
-HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
-HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
-HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
-HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
-HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
-HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
-HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
-HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans)
-HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans)
-HANDLE_IOCTL(CDROMREADMODE2, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADMODE1, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADRAW, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADCOOKED, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans)
-HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
-HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
-HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
-HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
-#ifdef CONFIG_VT
-HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
-HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
-HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
-HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl)
-HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
-HANDLE_IOCTL(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl)
-HANDLE_IOCTL(FBIOGETCMAP, do_fbiogetcmap_ioctl)
-HANDLE_IOCTL(FBIOPUTCMAP, do_fbioputcmap_ioctl)
-#endif
-HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl)
-HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl)
-HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSWIN32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl)
-/* One SMB ioctl needs translations. */
-HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
+
/* NCPFS */
HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2)
@@ -3827,51 +783,12 @@ HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname)
HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname)
HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
-HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl)
-HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
-HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
-#endif /* DRM */
+
+/* USB devfs */
HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
-/* take care of sizeof(sizeof()) breakage */
-/* block stuff */
-HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
-HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
-HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
IOCTL_TABLE_END
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
index d24d2dc50a7b..7f5b927882fe 100644
--- a/arch/ppc64/kernel/irq.c
+++ b/arch/ppc64/kernel/irq.c
@@ -596,7 +596,6 @@ void __init init_IRQ(void)
once++;
ppc_md.init_IRQ();
- if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ();
}
static struct proc_dir_entry * root_irq_dir;
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index 7a0cc5458090..299cbfc6b227 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -27,6 +27,7 @@
#include <asm/cache.h>
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
+#include <asm/cputable.h>
.text
@@ -445,6 +446,95 @@ _GLOBAL(cvt_df)
blr
/*
+ * identify_cpu,
+ * In: r3 = base of the cpu_specs array
+ * r4 = address of cur_cpu_spec
+ * r5 = relocation offset
+ */
+_GLOBAL(identify_cpu)
+ mfpvr r7
+1:
+ lwz r8,CPU_SPEC_PVR_MASK(r3)
+ and r8,r8,r7
+ lwz r9,CPU_SPEC_PVR_VALUE(r3)
+ cmplw 0,r9,r8
+ beq 1f
+ addi r3,r3,CPU_SPEC_ENTRY_SIZE
+ b 1b
+1:
+ add r3,r3,r5
+ std r3,0(r4)
+ blr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+ /* Get CPU 0 features */
+ LOADADDR(r6,cur_cpu_spec)
+ sub r6,r6,r3
+ ld r4,0(r6)
+ sub r4,r4,r3
+ ld r4,CPU_SPEC_FEATURES(r4)
+ /* Get the fixup table */
+ LOADADDR(r6,__start___ftr_fixup)
+ sub r6,r6,r3
+ LOADADDR(r7,__stop___ftr_fixup)
+ sub r7,r7,r3
+ /* Do the fixup */
+1: cmpld r6,r7
+ bgelr
+ addi r6,r6,32
+ ld r8,-32(r6) /* mask */
+ and r8,r8,r4
+ ld r9,-24(r6) /* value */
+ cmpld r8,r9
+ beq 1b
+ ld r8,-16(r6) /* section begin */
+ ld r9,-8(r6) /* section end */
+ subf. r9,r8,r9
+ beq 1b
+ /* write nops over the section of code */
+ /* todo: if large section, add a branch at the start of it */
+ srwi r9,r9,2
+ mtctr r9
+ sub r8,r8,r3
+ lis r0,0x60000000@h /* nop */
+3: stw r0,0(r8)
+ andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+ beq 2f
+ dcbst 0,r8 /* suboptimal, but simpler */
+ sync
+ icbi 0,r8
+2: addi r8,r8,4
+ bdnz 3b
+ sync /* additional sync needed on g4 */
+ isync
+ b 1b
+
+/*
+ * call_setup_cpu - call the setup_cpu function for this cpu
+ * r3 = data offset
+ *
+ * Setup function is called with:
+ * r3 = data offset
+ * r4 = ptr to CPU spec (relocated)
+ */
+_GLOBAL(call_setup_cpu)
+ LOADADDR(r4, cur_cpu_spec)
+ sub r4,r4,r3
+ lwz r4,0(r4) # load pointer to cpu_spec
+ sub r4,r4,r3 # relocate
+ lwz r6,CPU_SPEC_SETUP(r4) # load function pointer
+ sub r6,r6,r3
+ mtctr r6
+ bctr
+
+
+
+/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
diff --git a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c
index 8847feb93b1a..978211ac0e07 100644
--- a/arch/ppc64/kernel/module.c
+++ b/arch/ppc64/kernel/module.c
@@ -376,15 +376,57 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
return 0;
}
+LIST_HEAD(module_bug_list);
+
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, struct module *me)
{
+ char *secstrings;
+ unsigned int i;
+
+ me->arch.bug_table = NULL;
+ me->arch.num_bugs = 0;
+
+ /* Find the __bug_table section, if present */
+ secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ for (i = 1; i < hdr->e_shnum; i++) {
+ if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
+ continue;
+ me->arch.bug_table = (void *) sechdrs[i].sh_addr;
+ me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
+ break;
+ }
+
+ /*
+ * Strictly speaking this should have a spinlock to protect against
+ * traversals, but since we only traverse on BUG()s, a spinlock
+ * could potentially lead to deadlock and thus be counter-productive.
+ */
+ list_add(&me->arch.bug_list, &module_bug_list);
+
sort_ex_table((struct exception_table_entry *)me->extable,
(struct exception_table_entry *)me->extable +
me->num_exentries);
+
return 0;
}
void module_arch_cleanup(struct module *mod)
{
+ list_del(&mod->arch.bug_list);
+}
+
+struct bug_entry *module_find_bug(unsigned long bugaddr)
+{
+ struct mod_arch_specific *mod;
+ unsigned int i;
+ struct bug_entry *bug;
+
+ list_for_each_entry(mod, &module_bug_list, bug_list) {
+ bug = mod->bug_table;
+ for (i = 0; i < mod->num_bugs; ++i, ++bug)
+ if (bugaddr == bug->bug_addr)
+ return bug;
+ }
+ return NULL;
}
diff --git a/arch/ppc64/kernel/pSeries_htab.c b/arch/ppc64/kernel/pSeries_htab.c
index 0fd0e3b4da81..8028f98d6a9b 100644
--- a/arch/ppc64/kernel/pSeries_htab.c
+++ b/arch/ppc64/kernel/pSeries_htab.c
@@ -21,6 +21,7 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
+#include <asm/cputable.h>
#define HPTE_LOCK_BIT 3
@@ -217,7 +218,7 @@ static long pSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
}
/* Ensure it is out of the tlb too */
- if (cpu_has_tlbiel() && !large && local) {
+ if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) {
_tlbiel(va);
} else {
spin_lock_irqsave(&pSeries_tlbie_lock, flags);
@@ -283,7 +284,7 @@ static void pSeries_hpte_invalidate(unsigned long slot, unsigned long va,
}
/* Invalidate the tlb */
- if (cpu_has_tlbiel() && !large && local) {
+ if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) {
_tlbiel(va);
} else {
spin_lock_irqsave(&pSeries_tlbie_lock, flags);
@@ -346,7 +347,7 @@ static void pSeries_flush_hash_range(unsigned long context,
j++;
}
- if (cpu_has_tlbiel() && !large && local) {
+ if ((cur_cpu_spec->cpu_features & CPU_FTR_TLBIEL) && !large && local) {
asm volatile("ptesync":::"memory");
for (i = 0; i < j; i++) {
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index 58b9c57b3ae8..949425d44cb3 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -45,6 +45,7 @@
#include <asm/machdep.h>
#include <asm/iSeries/HvCallHpt.h>
#include <asm/hardirq.h>
+#include <asm/cputable.h>
struct task_struct *last_task_used_math = NULL;
@@ -412,7 +413,7 @@ void initialize_paca_hardware_interrupt_stack(void)
* __get_free_pages() might give us a page > KERNBASE+256M which
* is mapped with large ptes so we can't set up the guard page.
*/
- if (cpu_has_largepage())
+ if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
return;
for (i=0; i < NR_CPUS; i++) {
diff --git a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
index b973bddf95e3..76a9bd5f4e96 100644
--- a/arch/ppc64/kernel/ras.c
+++ b/arch/ppc64/kernel/ras.c
@@ -58,7 +58,6 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id,
struct pt_regs * regs);
static irqreturn_t ras_error_interrupt(int irq, void *dev_id,
struct pt_regs * regs);
-void init_ras_IRQ(void);
/* #define DEBUG */
@@ -66,7 +65,8 @@ void init_ras_IRQ(void);
* Initialize handlers for the set of interrupts caused by hardware errors
* and power system events.
*/
-void init_ras_IRQ(void) {
+static int __init init_ras_IRQ(void)
+{
struct device_node *np;
unsigned int *ireg, len, i;
@@ -91,7 +91,10 @@ void init_ras_IRQ(void) {
ireg++;
}
}
+
+ return 1;
}
+__initcall(init_ras_IRQ);
/*
* Handle power subsystem events (EPOW).
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 9a1414445643..7b9348deb270 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -47,6 +47,7 @@
#include "open_pic.h"
#include <asm/machdep.h>
#include <asm/xics.h>
+#include <asm/cputable.h>
int smp_threads_ready;
unsigned long cache_decay_ticks;
@@ -583,7 +584,7 @@ int __devinit __cpu_up(unsigned int cpu)
paca[cpu].prof_multiplier = 1;
paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock;
- if (!cpu_has_slb()) {
+ if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
void *tmp;
/* maximum of 48 CPUs on machines with a segment table */
diff --git a/arch/ppc64/kernel/stab.c b/arch/ppc64/kernel/stab.c
index 642dafbcb78b..1640413d5d0b 100644
--- a/arch/ppc64/kernel/stab.c
+++ b/arch/ppc64/kernel/stab.c
@@ -21,6 +21,7 @@
#include <asm/paca.h>
#include <asm/naca.h>
#include <asm/pmc.h>
+#include <asm/cputable.h>
int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid);
void make_slbe(unsigned long esid, unsigned long vsid, int large,
@@ -38,7 +39,7 @@ void stab_initialize(unsigned long stab)
esid = GET_ESID(KERNELBASE);
vsid = get_kernel_vsid(esid << SID_SHIFT);
- if (cpu_has_slb()) {
+ if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
/* Invalidate the entire SLB & all the ERATS */
#ifdef CONFIG_PPC_ISERIES
asm volatile("isync; slbia; isync":::"memory");
@@ -222,7 +223,7 @@ write_entry:
static inline void __ste_allocate(unsigned long esid, unsigned long vsid,
int kernel_segment)
{
- if (cpu_has_slb()) {
+ if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
#ifndef CONFIG_PPC_ISERIES
if (REGION_ID(esid << SID_SHIFT) == KERNEL_REGION_ID)
make_slbe(esid, vsid, 1, kernel_segment);
@@ -275,7 +276,7 @@ int ste_allocate(unsigned long ea)
esid = GET_ESID(ea);
__ste_allocate(esid, vsid, kernel_segment);
- if (!cpu_has_slb()) {
+ if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
/* Order update */
asm volatile("sync":::"memory");
}
@@ -327,7 +328,7 @@ static void preload_stab(struct task_struct *tsk, struct mm_struct *mm)
}
}
- if (!cpu_has_slb()) {
+ if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
/* Order update */
asm volatile("sync" : : : "memory");
}
@@ -336,7 +337,7 @@ static void preload_stab(struct task_struct *tsk, struct mm_struct *mm)
/* Flush all user entries from the segment table of the current processor. */
void flush_stab(struct task_struct *tsk, struct mm_struct *mm)
{
- if (cpu_has_slb()) {
+ if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
/*
* XXX disable 32bit slb invalidate optimisation until we fix
* the issue where a 32bit app execed out of a 64bit app can
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index ad742b3b0019..ff5ae46642c1 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -1136,7 +1136,11 @@ struct sysinfo32 {
u32 totalswap;
u32 freeswap;
unsigned short procs;
- char _f[22];
+ unsigned short pad;
+ u32 totalhigh;
+ u32 freehigh;
+ u32 mem_unit;
+ char _f[20-2*sizeof(long)-sizeof(int)];
};
extern asmlinkage long sys_sysinfo(struct sysinfo *info);
@@ -1145,11 +1149,30 @@ asmlinkage long sys32_sysinfo(struct sysinfo32 *info)
{
struct sysinfo s;
int ret, err;
+ int bitcount=0;
mm_segment_t old_fs = get_fs ();
set_fs (KERNEL_DS);
ret = sys_sysinfo(&s);
set_fs (old_fs);
+ /* Check to see if any memory value is too large for 32-bit and
+ * scale down if needed.
+ */
+ if ((s.totalram >> 32) || (s.totalswap >> 32)) {
+ while (s.mem_unit < PAGE_SIZE) {
+ s.mem_unit <<= 1;
+ bitcount++;
+ }
+ s.totalram >>=bitcount;
+ s.freeram >>= bitcount;
+ s.sharedram >>= bitcount;
+ s.bufferram >>= bitcount;
+ s.totalswap >>= bitcount;
+ s.freeswap >>= bitcount;
+ s.totalhigh >>= bitcount;
+ s.freehigh >>= bitcount;
+ }
+
err = put_user (s.uptime, &info->uptime);
err |= __put_user (s.loads[0], &info->loads[0]);
err |= __put_user (s.loads[1], &info->loads[1]);
@@ -1161,6 +1184,9 @@ asmlinkage long sys32_sysinfo(struct sysinfo32 *info)
err |= __put_user (s.totalswap, &info->totalswap);
err |= __put_user (s.freeswap, &info->freeswap);
err |= __put_user (s.procs, &info->procs);
+ err |= __put_user (s.totalhigh, &info->totalhigh);
+ err |= __put_user (s.freehigh, &info->freehigh);
+ err |= __put_user (s.mem_unit, &info->mem_unit);
if (err)
return -EFAULT;
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
index 348ea20a3ae1..97b2b5173dc6 100644
--- a/arch/ppc64/kernel/traps.c
+++ b/arch/ppc64/kernel/traps.c
@@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -306,6 +307,56 @@ static void parse_fpe(struct pt_regs *regs)
_exception(SIGFPE, &info, regs);
}
+/*
+ * Look through the list of trap instructions that are used for BUG(),
+ * BUG_ON() and WARN_ON() and see if we hit one. At this point we know
+ * that the exception was caused by a trap instruction of some kind.
+ * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
+ * otherwise.
+ */
+extern struct bug_entry __start___bug_table[], __stop___bug_table[];
+
+#ifndef CONFIG_MODULES
+#define module_find_bug(x) NULL
+#endif
+
+static struct bug_entry *find_bug(unsigned long bugaddr)
+{
+ struct bug_entry *bug;
+
+ for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
+ if (bugaddr == bug->bug_addr)
+ return bug;
+ return module_find_bug(bugaddr);
+}
+
+int
+check_bug_trap(struct pt_regs *regs)
+{
+ struct bug_entry *bug;
+ unsigned long addr;
+
+ if (regs->msr & MSR_PR)
+ return 0; /* not in kernel */
+ addr = regs->nip; /* address of trap instruction */
+ if (addr < PAGE_OFFSET)
+ return 0;
+ bug = find_bug(regs->nip);
+ if (bug == NULL)
+ return 0;
+ if (bug->line & BUG_WARNING_TRAP) {
+ /* this is a WARN_ON rather than BUG/BUG_ON */
+ printk(KERN_ERR "Badness in %s at %s:%d\n",
+ bug->function, bug->file,
+ bug->line & ~BUG_WARNING_TRAP);
+ dump_stack();
+ return 1;
+ }
+ printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+ bug->function, bug->file, bug->line);
+ return 0;
+}
+
void
ProgramCheckException(struct pt_regs *regs)
{
@@ -330,6 +381,10 @@ ProgramCheckException(struct pt_regs *regs)
if (debugger_bpt && debugger_bpt(regs))
return;
#endif
+ if (check_bug_trap(regs)) {
+ regs->nip += 4;
+ return;
+ }
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
diff --git a/arch/ppc64/lib/copyuser.S b/arch/ppc64/lib/copyuser.S
index a359bae9c051..a0b3fbbd6fb1 100644
--- a/arch/ppc64/lib/copyuser.S
+++ b/arch/ppc64/lib/copyuser.S
@@ -130,7 +130,7 @@ _GLOBAL(__copy_tofrom_user)
6: cmpwi cr1,r5,8
addi r3,r3,32
sld r9,r9,r10
- blt cr1,.Ldo_tail
+ ble cr1,.Ldo_tail
34: ld r0,8(r4)
srd r7,r0,r11
or r9,r7,r9
diff --git a/arch/ppc64/lib/string.S b/arch/ppc64/lib/string.S
index a63a3a012682..84d14d1b118e 100644
--- a/arch/ppc64/lib/string.S
+++ b/arch/ppc64/lib/string.S
@@ -200,6 +200,7 @@ _GLOBAL(__clear_user)
.llong 8b,92b
.text
+/* r3 = dst, r4 = src, r5 = count */
_GLOBAL(__strncpy_from_user)
addi r6,r3,-1
addi r4,r4,-1
@@ -222,14 +223,10 @@ _GLOBAL(__strncpy_from_user)
.llong 1b,99b
.text
-/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
+/* r3 = str, r4 = len (> 0) */
_GLOBAL(__strnlen_user)
addi r7,r3,-1
- subf r6,r7,r5 /* top+1 - str */
- cmplw 0,r4,r6
- bge 0f
- mr r6,r4
-0: mtctr r6 /* ctr = min(len, top - str) */
+ mtctr r4 /* ctr = len */
1: lbzu r0,1(r7) /* get next byte */
cmpwi 0,r0,0
bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index bc508197478d..79b716dbe6db 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -59,6 +59,7 @@
#include <asm/eeh.h>
#include <asm/processor.h>
#include <asm/mmzone.h>
+#include <asm/cputable.h>
#include <asm/ppcdebug.h>
@@ -512,7 +513,7 @@ void __init paging_init(void)
static struct kcore_list kcore_vmem;
-static void setup_kcore(void)
+static int __init setup_kcore(void)
{
int i;
@@ -536,7 +537,10 @@ static void setup_kcore(void)
}
kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
+
+ return 0;
}
+module_init(setup_kcore);
void initialize_paca_hardware_interrupt_stack(void);
@@ -606,8 +610,6 @@ void __init mem_init(void)
#endif
mem_init_done = 1;
- setup_kcore();
-
/* set the last page of each hardware interrupt stack to be protected */
initialize_paca_hardware_interrupt_stack();
@@ -698,7 +700,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long ea,
int local = 0;
/* handle i-cache coherency */
- if (!cpu_has_noexecute()) {
+ if (!(cur_cpu_spec->cpu_features & CPU_FTR_NOEXECUTE)) {
unsigned long pfn = pte_pfn(pte);
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
index af39634eabcd..fd86d7ec8267 100644
--- a/arch/ppc64/mm/numa.c
+++ b/arch/ppc64/mm/numa.c
@@ -154,8 +154,28 @@ new_range:
if (max_domain < numa_domain)
max_domain = numa_domain;
- node_data[numa_domain].node_start_pfn = start / PAGE_SIZE;
- node_data[numa_domain].node_size = size / PAGE_SIZE;
+ /*
+ * For backwards compatibility, OF splits the first node
+ * into two regions (the first being 0-4GB). Check for
+ * this simple case and complain if there is a gap in
+ * memory
+ */
+ if (node_data[numa_domain].node_size) {
+ unsigned long shouldstart =
+ node_data[numa_domain].node_start_pfn +
+ node_data[numa_domain].node_size;
+ if (shouldstart != (start / PAGE_SIZE)) {
+ printk(KERN_ERR "Hole in node, disabling "
+ "region start %lx length %lx\n",
+ start, size);
+ continue;
+ }
+ node_data[numa_domain].node_size += size / PAGE_SIZE;
+ } else {
+ node_data[numa_domain].node_start_pfn =
+ start / PAGE_SIZE;
+ node_data[numa_domain].node_size = size / PAGE_SIZE;
+ }
for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
@@ -174,6 +194,20 @@ new_range:
return 0;
}
+void setup_nonnuma(void)
+{
+ unsigned long i;
+
+ for (i = 0; i < NR_CPUS; i++)
+ map_cpu_to_node(i, 0);
+
+ node_data[0].node_start_pfn = 0;
+ node_data[0].node_size = lmb_end_of_DRAM() / PAGE_SIZE;
+
+ for (i = 0 ; i < lmb_end_of_DRAM(); i += MEMORY_INCREMENT)
+ numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
+}
+
void __init do_init_bootmem(void)
{
int nid;
@@ -181,9 +215,8 @@ void __init do_init_bootmem(void)
min_low_pfn = 0;
max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
- /* XXX FIXME: support machines without associativity information */
if (parse_numa_properties())
- BUG();
+ setup_nonnuma();
for (nid = 0; nid < numnodes; nid++) {
unsigned long start_paddr, end_paddr;
@@ -204,7 +237,7 @@ void __init do_init_bootmem(void)
NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
- bootmap_pages = bootmem_bootmap_pages(end_paddr - start_paddr);
+ bootmap_pages = bootmem_bootmap_pages((end_paddr - start_paddr) >> PAGE_SHIFT);
dbg("bootmap_pages = %lx\n", bootmap_pages);
bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
diff --git a/arch/ppc64/vmlinux.lds.S b/arch/ppc64/vmlinux.lds.S
index f6429d5d13c0..e67c30140531 100644
--- a/arch/ppc64/vmlinux.lds.S
+++ b/arch/ppc64/vmlinux.lds.S
@@ -65,6 +65,14 @@ SECTIONS
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
+ __start___bug_table = .;
+ __bug_table : { *(__bug_table) }
+ __stop___bug_table = .;
+
+ __start___ftr_fixup = .;
+ __ftr_fixup : { *(__ftr_fixup) }
+ __stop___ftr_fixup = .;
+
. = ALIGN(16384); /* init_task */
.data.init_task : { *(.data.init_task) }
@@ -104,6 +112,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff --git a/arch/s390/vmlinux.lds.S b/arch/s390/vmlinux.lds.S
index db6140c6b30a..bf599bab85e1 100644
--- a/arch/s390/vmlinux.lds.S
+++ b/arch/s390/vmlinux.lds.S
@@ -94,6 +94,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(256);
__initramfs_start = .;
.init.ramfs : { *(.init.initramfs) }
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 12053ca0422a..c78ddd287821 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -12,11 +12,7 @@ config SUPERH
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
gaming console. The SuperH port has a home page at
- <http://www.sh-linux.org/>.
-
-config MMU
- bool
- default y
+ <http://www.linux-sh.org/>.
config UID16
bool
@@ -33,60 +29,18 @@ config GENERIC_ISA_DMA
bool
default y
+config VARIABLE_CLOCK_TICK_RATE
+ bool
+ default y
+
source "init/Kconfig"
-menu "Processor type and features"
+menu "System type"
choice
prompt "SuperH system type"
- default SH_GENERIC
-
-config SH_GENERIC
- bool "Generic"
- ---help---
- Select Generic if configuring for a generic SuperH system.
- The "generic" option compiles in *all* the possible hardware
- support and relies on the sh_mv= kernel commandline option to choose
- at runtime which routines to use. "MV" stands for "machine vector";
- each of the machines below is described by a machine vector.
-
- Select SolutionEngine if configuring for a Hitachi SH7709
- or SH7750/7750S evalutation board.
-
- Select Overdrive if configuring for a ST407750 Overdrive board.
- More information at
- <http://linuxsh.sourceforge.net/docs/7750overdrive.php3>.
-
- Select HP620 if configuring for a HP Jornada HP620.
- More information (hardware only) at
- <http://www.hp.com/jornada/>.
-
- Select HP680 if configuring for a HP Jornada HP680.
- More information (hardware only) at
- <http://www.hp.com/jornada/products/680/>.
-
- Select HP690 if configuring for a HP Jornada HP690.
- More information (hardware only) at
- <http://www.hp.com/jornada/products/680/>.
-
- Select CqREEK if configuring for a CqREEK SH7708 or SH7750.
- More information at
- <http://sources.redhat.com/ecos/hardware.html#SuperH>.
-
- Select DMIDA if configuring for a DataMyte 4000 Industrial
- Digital Assistant. More information at <http://www.dmida.com/>.
-
- Select EC3104 if configuring for a system with an Eclipse
- International EC3104 chip, e.g. the Harris AD2000 or Compaq Aero 8000.
-
- Select Dreamcast if configuring for a SEGA Dreamcast.
- More information at
- <http://www.m17n.org/linux-sh/dreamcast/>. There is a
- Dreamcast project is at <http://linuxdc.sourceforge.net/>.
-
- Select BareCPU if you know what this means, and it applies
- to your system.
+ default SH_UNKNOWN
config SH_SOLUTION_ENGINE
bool "SolutionEngine"
@@ -146,6 +100,9 @@ config SH_EC3104
Select EC3104 if configuring for a system with an Eclipse
International EC3104 chip, e.g. the Harris AD2000.
+config SH_SATURN
+ bool "Saturn"
+
config SH_DREAMCAST
bool "Dreamcast"
help
@@ -162,10 +119,19 @@ config SH_BIGSUR
config SH_SH2000
bool "SH2000"
+ help
+ SH-2000 is a single-board computer based around SH7709A chip
+ intended for embedded applications.
+ It has an Ethernet interface (CS8900A), direct connected
+ Compact Flash socket, three serial ports and PC-104 bus.
+ More information at <http://sh2000.sh-linux.org>.
config SH_ADX
bool "ADX"
+config SH_MPC1211
+ bool "MPC1211"
+
config SH_UNKNOWN
bool "BareCPU"
help
@@ -180,6 +146,119 @@ config SH_UNKNOWN
endchoice
+config MMU
+ bool "Support for memory management hardware"
+ depends on !CPU_SH2
+ default y
+ help
+ Early SH processors (such as the SH7604) lack an MMU. In order to
+ boot on these systems, this option must not be set.
+
+ On other systems (such as the SH-3 and 4) where an MMU exists,
+ turning this off will boot the kernel on these machines with the
+ MMU implicitly switched off.
+
+config CMDLINE_BOOL
+ bool "Default bootloader kernel arguments"
+
+config CMDLINE
+ string "Initial kernel command string"
+ depends on CMDLINE_BOOL
+ default "console=ttySC1,115200"
+
+# Platform-specific memory start and size definitions
+config MEMORY_START
+ hex "Physical memory start address" if !MEMORY_SET || MEMORY_OVERRIDE
+ default "08000000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || SH_MPC1211
+ default "0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE)
+ ---help---
+ Computers built with Hitachi SuperH processors always
+ map the ROM starting at address zero. But the processor
+ does not specify the range that RAM takes.
+
+ The physical memory (RAM) start address will be automatically
+ set to 08000000, unless you selected one of the following
+ processor types: SolutionEngine, Overdrive, HP620, HP680, HP690,
+ in which case the start address will be set to 0c000000.
+
+ Tweak this only when porting to a new machine which is not already
+ known by the config system. Changing it from the known correct
+ value on any of the known systems will only lead to disaster.
+
+config MEMORY_SIZE
+ hex "Physical memory size" if !MEMORY_SET || MEMORY_OVERRIDE
+ default "00400000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || !MEMORY_OVERRIDE && (SH_HP600 || SH_BIGSUR || SH_SH2000)
+ default "01000000" if !MEMORY_OVERRIDE && SH_DREAMCAST
+ default "04000000" if !MEMORY_OVERRIDE && SH_7751_SOLUTION_ENGINE
+ default "02000000" if !MEMORY_OVERRIDE && SH_SOLUTION_ENGINE
+ default "08000000" if SH_MPC1211
+ help
+ This sets the default memory size assumed by your SH kernel. It can
+ be overridden as normal by the 'mem=' argument on the kernel command
+ line. If unsure, consult your board specifications or just leave it
+ as 0x00400000 which was the default value before this became
+ configurable.
+
+config MEMORY_SET
+ bool
+ depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE)
+ default y
+ help
+ This is an option about which you will never be asked a question.
+ Therefore, I conclude that you do not exist - go away.
+
+ There is a grue here.
+
+# If none of the above have set memory start/size, ask the user.
+config MEMORY_OVERRIDE
+ bool "Override default load address and memory size"
+
+# XXX: break these out into the board-specific configs below
+config CF_ENABLER
+ bool "Compact Flash Enabler support"
+ depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701
+ ---help---
+ Compact Flash is a small, removable mass storage device introduced
+ in 1994 originally as a PCMCIA device. If you say `Y' here, you
+ compile in support for Compact Flash devices directly connected to
+ a SuperH processor. A Compact Flash FAQ is available at
+ <http://www.compactflash.org/faqs/faq.htm>.
+
+ If your board has "Directly Connected" CompactFlash at area 5 or 6,
+ you may want to enable this option. Then, you can use CF as
+ primary IDE drive (only tested for SanDisk).
+
+ If in doubt, select 'N'.
+
+choice
+ prompt "Compact Flash Connection Area"
+ depends on CF_ENABLER
+ default CF_AREA6
+
+config CF_AREA5
+ bool "Area5"
+ help
+ If your board has "Directly Connected" CompactFlash, You should
+ select the area where your CF is connected to.
+
+ - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
+ - "Area6" if it is connected to Area 6 (0x18000000)
+
+ "Area6" will work for most boards. For ADX, select "Area5".
+
+config CF_AREA6
+ bool "Area6"
+
+endchoice
+
+config CF_BASE_ADDR
+ hex
+ depends on CF_ENABLER
+ default "b8000000" if CF_AREA6
+ default "b4000000" if CF_AREA5
+
+endmenu
+
# The SH7750 RTC module is disabled in the Dreamcast
config SH_RTC
bool
@@ -191,21 +270,50 @@ config SH_RTC
If unsure, say N.
+# This is also board-specific
+config PCI_AUTO
+ bool
+
config SH_HP600
bool
depends on SH_HP620 || SH_HP680 || SH_HP690
default y
+config DISCONTIGMEM
+ bool
+ depends on SH_HP690
+ default y
+ help
+ Say Y to upport efficient handling of discontiguous physical memory,
+ for architectures which are either NUMA (Non-Uniform Memory Access)
+ or have huge holes in the physical address space for other reasons.
+ See <file:Documentation/vm/numa> for more.
+
+
+menu "Processor type and features"
+
+#
+# Ick, get rid of all this CPU_SUBTYPE nonsense. Just probe it, fill in
+# cpu_data, and leave it alone. (Feasible for SH-4 at least, and some
+# SH-3). ++paulm
+#
choice
prompt "Processor type"
default CPU_SUBTYPE_SH7708
+config CPU_SUBTYPE_SH7604
+ bool "SH7604"
+ help
+ Select SH7604 if you have SH7604
+
config CPU_SUBTYPE_SH7707
bool "SH7707"
---help---
Select the type of SuperH processor you have. This information is
used for optimizing and configuration purposes.
+ Select SH7604 if you have a SH-2 CPU.
+
Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU.
Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or
@@ -237,174 +345,188 @@ config CPU_SUBTYPE_SH7750
config CPU_SUBTYPE_SH7751
bool "SH7751"
+ help
+ Select SH7750 if you have a 166 Mhz SH-4 HD6417751 CPU.
config CPU_SUBTYPE_ST40STB1
bool "ST40STB1"
+ help
+ Select ST40STB1 if you have a ST40STB1 CPU.
endchoice
+config CPU_SH2
+ bool
+ depends on CPU_SUBTYPE_SH7604
+ default y
+
config CPU_SH3
bool
- depends on CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7708 || CPU_SUBTYPE_SH7707
+ depends on !CPU_SH2 && (CPU_SUBTYPE_SH7707 || CPU_SUBTYPE_SH7708 || CPU_SUBTYPE_SH7709)
default y
config CPU_SH4
bool
- depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7750
+ depends on !CPU_SH3 && !CPU_SH2 && (CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_ST40STB1)
default y
-config CPU_LITTLE_ENDIAN
- bool "Little Endian"
+config ZERO_PAGE_OFFSET
+ hex "Zero page offset"
+ default "00001000" if !SH_MPC1211
+ default "00004000" if SH_MPC1211
help
- Some MIPS machines can be configured for either little or big endian
- byte order. These modes require different kernels. Say Y if your
- machine is little endian, N if it's a big endian machine.
-
-# Platform-specific memory start and size definitions
-config MEMORY_START
- hex "Physical memory start address" if !MEMORY_SET
- default "08000000" if !MEMORY_SET || SH_ADX || CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
- default "0c000000" if SH_HP600 || SH_BIGSUR || SH_DREAMCAST || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE
- ---help---
- Computers built with Hitachi SuperH processors always
- map the ROM starting at address zero. But the processor
- does not specify the range that RAM takes.
+ This sets the default offset of zero page.
- The physical memory (RAM) start address will be automatically
- set to 08000000, unless you selected one of the following
- processor types: SolutionEngine, Overdrive, HP620, HP680, HP690,
- in which case the start address will be set to 0c000000.
+# XXX: needs to lose subtype for system type
+config ST40_LMI_MEMORY
+ bool "Memory on LMI"
+ depends on CPU_SUBTYPE_ST40STB1
- Tweak this only when porting to a new machine which is not already
- known by the config system. Changing it from the known correct
- value on any of the known systems will only lead to disaster.
+config MEMORY_START
+ hex
+ depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
+ default "08000000"
config MEMORY_SIZE
- hex "Physical memory size" if !MEMORY_SET
- default "00400000" if !MEMORY_SET || SH_ADX || CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY || SH_HP600 || SH_BIGSUR || SH_DREAMCAST || SH_SH2000
- default "04000000" if SH_7751_SOLUTION_ENGINE
- default "02000000" if SH_SOLUTION_ENGINE
- help
- This sets the default memory size assumed by your SH kernel. It can
- be overridden as normal by the 'mem=' argument on the kernel command
- line. If unsure, consult your board specifications or just leave it
- as 0x00400000 which was the default value before this became
- configurable.
+ hex
+ depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
+ default "00400000"
config MEMORY_SET
bool
- depends on SH_ADX || CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY || SH_HP600 || SH_BIGSUR || SH_DREAMCAST || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE
+ depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
default y
+
+config CPU_LITTLE_ENDIAN
+ bool "Little Endian"
help
- This is an option about which you will never be asked a question.
- Therefore, I conclude that you do not exist - go away.
+ Some SuperH machines can be configured for either little or big
+ endian byte order. These modes require different kernels. Say Y if
+ your machine is little endian, N if it's a big endian machine.
- There is a grue here.
+config PREEMPT
+ bool "Preemptible Kernel (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
-config ST40_LMI_MEMORY
- bool "Memory on LMI"
- depends on CPU_SUBTYPE_ST40STB1
+config UBC_WAKEUP
+ bool "Wakeup UBC on startup"
+ help
+ Selecting this option will wakeup the User Break Controller (UBC) on
+ startup. Although the UBC is left in an awake state when the processor
+ comes up, some boot loaders misbehave by putting the UBC to sleep in a
+ power saving state, which causes issues with things like ptrace().
-# If none of the above have set memory start/size, ask the user.
-endmenu
+ If unsure, say N.
-config DISCONTIGMEM
- bool
- depends on SH_HP690
- default y
+config SH_WRITETHROUGH
+ bool "Use write-through caching"
+ default y if CPU_SH2
help
- Say Y to upport efficient handling of discontiguous physical memory,
- for architectures which are either NUMA (Non-Uniform Memory Access)
- or have huge holes in the physical address space for other reasons.
- See <file:Documentation/vm/numa> for more.
+ Selecting this option will configure the caches in write-through
+ mode, as opposed to the default write-back configuration.
+ Since there's sill some aliasing issues on SH-4, this option will
+ unfortunately still require the majority of flushing functions to
+ be implemented to deal with aliasing.
-menu "General setup"
+ If unsure, say N.
-# Even on SuperH devices which don't have an ISA bus,
-# this variable helps the PCMCIA modules handle
-# IRQ requesting properly -- Greg Banks.
-config ISA
- bool
- default y
+config SH_OCRAM
+ bool "Operand Cache RAM (OCRAM) support"
help
- Find out whether you have ISA slots on your motherboard. ISA is the
- name of a bus system, i.e. the way the CPU talks to the other stuff
- inside your box. Other bus systems are PCI, EISA, MicroChannel
- (MCA) or VESA. ISA is an older system, now being displaced by PCI;
- newer boards don't support it. If you have ISA, say Y, otherwise N.
+ Selecting this option will automatically tear down the number of
+ sets in the dcache by half, which in turn exposes a memory range.
-config EISA
- bool
- ---help---
- The Extended Industry Standard Architecture (EISA) bus was
- developed as an open alternative to the IBM MicroChannel bus.
+ The addresses for the OC RAM base will vary according to the
+ processor version. Consult vendor documentation for specifics.
- The EISA bus provided some of the features of the IBM MicroChannel
- bus while maintaining backward compatibility with cards made for
- the older ISA bus. The EISA bus saw limited use between 1988 and
- 1995 when it was made obsolete by the PCI bus.
+ If unsure, say N.
- Say Y here if you are building a kernel for an EISA-based machine.
+config SMP
+ bool "Symmetric multi-processing support"
+ ---help---
+ This enables support for systems with more than one CPU. If you have
+ a system with only one CPU, like most personal computers, say N. If
+ you have a system with more than one CPU, say Y.
+
+ If you say N here, the kernel will run on single and multiprocessor
+ machines, but will use only one CPU of a multiprocessor machine. If
+ you say Y here, the kernel will run on many, but not all,
+ singleprocessor machines. On a singleprocessor machine, the kernel
+ will run faster if you say N here.
+
+ People using multiprocessor machines who say Y here should also say
+ Y to "Enhanced Real Time Clock Support", below.
+
+ See also the <file:Documentation/smp.tex>,
+ <file:Documentation/smp.txt>, <file:Documentation/nmi_watchdog.txt>
+ and the SMP-HOWTO available at
+ <http://www.tldp.org/docs.html#howto>.
- Otherwise, say N.
+ If you don't know what to do here, say N.
-config MCA
- bool
+config NR_CPUS
+ int "Maximum number of CPUs (2-32)"
+ depends on SMP
+ default "2"
help
- MicroChannel Architecture is found in some IBM PS/2 machines and
- laptops. It is a bus system similar to PCI or ISA. See
- <file:Documentation/mca.txt> (and especially the web page given
- there) before attempting to build an MCA bus kernel.
+ This allows you to specify the maximum number of CPUs which this
+ kernel will support. The maximum supported value is 32 and the
+ minimum value which makes sense is 2.
-config SBUS
- bool
+ This is purely to save memory - each supported CPU adds
+ approximately eight kilobytes to the kernel image.
-config CF_ENABLER
- bool "Compact Flash Enabler support"
- depends on SH_GENERIC || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_ADX
- ---help---
- Compact Flash is a small, removable mass storage device introduced
- in 1994 originally as a PCMCIA device. If you say `Y' here, you
- compile in support for Compact Flash devices directly connected to
- a SuperH processor. A Compact Flash FAQ is available at
- <http://www.compactflash.org/faqs/faq.htm>.
+config SH_DMA
+ bool "DMA controller (DMAC) support"
+ help
+ Selecting this option will provide same API as PC's Direct Memory
+ Access Controller(8237A) for SuperH DMAC.
- If your board has "Directly Connected" CompactFlash at area 5 or 6,
- you may want to enable this option. Then, you can use CF as
- primary IDE drive (only tested for SanDisk).
+ If unsure, say N.
- If in doubt, select 'N'.
+config CPU_FREQ
+ bool "CPU Frequency scaling"
+ help
+ CPU clock scaling allows you to change the clock speed of the
+ running CPU on the fly.
-choice
- prompt "Compact Flash Connection Area"
- depends on CF_ENABLER
- default CF_AREA6
+ For details, take a look at <file:Documentation/cpufreq>.
-config CF_AREA5
- bool "Area5"
+ If unsure, say N.
+
+config CPU_FREQ_TABLE
+ tristate "CPU frequency table helpers"
+ depends on CPU_FREQ
+ default y
help
- If your board has "Directly Connected" CompactFlash, You should
- select the area where your CF is connected to.
+ Many cpufreq drivers use these helpers, so only say N here if
+ the cpufreq driver of your choice doesn't need these helpers.
- - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
- - "Area6" if it is connected to Area 6 (0x18000000)
+ If unsure, say Y.
- "Area6" will work for most boards. For ADX, select "Area5".
+config SH_CPU_FREQ
+ tristate "SuperH CPU Frequency driver"
+ depends on CPU_FREQ
+ help
+ This adds the cpufreq driver for SuperH. At present, only
+ the SH-4 is supported.
-config CF_AREA6
- bool "Area6"
+ For details, take a look at <file:Documentation/cpufreq>.
-endchoice
+ If unsure, say N.
-config CF_BASE_ADDR
- hex
- depends on CF_ENABLER
- default "b8000000" if CF_AREA6
- default "b4000000" if CF_AREA5
+source "drivers/cpufreq/Kconfig"
+
+# A board must have defined HD6446X_SERIES in order to see these
+choice
+ prompt "HD6446x options"
+ depends HD6446X_SERIES
+ default HD64461
config HD64461
bool "Hitachi HD64461 companion chip support"
+ depends on CPU_SUBTYPE_SH7709
---help---
The Hitachi HD64461 provides an interface for
the SH7709 CPU, supporting a LCD controller,
@@ -417,6 +539,24 @@ config HD64461
Say Y if you want support for the HD64461.
Otherwise, say N.
+config HD64465
+ bool "Hitachi HD64465 companion chip support"
+ depends on CPU_SUBTYPE_SH7750
+ ---help---
+ The Hitachi HD64465 provides an interface for
+ the SH7750 CPU, supporting a LCD controller,
+ CRT color controller, IrDA, USB, PCMCIA,
+ keyboard controller, and a printer interface.
+
+ More information is available at
+ <http://global.hitachi.com/New/cnews/E/1998/981019B.html>.
+
+ Say Y if you want support for the HD64465.
+ Otherwise, say N.
+
+endchoice
+
+# These will also be split into the Kconfig's below
config HD64461_IRQ
int "HD64461 IRQ"
depends on HD64461
@@ -434,19 +574,6 @@ config HD64461_ENABLER
via the HD64461 companion chip.
Otherwise, say N.
-config HD64465
- bool "Hitachi HD64465 companion chip support"
- ---help---
- The Hitachi HD64465 provides an interface for
- the SH7750 CPU, supporting a LCD controller,
- CRT color controller, IrDA, USB, PCMCIA,
- keyboard controller, and a printer interface.
-
- More information is available at
- <http://global.hitachi.com/New/cnews/E/1998/981019B.html>.
-
- Say Y if you want support for the HD64465.
- Otherwise, say N.
config HD64465_IOBASE
hex "HD64465 start address"
@@ -466,13 +593,49 @@ config HD64465_IRQ
Do not change this unless you know what you are doing.
-config SH_DMA
- bool "DMA controller (DMAC) support"
+endmenu
+
+
+menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+# Even on SuperH devices which don't have an ISA bus,
+# this variable helps the PCMCIA modules handle
+# IRQ requesting properly -- Greg Banks.
+config ISA
+ bool
+ default y
help
- Selecting this option will provide same API as PC's Direct Memory
- Access Controller(8237A) for SuperH DMAC.
+ Find out whether you have ISA slots on your motherboard. ISA is the
+ name of a bus system, i.e. the way the CPU talks to the other stuff
+ inside your box. Other bus systems are PCI, EISA, MicroChannel
+ (MCA) or VESA. ISA is an older system, now being displaced by PCI;
+ newer boards don't support it. If you have ISA, say Y, otherwise N.
- If unsure, say N.
+config EISA
+ bool
+ ---help---
+ The Extended Industry Standard Architecture (EISA) bus was
+ developed as an open alternative to the IBM MicroChannel bus.
+
+ The EISA bus provided some of the features of the IBM MicroChannel
+ bus while maintaining backward compatibility with cards made for
+ the older ISA bus. The EISA bus saw limited use between 1988 and
+ 1995 when it was made obsolete by the PCI bus.
+
+ Say Y here if you are building a kernel for an EISA-based machine.
+
+ Otherwise, say N.
+
+config MCA
+ bool
+ help
+ MicroChannel Architecture is found in some IBM PS/2 machines and
+ laptops. It is a bus system similar to PCI or ISA. See
+ <file:Documentation/mca.txt> (and especially the web page given
+ there) before attempting to build an MCA bus kernel.
+
+config SBUS
+ bool
config PCI
bool "PCI support"
@@ -559,6 +722,13 @@ config HOTPLUG
source "drivers/pcmcia/Kconfig"
+source "drivers/hotplug/Kconfig"
+
+endmenu
+
+
+menu "Executable file formats"
+
choice
prompt "Kernel core (/proc/kcore) format"
depends on PROC_FS
@@ -622,6 +792,9 @@ config BINFMT_ELF
will be called binfmt_elf. Saying M or N here is dangerous because
some crucial programs on your system might be in ELF format.
+config BINFMT_FLAT
+ tristate "Kernel support for FLAT binaries"
+
config BINFMT_MISC
tristate "Kernel support for MISC binaries"
---help---
@@ -647,15 +820,13 @@ config BINFMT_MISC
you have use for it; the module is called binfmt_misc. If you
don't know what to answer at this point, say Y.
-source "drivers/parport/Kconfig"
-
endmenu
source "drivers/mtd/Kconfig"
-source "drivers/block/Kconfig"
+source "drivers/parport/Kconfig"
-source "drivers/md/Kconfig"
+source "drivers/block/Kconfig"
menu "ATA/ATAPI/MFM/RLL support"
@@ -711,10 +882,10 @@ source "drivers/ide/Kconfig"
endmenu
-menu "SCSI support"
+menu "SCSI device support"
config SCSI
- tristate "SCSI support"
+ tristate "SCSI device support"
---help---
If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
any other SCSI device under Linux, say Y and make sure that you know
@@ -737,9 +908,6 @@ source "drivers/scsi/Kconfig"
endmenu
-source "drivers/ieee1394/Kconfig"
-
-source "net/Kconfig"
menu "Old CD-ROM drivers (not SCSI, not IDE)"
@@ -776,8 +944,22 @@ source "drivers/cdrom/Kconfig"
endmenu
+source "drivers/md/Kconfig"
+
+source "drivers/ieee1394/Kconfig"
+
+source "net/Kconfig"
+
+source "net/ax25/Kconfig"
+
+source "net/irda/Kconfig"
+
+source "drivers/isdn/Kconfig"
+
+source "drivers/telephony/Kconfig"
+
#
-# input before char - char/joystick depends on it. As does USB.
+# input - input/joystick depends on it. As does USB.
#
source "drivers/input/Kconfig"
@@ -837,6 +1019,11 @@ config VT_CONSOLE
If unsure, say Y.
+config HW_CONSOLE
+ bool
+ depends on VT && !S390 && !UM
+ default y
+
config SERIAL
tristate "Serial (8250, 16450, 16550 or compatible) support"
---help---
@@ -948,7 +1135,7 @@ config UNIX98_PTY_COUNT
config HEARTBEAT
bool "Heartbeat LED"
- depends on SH_GENERIC || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE
+ depends on SH_MPC1211 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE
help
Use the power-on LED on your machine as a load meter. The exact
behavior is platform-dependent, but normally the flash frequency is
@@ -971,7 +1158,6 @@ comment "Input core support is required for Maple input peripherals"
endmenu
-#source drivers/char/joystick/Config.in
config PRINTER
tristate "Parallel printer support"
depends on PARPORT
@@ -1095,12 +1281,18 @@ config WATCHDOG_NOWAYOUT
it has been started.
config SH_WDT
- tristate "SH 3/4 Watchdog"
+ tristate "SuperH Watchdog"
depends on WATCHDOG
help
This driver adds watchdog support for the integrated watchdog in the
- SuperH 3 and 4 processors. If you have one of these processors, say Y,
- otherwise say N.
+ SuperH processors. If you have one of these processors and wish
+ to have watchdog support enabled, say Y, otherwise say N.
+
+ As a side note, saying Y here will automatically boost HZ to 1000
+ so that the timer has a chance to clear the overflow counter. On
+ slower systems (such as the SH-2 and SH-3) this will likely yield
+ some performance issues. As such, the WDT should be avoided here
+ unless it is absolutely necessary.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
@@ -1138,6 +1330,10 @@ config RTC
source "drivers/char/pcmcia/Kconfig"
+source "drivers/serial/Kconfig"
+
+source "drivers/i2c/Kconfig"
+
endmenu
source "fs/Kconfig"
@@ -1182,6 +1378,10 @@ source "sound/Kconfig"
endmenu
+source "drivers/usb/Kconfig"
+
+source "net/bluetooth/Kconfig"
+
menu "Kernel hacking"
@@ -1198,6 +1398,14 @@ config MAGIC_SYSRQ
keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
unless you really know what this hack does.
+config DEBUG_SPINLOCK
+ bool "Spinlock debugging"
+ help
+ Say Y here and build SMP to catch missing spinlock initialization
+ and certain other kinds of spinlock errors commonly made. This is
+ best used in conjunction with the NMI watchdog so that spinlock
+ deadlocks are also debuggable.
+
config SH_STANDARD_BIOS
bool "Use LinuxSH standard BIOS"
help
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 2fd1224ae8f7..e965c9baaf93 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -1,10 +1,12 @@
-# $Id: Makefile,v 1.6 2000/06/10 03:03:52 gniibe Exp $
+# $Id: Makefile,v 1.17 2003/05/20 03:12:54 lethal Exp $
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1999 Kaz Kojima
+# Copyright (C) 2002, 2003 Paul Mundt
+# Copyright (C) 2002 M. R. Brown
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
@@ -12,72 +14,116 @@
# this architecture
#
-ifdef CONFIG_CPU_LITTLE_ENDIAN
-CFLAGS += -ml
-AFLAGS += -ml
-# LDFLAGS_vmlinux += -EL
-LDFLAGS := -EL
-else
-CFLAGS += -mb
-AFLAGS += -mb
-# LDFLAGS_vmlinux += -EB
-LDFLAGS := -EB
+#
+# We don't necessarily agree with the top-level Makefile with regards to what
+# does and does not qualify as a noconfig_targets rule. In this case, we're
+# still dependant on .config settings in order for core-y (machdir-y in
+# particular) to resolve the proper directory. So we just manually include it
+# if it hasn't been already..
+#
+ifndef include_config
+-include .config
endif
-OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S
-
-MODFLAGS +=
+cpu-y := -mb
+cpu-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml
-#
-#
+cpu-$(CONFIG_CPU_SH2) += -m2
+cpu-$(CONFIG_CPU_SH3) += -m3
+cpu-$(CONFIG_CPU_SH4) += -m4 -mno-implicit-fp
-ifdef CONFIG_CPU_SH3
-CFLAGS += -m3
-AFLAGS += -m3
+ifdef CONFIG_SH_KGDB
+CFLAGS :=$(CFLAGS:-fomit-frame-pointer=) -g
+AFLAGS += -g
+ifdef CONFIG_KGDB_MORE
+CFLAGS += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
endif
-ifdef CONFIG_CPU_SH4
-CFLAGS += -m4 -mno-implicit-fp
-AFLAGS += -m4 -mno-implicit-fp
endif
+OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S
+
#
# Choosing incompatible machines durings configuration will result in
# error messages during linking.
#
LDFLAGS_vmlinux += -e _stext
-ifdef LOADADDR
-LDFLAGS_vmlinux += -Ttext $(word 1,$(LOADADDR))
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64' -EL
+LDFLAGS_BLOB :=--format binary --oformat elf32-sh-linux
+else
+LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4' -EB
+LDFLAGS_BLOB :=--format binary --oformat elf32-shbig-linux
endif
-#
-CFLAGS += -pipe
+CFLAGS += -pipe $(cpu-y)
+AFLAGS += $(cpu-y)
head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
core-y += arch/sh/kernel/ arch/sh/mm/
-core-$(CONFIG_SH_GENERIC) += arch/sh/stboards/
-core-$(CONFIG_SH_STB1_HARP) += arch/sh/stboards/
-core-$(CONFIG_SH_STB1_OVERDRIVE)+= arch/sh/stboards/
+
+# Boards
+machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
+machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
+machdir-$(CONFIG_SH_STB1_HARP) := harp
+machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive
+machdir-$(CONFIG_SH_HP620) := hp6xx/hp620
+machdir-$(CONFIG_SH_HP680) := hp6xx/hp680
+machdir-$(CONFIG_SH_HP690) := hp6xx/hp690
+machdir-$(CONFIG_SH_CQREEK) := cqreek
+machdir-$(CONFIG_SH_DMIDA) := dmida
+machdir-$(CONFIG_SH_EC3104) := ec3104
+machdir-$(CONFIG_SH_SATURN) := saturn
+machdir-$(CONFIG_SH_DREAMCAST) := dreamcast
+machdir-$(CONFIG_SH_CAT68701) := cat68701
+machdir-$(CONFIG_SH_BIGSUR) := bigsur
+machdir-$(CONFIG_SH_SH2000) := sh2000
+machdir-$(CONFIG_SH_ADX) := adx
+machdir-$(CONFIG_SH_MPC1211) := mpc1211
+machdir-$(CONFIG_SH_UNKNOWN) := unknown
+
+incdir-y := $(machdir-y)
+
+incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se
+incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751
+incdir-$(CONFIG_SH_HP600) := hp6xx
+
+core-y += arch/sh/boards/$(machdir-y)/
+
+# Companion chips
+core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/
+core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/
+
+cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2
+cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3
+cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4
+
libs-y += arch/sh/lib/ $(LIBGCC)
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+boot := arch/sh/boot
AFLAGS_vmlinux.lds.o := -traditional
+prepare: target_links
+
+.PHONY: target_links FORCE
+target_links:
+ @echo ' Making asm-sh/cpu -> asm-sh/$(cpuincdir-y) link'
+ @ln -sf $(cpuincdir-y) include/asm-sh/cpu
+
+ @echo ' Making asm-sh/mach -> asm-sh/$(incdir-y) link'
+ @ln -sf $(incdir-y) include/asm-sh/mach
+
+ $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
+
+BOOTIMAGE=arch/sh/boot/zImage
zImage: vmlinux
- @$(MAKEBOOT) zImage
+ $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
compressed: zImage
-zdisk: vmlinux
- @$(MAKEBOOT) zdisk
-
archclean:
- @$(MAKEBOOT) clean
- $(MAKE) -C arch/$(ARCH)/kernel clean
- $(MAKE) -C arch/$(ARCH)/stboards clean
-# $(MAKE) -C arch/$(ARCH)/tools clean
-
+ $(Q)$(MAKE) $(clean)=$(boot)
diff --git a/arch/sh/boards/adx/Makefile b/arch/sh/boards/adx/Makefile
new file mode 100644
index 000000000000..213d7f8bcfc6
--- /dev/null
+++ b/arch/sh/boards/adx/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for ADX boards
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o irq_maskreq.o
+
diff --git a/arch/sh/kernel/io_adx.c b/arch/sh/boards/adx/io.c
index 9d45dc8b1815..54aa27958959 100644
--- a/arch/sh/kernel/io_adx.c
+++ b/arch/sh/boards/adx/io.c
@@ -173,6 +173,7 @@ void adx_iounmap(void *addr)
EXPORT_SYMBOL(adx_iounmap);
+#ifdef CONFIG_IDE
#include <linux/vmalloc.h>
extern void *cf_io_base;
@@ -190,3 +191,5 @@ unsigned long adx_isa_port2addr(unsigned long offset)
return offset + 0xb0000000; /* IOBUS (AREA 4)*/
}
+#endif
+
diff --git a/arch/sh/boards/adx/irq.c b/arch/sh/boards/adx/irq.c
new file mode 100644
index 000000000000..c6ca409dff98
--- /dev/null
+++ b/arch/sh/boards/adx/irq.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/sh/boards/adx/irq.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * I/O routine and setup routines for A&D ADX Board
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/irq.h>
+
+void init_adx_IRQ(void)
+{
+ int i;
+
+/* printk("init_adx_IRQ()\n");*/
+ /* setup irq_mask_register */
+ irq_mask_register = (unsigned short *)0xa6000008;
+
+ /* cover all external interrupt area by maskreg_irq_type
+ * (Actually, irq15 doesn't exist)
+ */
+ for (i = 0; i < 16; i++) {
+ make_maskreg_irq(i);
+ disable_irq(i);
+ }
+}
diff --git a/arch/sh/kernel/irq_maskreg.c b/arch/sh/boards/adx/irq_maskreg.c
index d793a9bce12a..ca91bb0f1f5c 100644
--- a/arch/sh/kernel/irq_maskreg.c
+++ b/arch/sh/boards/adx/irq_maskreg.c
@@ -65,11 +65,11 @@ static void disable_maskreg_irq(unsigned int irq)
unsigned short val, mask = 0x01 << irq;
/* Set "irq"th bit */
- save_and_cli(flags);
+ local_irq_save(flags);
val = ctrl_inw((unsigned long)irq_mask_register);
val |= mask;
ctrl_outw(val, (unsigned long)irq_mask_register);
- restore_flags(flags);
+ local_irq_restore(flags);
}
}
@@ -80,11 +80,11 @@ static void enable_maskreg_irq(unsigned int irq)
unsigned short val, mask = ~(0x01 << irq);
/* Clear "irq"th bit */
- save_and_cli(flags);
+ local_irq_save(flags);
val = ctrl_inw((unsigned long)irq_mask_register);
val &= mask;
ctrl_outw(val, (unsigned long)irq_mask_register);
- restore_flags(flags);
+ local_irq_restore(flags);
}
}
diff --git a/arch/sh/boards/adx/mach.c b/arch/sh/boards/adx/mach.c
new file mode 100644
index 000000000000..6e95433d7da8
--- /dev/null
+++ b/arch/sh/boards/adx/mach.c
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/sh/kernel/mach_adx.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * This file may be copied or modified under the terms of the GNU
+ * General Public License. See linux/COPYING for more information.
+ *
+ * Machine vector for the A&D ADX Board
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/adx/io.h>
+
+extern void init_adx_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_adx __initmv = {
+ mv_nr_irqs: 48,
+
+ mv_inb: adx_inb,
+ mv_inw: adx_inw,
+ mv_inl: adx_inl,
+ mv_outb: adx_outb,
+ mv_outw: adx_outw,
+ mv_outl: adx_outl,
+
+ mv_inb_p: adx_inb_p,
+ mv_inw_p: adx_inw,
+ mv_inl_p: adx_inl,
+ mv_outb_p: adx_outb_p,
+ mv_outw_p: adx_outw,
+ mv_outl_p: adx_outl,
+
+ mv_insb: adx_insb,
+ mv_insw: adx_insw,
+ mv_insl: adx_insl,
+ mv_outsb: adx_outsb,
+ mv_outsw: adx_outsw,
+ mv_outsl: adx_outsl,
+
+ mv_readb: adx_readb,
+ mv_readw: adx_readw,
+ mv_readl: adx_readl,
+ mv_writeb: adx_writeb,
+ mv_writew: adx_writew,
+ mv_writel: adx_writel,
+
+ mv_ioremap: adx_ioremap,
+ mv_iounmap: adx_iounmap,
+
+ mv_isa_port2addr: adx_isa_port2addr,
+
+ mv_init_irq: init_adx_IRQ,
+
+ mv_hw_adx: 1,
+};
+ALIAS_MV(adx)
diff --git a/arch/sh/boards/adx/setup.c b/arch/sh/boards/adx/setup.c
new file mode 100644
index 000000000000..cce2eb4a6bd1
--- /dev/null
+++ b/arch/sh/boards/adx/setup.c
@@ -0,0 +1,24 @@
+/*
+ * linux/arch/sh/board/adx/setup.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * I/O routine and setup routines for A&D ADX Board
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/machvec.h>
+#include <linux/module.h>
+
+const char *get_system_type(void)
+{
+ return "A&D ADX";
+}
+
+void platform_setup(void)
+{
+}
diff --git a/arch/sh/boards/bigsur/Makefile b/arch/sh/boards/bigsur/Makefile
new file mode 100644
index 000000000000..3b40028fc16e
--- /dev/null
+++ b/arch/sh/boards/bigsur/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the BigSur specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o led.o
+
+obj-$(CONFIG_PCI) += pci.o
+
diff --git a/arch/sh/kernel/io_bigsur.c b/arch/sh/boards/bigsur/io.c
index 15a6f3a3dc2b..a4db9324b19d 100644
--- a/arch/sh/kernel/io_bigsur.c
+++ b/arch/sh/boards/bigsur/io.c
@@ -19,7 +19,7 @@
#include <linux/module.h>
#include <asm/machvec.h>
#include <asm/io.h>
-#include <asm/bigsur.h>
+#include <asm/bigsur/bigsur.h>
//#define BIGSUR_DEBUG 2
#undef BIGSUR_DEBUG
diff --git a/arch/sh/boards/bigsur/irq.c b/arch/sh/boards/bigsur/irq.c
new file mode 100644
index 000000000000..082472448611
--- /dev/null
+++ b/arch/sh/boards/bigsur/irq.c
@@ -0,0 +1,348 @@
+/*
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ *
+ * Setup and IRQ handling code for the HD64465 companion chip.
+ * by Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc
+ *
+ * Derived from setup_hd64465.c which bore the message:
+ * Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc and
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * and setup_cqreek.c which bore message:
+ * Copyright (C) 2000 Niibe Yutaka
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * IRQ functions for a Hitachi Big Sur Evaluation Board.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#include <asm/bigsur/io.h>
+#include <asm/hd64465/hd64465.h>
+#include <asm/bigsur/bigsur.h>
+
+//#define BIGSUR_DEBUG 3
+#undef BIGSUR_DEBUG
+
+#ifdef BIGSUR_DEBUG
+#define DPRINTK(args...) printk(args)
+#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
+#else
+#define DPRINTK(args...)
+#define DIPRINTK(n, args...)
+#endif /* BIGSUR_DEBUG */
+
+#ifdef CONFIG_HD64465
+extern int hd64465_irq_demux(int irq);
+#endif /* CONFIG_HD64465 */
+
+
+/*===========================================================*/
+// Big Sur CPLD IRQ Routines
+/*===========================================================*/
+
+/* Level 1 IRQ routines */
+static void disable_bigsur_l1irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned char mask;
+ unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
+ unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
+
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
+ DPRINTK("Disable L1 IRQ %d\n", irq);
+ DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
+ mask_port, bit);
+ local_irq_save(flags);
+
+ /* Disable IRQ - set mask bit */
+ mask = inb(mask_port) | bit;
+ outb(mask, mask_port);
+ local_irq_restore(flags);
+ return;
+ }
+ DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
+}
+
+static void enable_bigsur_l1irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned char mask;
+ unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
+ unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
+
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
+ DPRINTK("Enable L1 IRQ %d\n", irq);
+ DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
+ mask_port, bit);
+ local_irq_save(flags);
+ /* Enable L1 IRQ - clear mask bit */
+ mask = inb(mask_port) & ~bit;
+ outb(mask, mask_port);
+ local_irq_restore(flags);
+ return;
+ }
+ DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
+}
+
+
+/* Level 2 irq masks and registers for L2 decoding */
+/* Level2 bitmasks for each level 1 IRQ */
+const u32 bigsur_l2irq_mask[] =
+ {0x40,0x80,0x08,0x01,0x01,0x3C,0x3E,0xFF,0x40,0x80,0x06,0x03};
+/* Level2 to ISR[n] map for each level 1 IRQ */
+const u32 bigsur_l2irq_reg[] =
+ { 2, 2, 3, 3, 1, 2, 1, 0, 1, 1, 3, 2};
+/* Level2 to Level 1 IRQ map */
+const u32 bigsur_l2_l1_map[] =
+ {7,7,7,7,7,7,7,7, 4,6,6,6,6,6,8,9, 11,11,5,5,5,5,0,1, 3,10,10,2,-1,-1,-1,-1};
+/* IRQ inactive level (high or low) */
+const u32 bigsur_l2_inactv_state[] = {0x00, 0xBE, 0xFC, 0xF7};
+
+/* CPLD external status and mask registers base and offsets */
+static const u32 isr_base = BIGSUR_IRQ0;
+static const u32 isr_offset = BIGSUR_IRQ0 - BIGSUR_IRQ1;
+static const u32 imr_base = BIGSUR_IMR0;
+static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;
+
+#define REG_NUM(irq) ((irq-BIGSUR_2NDLVL_IRQ_LOW)/8 )
+
+/* Level 2 IRQ routines */
+static void disable_bigsur_l2irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned char mask;
+ unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
+ unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
+
+ if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
+ DPRINTK("Disable L2 IRQ %d\n", irq);
+ DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
+ mask_port, bit);
+ local_irq_save(flags);
+
+ /* Disable L2 IRQ - set mask bit */
+ mask = inb(mask_port) | bit;
+ outb(mask, mask_port);
+ local_irq_restore(flags);
+ return;
+ }
+ DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
+}
+
+static void enable_bigsur_l2irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned char mask;
+ unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
+ unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
+
+ if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
+ DPRINTK("Enable L2 IRQ %d\n", irq);
+ DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
+ mask_port, bit);
+ local_irq_save(flags);
+
+ /* Enable L2 IRQ - clear mask bit */
+ mask = inb(mask_port) & ~bit;
+ outb(mask, mask_port);
+ local_irq_restore(flags);
+ return;
+ }
+ DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
+}
+
+static void mask_and_ack_bigsur(unsigned int irq)
+{
+ DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq);
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
+ disable_bigsur_l1irq(irq);
+ else
+ disable_bigsur_l2irq(irq);
+}
+
+static void end_bigsur_irq(unsigned int irq)
+{
+ DPRINTK("end_bigsur_irq IRQ %d\n", irq);
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
+ enable_bigsur_l1irq(irq);
+ else
+ enable_bigsur_l2irq(irq);
+ }
+}
+
+static unsigned int startup_bigsur_irq(unsigned int irq)
+{
+ u8 mask;
+ u32 reg;
+
+ DPRINTK("startup_bigsur_irq IRQ %d\n", irq);
+
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
+ /* Enable the L1 IRQ */
+ enable_bigsur_l1irq(irq);
+ /* Enable all L2 IRQs in this L1 IRQ */
+ mask = ~(bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW]);
+ reg = imr_base - bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW] * imr_offset;
+ mask &= inb(reg);
+ outb(mask,reg);
+ DIPRINTK(2,"startup_bigsur_irq: IMR=0x%08x mask=0x%x\n",reg,inb(reg));
+ }
+ else {
+ /* Enable the L2 IRQ - clear mask bit */
+ enable_bigsur_l2irq(irq);
+ /* Enable the L1 bit masking this L2 IRQ */
+ enable_bigsur_l1irq(bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW]);
+ DIPRINTK(2,"startup_bigsur_irq: L1=%d L2=%d\n",
+ bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW],irq);
+ }
+ return 0;
+}
+
+static void shutdown_bigsur_irq(unsigned int irq)
+{
+ DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq);
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
+ disable_bigsur_l1irq(irq);
+ else
+ disable_bigsur_l2irq(irq);
+}
+
+/* Define the IRQ structures for the L1 and L2 IRQ types */
+static struct hw_interrupt_type bigsur_l1irq_type = {
+ "BigSur-CPLD-Level1-IRQ",
+ startup_bigsur_irq,
+ shutdown_bigsur_irq,
+ enable_bigsur_l1irq,
+ disable_bigsur_l1irq,
+ mask_and_ack_bigsur,
+ end_bigsur_irq
+};
+
+static struct hw_interrupt_type bigsur_l2irq_type = {
+ "BigSur-CPLD-Level2-IRQ",
+ startup_bigsur_irq,
+ shutdown_bigsur_irq,
+ enable_bigsur_l2irq,
+ disable_bigsur_l2irq,
+ mask_and_ack_bigsur,
+ end_bigsur_irq
+};
+
+
+static void make_bigsur_l1isr(unsigned int irq) {
+
+ /* sanity check first */
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
+ /* save the handler in the main description table */
+ irq_desc[irq].handler = &bigsur_l1irq_type;
+ irq_desc[irq].status = IRQ_DISABLED;
+ irq_desc[irq].action = 0;
+ irq_desc[irq].depth = 1;
+
+ disable_bigsur_l1irq(irq);
+ return;
+ }
+ DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq);
+ return;
+}
+
+static void make_bigsur_l2isr(unsigned int irq) {
+
+ /* sanity check first */
+ if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
+ /* save the handler in the main description table */
+ irq_desc[irq].handler = &bigsur_l2irq_type;
+ irq_desc[irq].status = IRQ_DISABLED;
+ irq_desc[irq].action = 0;
+ irq_desc[irq].depth = 1;
+
+ disable_bigsur_l2irq(irq);
+ return;
+ }
+ DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq);
+ return;
+}
+
+/* The IRQ's will be decoded as follows:
+ * If a level 2 handler exists and there is an unmasked active
+ * IRQ, the 2nd level handler will be called.
+ * If a level 2 handler does not exist for the active IRQ
+ * the 1st level handler will be called.
+ */
+
+int bigsur_irq_demux(int irq)
+{
+ int dmux_irq = irq;
+ u8 mask, actv_irqs;
+ u32 reg_num;
+
+ DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq);
+ /* decode the 1st level IRQ */
+ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
+ /* Get corresponding L2 ISR bitmask and ISR number */
+ mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW];
+ reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW];
+ /* find the active IRQ's (XOR with inactive level)*/
+ actv_irqs = inb(isr_base-reg_num*isr_offset) ^
+ bigsur_l2_inactv_state[reg_num];
+ /* decode active IRQ's */
+ actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset));
+ /* if NEZ then we have an active L2 IRQ */
+ if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW;
+ /* if no 2nd level IRQ action, but has 1st level, use 1st level handler */
+ if(!irq_desc[dmux_irq].action && irq_desc[irq].action)
+ dmux_irq = irq;
+ DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n",
+ irq, dmux_irq, mask, reg_num);
+ }
+#ifdef CONFIG_HD64465
+ dmux_irq = hd64465_irq_demux(dmux_irq);
+#endif /* CONFIG_HD64465 */
+ DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq);
+
+ return dmux_irq;
+}
+
+/*===========================================================*/
+// Big Sur Init Routines
+/*===========================================================*/
+void __init init_bigsur_IRQ(void)
+{
+ int i;
+
+ if (!MACH_BIGSUR) return;
+
+ /* Create ISR's for Big Sur CPLD IRQ's */
+ /*==============================================================*/
+ for(i=BIGSUR_IRQ_LOW;i<BIGSUR_IRQ_HIGH;i++)
+ make_bigsur_l1isr(i);
+
+ printk(KERN_INFO "Big Sur CPLD L1 interrupts %d to %d.\n",
+ BIGSUR_IRQ_LOW,BIGSUR_IRQ_HIGH);
+
+ for(i=BIGSUR_2NDLVL_IRQ_LOW;i<BIGSUR_2NDLVL_IRQ_HIGH;i++)
+ make_bigsur_l2isr(i);
+
+ printk(KERN_INFO "Big Sur CPLD L2 interrupts %d to %d.\n",
+ BIGSUR_2NDLVL_IRQ_LOW,BIGSUR_2NDLVL_IRQ_HIGH);
+
+}
diff --git a/arch/sh/kernel/led_bigsur.c b/arch/sh/boards/bigsur/led.c
index 7155dfa15f7c..0a2339c69440 100644
--- a/arch/sh/kernel/led_bigsur.c
+++ b/arch/sh/boards/bigsur/led.c
@@ -13,7 +13,7 @@
#include <linux/config.h>
#include <asm/io.h>
-#include <asm/bigsur.h>
+#include <asm/bigsur/bigsur.h>
static void mach_led(int position, int value)
{
diff --git a/arch/sh/boards/bigsur/mach.c b/arch/sh/boards/bigsur/mach.c
new file mode 100644
index 000000000000..b8044aa5167f
--- /dev/null
+++ b/arch/sh/boards/bigsur/mach.c
@@ -0,0 +1,72 @@
+/*
+ * linux/arch/sh/kernel/mach_bigsur.c
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ * Derived from mach_se.h, which bore the message:
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi Big Sur Evaluation Board
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/io.h>
+#include <asm/bigsur/io.h>
+#include <asm/irq.h>
+
+/*
+ * The Machine Vector
+ */
+extern void heartbeat_bigsur(void);
+extern void init_bigsur_IRQ(void);
+
+struct sh_machine_vector mv_bigsur __initmv = {
+ mv_nr_irqs: NR_IRQS, // Defined in <asm/irq.h>
+ mv_inb: bigsur_inb,
+ mv_inw: bigsur_inw,
+ mv_inl: bigsur_inl,
+ mv_outb: bigsur_outb,
+ mv_outw: bigsur_outw,
+ mv_outl: bigsur_outl,
+
+ mv_inb_p: bigsur_inb_p,
+ mv_inw_p: bigsur_inw,
+ mv_inl_p: bigsur_inl,
+ mv_outb_p: bigsur_outb_p,
+ mv_outw_p: bigsur_outw,
+ mv_outl_p: bigsur_outl,
+
+ mv_insb: bigsur_insb,
+ mv_insw: bigsur_insw,
+ mv_insl: bigsur_insl,
+ mv_outsb: bigsur_outsb,
+ mv_outsw: bigsur_outsw,
+ mv_outsl: bigsur_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+
+ mv_isa_port2addr: bigsur_isa_port2addr,
+ mv_irq_demux: bigsur_irq_demux,
+
+ mv_init_irq: init_bigsur_IRQ,
+#ifdef CONFIG_HEARTBEAT
+ mv_heartbeat: heartbeat_bigsur,
+#endif
+
+};
+ALIAS_MV(bigsur)
diff --git a/arch/sh/kernel/pci-bigsur.c b/arch/sh/boards/bigsur/pci.c
index cc1eacdbf5d0..228befcc8c44 100644
--- a/arch/sh/kernel/pci-bigsur.c
+++ b/arch/sh/boards/bigsur/pci.c
@@ -18,7 +18,7 @@
#include <asm/io.h>
#include <asm/pci-sh7751.h>
-#include <asm/bigsur.h>
+#include <asm/bigsur/bigsur.h>
#define PCI_REG(reg) (SH7751_PCIREG_BASE+reg)
diff --git a/arch/sh/boards/bigsur/setup.c b/arch/sh/boards/bigsur/setup.c
new file mode 100644
index 000000000000..5c66cf6b7da0
--- /dev/null
+++ b/arch/sh/boards/bigsur/setup.c
@@ -0,0 +1,94 @@
+/*
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ *
+ * Setup and IRQ handling code for the HD64465 companion chip.
+ * by Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc
+ *
+ * Derived from setup_hd64465.c which bore the message:
+ * Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc and
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * and setup_cqreek.c which bore message:
+ * Copyright (C) 2000 Niibe Yutaka
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Setup functions for a Hitachi Big Sur Evaluation Board.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#include <asm/bigsur/io.h>
+#include <asm/hd64465/hd64465.h>
+#include <asm/bigsur/bigsur.h>
+
+//#define BIGSUR_DEBUG 3
+#undef BIGSUR_DEBUG
+
+#ifdef BIGSUR_DEBUG
+#define DPRINTK(args...) printk(args)
+#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
+#else
+#define DPRINTK(args...)
+#define DIPRINTK(n, args...)
+#endif /* BIGSUR_DEBUG */
+
+/*===========================================================*/
+// Big Sur Init Routines
+/*===========================================================*/
+
+const char *get_system_type(void)
+{
+ return "Big Sur";
+}
+
+int __init platform_setup(void)
+{
+ static int done = 0; /* run this only once */
+
+ if (!MACH_BIGSUR || done) return 0;
+ done = 1;
+
+ /* Mask all 2nd level IRQ's */
+ outb(-1,BIGSUR_IMR0);
+ outb(-1,BIGSUR_IMR1);
+ outb(-1,BIGSUR_IMR2);
+ outb(-1,BIGSUR_IMR3);
+
+ /* Mask 1st level interrupts */
+ outb(-1,BIGSUR_IRLMR0);
+ outb(-1,BIGSUR_IRLMR1);
+
+#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL)
+ /* remap IO ports for first ISA serial port to HD64465 UART */
+ bigsur_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
+#endif /* CONFIG_HD64465 && CONFIG_SERIAL */
+ /* TODO: setup IDE registers */
+ bigsur_port_map(BIGSUR_IDECTL_IOPORT, 2, BIGSUR_ICTL, 8);
+ /* Setup the Ethernet port to BIGSUR_ETHER_IOPORT */
+ bigsur_port_map(BIGSUR_ETHER_IOPORT, 16, BIGSUR_ETHR+BIGSUR_ETHER_IOPORT, 0);
+ /* set page to 1 */
+ outw(1, BIGSUR_ETHR+0xe);
+ /* set the IO port to BIGSUR_ETHER_IOPORT */
+ outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
+
+ return 0;
+}
+
+module_init(setup_bigsur);
diff --git a/arch/sh/boards/cat68701/Makefile b/arch/sh/boards/cat68701/Makefile
new file mode 100644
index 000000000000..48105f39c788
--- /dev/null
+++ b/arch/sh/boards/cat68701/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the CAT-68701 specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o
+
diff --git a/arch/sh/kernel/io_cat68701.c b/arch/sh/boards/cat68701/io.c
index f2ae2d4c7bc4..596a8c26acc5 100644
--- a/arch/sh/kernel/io_cat68701.c
+++ b/arch/sh/boards/cat68701/io.c
@@ -1,10 +1,10 @@
/*
- * linux/arch/sh/kernel/io_cat68701.c
+ * linux/arch/sh/boards/cat68701/io.c
*
* Copyright (C) 2000 Niibe Yutaka
* 2001 Yutaro Ebihara
*
- * I/O routine and setup routines for A-ONE Corp CAT-68701 SH7708 Board
+ * I/O routines for A-ONE Corp CAT-68701 SH7708 Board
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -205,45 +205,3 @@ unsigned long cat68701_isa_port2addr(unsigned long offset)
return offset + 0xb4000000; /* other I/O (EREA 5)*/
}
-
-int cat68701_irq_demux(int irq)
-{
- if(irq==13) return 14;
- if(irq==7) return 10;
- return irq;
-}
-
-
-
-/*-------------------------------------------------------*/
-
-void setup_cat68701(){
- /* dummy read erea5 (CS8900A) */
-}
-
-void init_cat68701_IRQ(){
- make_imask_irq(10);
- make_imask_irq(14);
-}
-
-#ifdef CONFIG_HEARTBEAT
-#include <linux/sched.h>
-void heartbeat_cat68701()
-{
- static unsigned int cnt = 0, period = 0 , bit = 0;
- cnt += 1;
- if (cnt < period) {
- return;
- }
- cnt = 0;
-
- /* Go through the points (roughly!):
- * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
- */
- period = 110 - ( (300<<FSHIFT)/
- ((avenrun[0]/5) + (3<<FSHIFT)) );
-
- if(bit){ bit=0; }else{ bit=1; }
- outw(bit<<15,0x3fe);
-}
-#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/cat68701/irq.c b/arch/sh/boards/cat68701/irq.c
new file mode 100644
index 000000000000..f9a6d185fb8b
--- /dev/null
+++ b/arch/sh/boards/cat68701/irq.c
@@ -0,0 +1,28 @@
+/*
+ * linux/arch/sh/boards/cat68701/irq.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ * 2001 Yutaro Ebihara
+ *
+ * Setup routines for A-ONE Corp CAT-68701 SH7708 Board
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/irq.h>
+
+int cat68701_irq_demux(int irq)
+{
+ if(irq==13) return 14;
+ if(irq==7) return 10;
+ return irq;
+}
+
+void init_cat68701_IRQ()
+{
+ make_imask_irq(10);
+ make_imask_irq(14);
+}
diff --git a/arch/sh/boards/cat68701/mach.c b/arch/sh/boards/cat68701/mach.c
new file mode 100644
index 000000000000..7d739c7bb0fe
--- /dev/null
+++ b/arch/sh/boards/cat68701/mach.c
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/sh/boards/cat68701/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ * 2001 Yutaro Ebihara (ebihara@si-linux.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the A-ONE corp. CAT-68701 SH7708 board
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/cat68701/io.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_cat68701 __initmv = {
+ mv_nr_irqs: 32,
+ mv_inb: cat68701_inb,
+ mv_inw: cat68701_inw,
+ mv_inl: cat68701_inl,
+ mv_outb: cat68701_outb,
+ mv_outw: cat68701_outw,
+ mv_outl: cat68701_outl,
+
+ mv_inb_p: cat68701_inb_p,
+ mv_inw_p: cat68701_inw,
+ mv_inl_p: cat68701_inl,
+ mv_outb_p: cat68701_outb_p,
+ mv_outw_p: cat68701_outw,
+ mv_outl_p: cat68701_outl,
+
+ mv_insb: cat68701_insb,
+ mv_insw: cat68701_insw,
+ mv_insl: cat68701_insl,
+ mv_outsb: cat68701_outsb,
+ mv_outsw: cat68701_outsw,
+ mv_outsl: cat68701_outsl,
+
+ mv_readb: cat68701_readb,
+ mv_readw: cat68701_readw,
+ mv_readl: cat68701_readl,
+ mv_writeb: cat68701_writeb,
+ mv_writew: cat68701_writew,
+ mv_writel: cat68701_writel,
+
+ mv_ioremap: cat68701_ioremap,
+ mv_iounmap: cat68701_iounmap,
+
+ mv_isa_port2addr: cat68701_isa_port2addr,
+ mv_irq_demux: cat68701_irq_demux,
+
+ mv_init_irq: init_cat68701_IRQ,
+#ifdef CONFIG_HEARTBEAT
+ mv_heartbeat: heartbeat_cat68701,
+#endif
+};
+ALIAS_MV(cat68701)
diff --git a/arch/sh/boards/cat68701/setup.c b/arch/sh/boards/cat68701/setup.c
new file mode 100644
index 000000000000..c20b1160a365
--- /dev/null
+++ b/arch/sh/boards/cat68701/setup.c
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/sh/boards/cat68701/setup.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ * 2001 Yutaro Ebihara
+ *
+ * Setup routines for A-ONE Corp CAT-68701 SH7708 Board
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <linux/config.h>
+#include <linux/module.h>
+
+const char *get_system_type(void)
+{
+ return "CAT-68701";
+}
+
+void platform_setup()
+{
+ /* dummy read erea5 (CS8900A) */
+}
+
+#ifdef CONFIG_HEARTBEAT
+#include <linux/sched.h>
+void heartbeat_cat68701()
+{
+ static unsigned int cnt = 0, period = 0 , bit = 0;
+ cnt += 1;
+ if (cnt < period) {
+ return;
+ }
+ cnt = 0;
+
+ /* Go through the points (roughly!):
+ * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
+ */
+ period = 110 - ( (300<<FSHIFT)/
+ ((avenrun[0]/5) + (3<<FSHIFT)) );
+
+ if(bit){ bit=0; }else{ bit=1; }
+ outw(bit<<15,0x3fe);
+}
+#endif /* CONFIG_HEARTBEAT */
+
diff --git a/arch/sh/boards/cqreek/Makefile b/arch/sh/boards/cqreek/Makefile
new file mode 100644
index 000000000000..501dc840f87f
--- /dev/null
+++ b/arch/sh/boards/cqreek/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the CqREEK specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o
+
diff --git a/arch/sh/boards/cqreek/io.c b/arch/sh/boards/cqreek/io.c
new file mode 100644
index 000000000000..2c5bc38ba0da
--- /dev/null
+++ b/arch/sh/boards/cqreek/io.c
@@ -0,0 +1,14 @@
+#define IDE_OFFSET 0xA4000000UL
+#define ISA_OFFSET 0xA4A00000UL
+
+unsigned long cqreek_port2addr(unsigned long port)
+{
+ if (0x0000<=port && port<=0x0040)
+ return IDE_OFFSET + port;
+ if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
+ return IDE_OFFSET + port;
+
+ return ISA_OFFSET + port;
+}
+
+
diff --git a/arch/sh/boards/cqreek/irq.c b/arch/sh/boards/cqreek/irq.c
new file mode 100644
index 000000000000..fa6cfe5a20a7
--- /dev/null
+++ b/arch/sh/boards/cqreek/irq.c
@@ -0,0 +1,128 @@
+/* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $
+ *
+ * arch/sh/boards/cqreek/irq.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ *
+ * CqREEK IDE/ISA Bridge Support.
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/init.h>
+
+#include <asm/cqreek/cqreek.h>
+#include <asm/io.h>
+#include <asm/io_generic.h>
+#include <asm/irq.h>
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+#include <asm/rtc.h>
+
+struct cqreek_irq_data {
+ unsigned short mask_port; /* Port of Interrupt Mask Register */
+ unsigned short stat_port; /* Port of Interrupt Status Register */
+ unsigned short bit; /* Value of the bit */
+};
+static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
+
+static void disable_cqreek_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short mask;
+ unsigned short mask_port = cqreek_irq_data[irq].mask_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
+
+ local_irq_save(flags);
+ /* Disable IRQ */
+ mask = inw(mask_port) & ~bit;
+ outw_p(mask, mask_port);
+ local_irq_restore(flags);
+}
+
+static void enable_cqreek_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short mask;
+ unsigned short mask_port = cqreek_irq_data[irq].mask_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
+
+ local_irq_save(flags);
+ /* Enable IRQ */
+ mask = inw(mask_port) | bit;
+ outw_p(mask, mask_port);
+ local_irq_restore(flags);
+}
+
+static void mask_and_ack_cqreek(unsigned int irq)
+{
+ unsigned short stat_port = cqreek_irq_data[irq].stat_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
+
+ disable_cqreek_irq(irq);
+ /* Clear IRQ (it might be edge IRQ) */
+ inw(stat_port);
+ outw_p(bit, stat_port);
+}
+
+static void end_cqreek_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_cqreek_irq(irq);
+}
+
+static unsigned int startup_cqreek_irq(unsigned int irq)
+{
+ enable_cqreek_irq(irq);
+ return 0;
+}
+
+static void shutdown_cqreek_irq(unsigned int irq)
+{
+ disable_cqreek_irq(irq);
+}
+
+static struct hw_interrupt_type cqreek_irq_type = {
+ "CqREEK-IRQ",
+ startup_cqreek_irq,
+ shutdown_cqreek_irq,
+ enable_cqreek_irq,
+ disable_cqreek_irq,
+ mask_and_ack_cqreek,
+ end_cqreek_irq
+};
+
+int cqreek_has_ide, cqreek_has_isa;
+
+/* XXX: This is just for test for my NE2000 ISA board
+ What we really need is virtualized IRQ and demultiplexer like HP600 port */
+void __init init_cqreek_IRQ(void)
+{
+ if (cqreek_has_ide) {
+ cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
+ cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
+ cqreek_irq_data[14].bit = 1;
+
+ irq_desc[14].handler = &cqreek_irq_type;
+ irq_desc[14].status = IRQ_DISABLED;
+ irq_desc[14].action = 0;
+ irq_desc[14].depth = 1;
+
+ disable_cqreek_irq(14);
+ }
+
+ if (cqreek_has_isa) {
+ cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
+ cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
+ cqreek_irq_data[10].bit = (1 << 10);
+
+ /* XXX: Err... we may need demultiplexer for ISA irq... */
+ irq_desc[10].handler = &cqreek_irq_type;
+ irq_desc[10].status = IRQ_DISABLED;
+ irq_desc[10].action = 0;
+ irq_desc[10].depth = 1;
+
+ disable_cqreek_irq(10);
+ }
+}
+
diff --git a/arch/sh/boards/cqreek/mach.c b/arch/sh/boards/cqreek/mach.c
new file mode 100644
index 000000000000..938113f9b49a
--- /dev/null
+++ b/arch/sh/boards/cqreek/mach.c
@@ -0,0 +1,66 @@
+/* $Id: mach.c,v 1.1.2.4.2.1 2003/01/10 17:26:32 lethal Exp $
+ *
+ * arch/sh/kernel/setup_cqreek.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ *
+ * CqREEK IDE/ISA Bridge Support.
+ *
+ */
+
+#include <asm/rtc.h>
+#include <asm/io.h>
+#include <asm/io_generic.h>
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+#include <asm/cqreek/cqreek.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_cqreek __initmv = {
+#if defined(CONFIG_CPU_SH4)
+ mv_nr_irqs: 48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+ mv_nr_irqs: 32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+ mv_nr_irqs: 61,
+#endif
+
+ mv_inb: generic_inb,
+ mv_inw: generic_inw,
+ mv_inl: generic_inl,
+ mv_outb: generic_outb,
+ mv_outw: generic_outw,
+ mv_outl: generic_outl,
+
+ mv_inb_p: generic_inb_p,
+ mv_inw_p: generic_inw_p,
+ mv_inl_p: generic_inl_p,
+ mv_outb_p: generic_outb_p,
+ mv_outw_p: generic_outw_p,
+ mv_outl_p: generic_outl_p,
+
+ mv_insb: generic_insb,
+ mv_insw: generic_insw,
+ mv_insl: generic_insl,
+ mv_outsb: generic_outsb,
+ mv_outsw: generic_outsw,
+ mv_outsl: generic_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_init_irq: init_cqreek_IRQ,
+
+ mv_isa_port2addr: cqreek_port2addr,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+};
+ALIAS_MV(cqreek)
diff --git a/arch/sh/boards/cqreek/setup.c b/arch/sh/boards/cqreek/setup.c
new file mode 100644
index 000000000000..c20e00997eaa
--- /dev/null
+++ b/arch/sh/boards/cqreek/setup.c
@@ -0,0 +1,69 @@
+/* $Id: setup.c,v 1.1.2.5 2002/03/02 21:57:07 lethal Exp $
+ *
+ * arch/sh/kernel/setup_cqreek.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ *
+ * CqREEK IDE/ISA Bridge Support.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/cqreek/cqreek.h>
+#include <asm/io.h>
+#include <asm/io_generic.h>
+#include <asm/irq.h>
+#include <asm/rtc.h>
+
+const char *get_system_type(void)
+{
+ return "CqREEK";
+}
+
+/*
+ * Initialize the board
+ */
+void __init platform_setup(void)
+{
+ int i;
+/* udelay is not available at setup time yet... */
+#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
+
+ if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
+ outw_p(0, BRIDGE_IDE_INTR_LVL);
+ outw_p(0, BRIDGE_IDE_INTR_MASK);
+
+ outw_p(0, BRIDGE_IDE_CTRL);
+ DELAY();
+
+ outw_p(0x8000, BRIDGE_IDE_CTRL);
+ DELAY();
+
+ outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
+ outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
+ outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
+ cqreek_has_ide=1;
+ }
+
+ if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
+ outw_p(0, BRIDGE_ISA_INTR_LVL);
+ outw_p(0, BRIDGE_ISA_INTR_MASK);
+
+ outw_p(0, BRIDGE_ISA_CTRL);
+ DELAY();
+ outw_p(0x8000, BRIDGE_ISA_CTRL);
+ DELAY();
+
+ outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
+ outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
+ outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
+ cqreek_has_isa=1;
+ }
+
+ printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", cqreek_has_ide, cqreek_has_isa);
+}
+
diff --git a/arch/sh/boards/dmida/Makefile b/arch/sh/boards/dmida/Makefile
new file mode 100644
index 000000000000..9609809c8cc8
--- /dev/null
+++ b/arch/sh/boards/dmida/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts
+# of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o
+
diff --git a/arch/sh/boards/dmida/mach.c b/arch/sh/boards/dmida/mach.c
new file mode 100644
index 000000000000..e6aeae4a37f8
--- /dev/null
+++ b/arch/sh/boards/dmida/mach.c
@@ -0,0 +1,73 @@
+/*
+ * linux/arch/sh/kernel/mach_dmida.c
+ *
+ * by Greg Banks <gbanks@pocketpenguins.com>
+ * (c) 2000 PocketPenguins Inc
+ *
+ * Derived from mach_hp600.c, which bore the message:
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the DataMyte Industrial Digital Assistant(tm).
+ * See http://www.dmida.com
+ *
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io.h>
+#include <asm/hd64465/hd64465.h>
+#include <asm/irq.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_dmida __initmv = {
+ mv_name: "DMIDA",
+
+ mv_nr_irqs: HD64465_IRQ_BASE+HD64465_IRQ_NUM,
+
+ mv_inb: hd64465_inb,
+ mv_inw: hd64465_inw,
+ mv_inl: hd64465_inl,
+ mv_outb: hd64465_outb,
+ mv_outw: hd64465_outw,
+ mv_outl: hd64465_outl,
+
+ mv_inb_p: hd64465_inb_p,
+ mv_inw_p: hd64465_inw,
+ mv_inl_p: hd64465_inl,
+ mv_outb_p: hd64465_outb_p,
+ mv_outw_p: hd64465_outw,
+ mv_outl_p: hd64465_outl,
+
+ mv_insb: hd64465_insb,
+ mv_insw: hd64465_insw,
+ mv_insl: hd64465_insl,
+ mv_outsb: hd64465_outsb,
+ mv_outsw: hd64465_outsw,
+ mv_outsl: hd64465_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_irq_demux: hd64465_irq_demux,
+
+ mv_rtc_gettimeofday: sh_rtc_gettimeofday,
+ mv_rtc_settimeofday: sh_rtc_settimeofday,
+
+ mv_hw_hd64465: 1,
+};
+ALIAS_MV(dmida)
+
diff --git a/arch/sh/boards/dreamcast/Makefile b/arch/sh/boards/dreamcast/Makefile
new file mode 100644
index 000000000000..09ccf1d9c14b
--- /dev/null
+++ b/arch/sh/boards/dreamcast/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the Sega Dreamcast specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o rtc.o
+
+obj-$(CONFIG_PCI) += pci.o
+
diff --git a/arch/sh/kernel/io_dc.c b/arch/sh/boards/dreamcast/io.c
index 9d27dc938ada..757d65de4d39 100644
--- a/arch/sh/kernel/io_dc.c
+++ b/arch/sh/boards/dreamcast/io.c
@@ -1,5 +1,5 @@
/*
- * $Id: io_dc.c,v 1.2 2001/05/24 00:13:47 gniibe Exp $
+ * $Id: io.c,v 1.1.2.1 2002/01/19 23:54:19 mrbrown Exp $
* I/O routines for SEGA Dreamcast
*/
diff --git a/arch/sh/boards/dreamcast/irq.c b/arch/sh/boards/dreamcast/irq.c
new file mode 100644
index 000000000000..ce83502b7ab0
--- /dev/null
+++ b/arch/sh/boards/dreamcast/irq.c
@@ -0,0 +1,160 @@
+/*
+ * arch/sh/boards/dreamcast/irq.c
+ *
+ * Holly IRQ support for the Sega Dreamcast.
+ *
+ * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
+ *
+ * This file is part of the LinuxDC project (www.linuxdc.org)
+ * Released under the terms of the GNU GPL v2.0
+ */
+
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/dreamcast/sysasic.h>
+
+/* Dreamcast System ASIC Hardware Events -
+
+ The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
+ hardware events from system peripherals and triggering an SH7750 IRQ.
+ Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
+ set in the Event Mask Registers (EMRs). When a hardware event is
+ triggered, it's corresponding bit in the Event Status Registers (ESRs)
+ is set, and that bit should be rewritten to the ESR to acknowledge that
+ event.
+
+ There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event
+ types can be found in include/asm-sh/dc_sysasic.h. There are three groups
+ of EMRs that parallel the ESRs. Each EMR group corresponds to an IRQ, so
+ 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers
+ IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
+
+ In the kernel, these events are mapped to virtual IRQs so that drivers can
+ respond to them as they would a normal interrupt. In order to keep this
+ mapping simple, the events are mapped as:
+
+ 6900/6910 - Events 0-31, IRQ 13
+ 6904/6924 - Events 32-63, IRQ 11
+ 6908/6938 - Events 64-95, IRQ 9
+
+*/
+
+#define ESR_BASE 0x005f6900 /* Base event status register */
+#define EMR_BASE 0x005f6910 /* Base event mask register */
+
+/* Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
+ 1 = 0x6920, 2 = 0x6930; also determine the event offset */
+#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
+
+/* Return the hardware event's bit positon within the EMR/ESR */
+#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
+
+/* For each of these *_irq routines, the IRQ passed in is the virtual IRQ
+ (logically mapped to the corresponding bit for the hardware event). */
+
+/* Disable the hardware event by masking its bit in its EMR */
+static inline void disable_systemasic_irq(unsigned int irq)
+{
+ unsigned long flags;
+ __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+ __u32 mask;
+
+ local_irq_save(flags);
+ mask = inl(emr);
+ mask &= ~(1 << EVENT_BIT(irq));
+ outl(mask, emr);
+ local_irq_restore(flags);
+}
+
+/* Enable the hardware event by setting its bit in its EMR */
+static inline void enable_systemasic_irq(unsigned int irq)
+{
+ unsigned long flags;
+ __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
+ __u32 mask;
+
+ local_irq_save(flags);
+ mask = inl(emr);
+ mask |= (1 << EVENT_BIT(irq));
+ outl(mask, emr);
+ local_irq_restore(flags);
+}
+
+/* Acknowledge a hardware event by writing its bit back to its ESR */
+static void ack_systemasic_irq(unsigned int irq)
+{
+ __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
+ disable_systemasic_irq(irq);
+ outl((1 << EVENT_BIT(irq)), esr);
+}
+
+/* After a IRQ has been ack'd and responded to, it needs to be renabled */
+static void end_systemasic_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_systemasic_irq(irq);
+}
+
+static unsigned int startup_systemasic_irq(unsigned int irq)
+{
+ enable_systemasic_irq(irq);
+
+ return 0;
+}
+
+static void shutdown_systemasic_irq(unsigned int irq)
+{
+ disable_systemasic_irq(irq);
+}
+
+struct hw_interrupt_type systemasic_int = {
+ typename: "System ASIC",
+ startup: startup_systemasic_irq,
+ shutdown: shutdown_systemasic_irq,
+ enable: enable_systemasic_irq,
+ disable: disable_systemasic_irq,
+ ack: ack_systemasic_irq,
+ end: end_systemasic_irq,
+};
+
+/*
+ * Map the hardware event indicated by the processor IRQ to a virtual IRQ.
+ */
+int systemasic_irq_demux(int irq)
+{
+ __u32 emr, esr, status, level;
+ __u32 j, bit;
+
+ switch (irq) {
+ case 13:
+ level = 0;
+ break;
+ case 11:
+ level = 1;
+ break;
+ case 9:
+ level = 2;
+ break;
+ default:
+ return irq;
+ }
+ emr = EMR_BASE + (level << 4) + (level << 2);
+ esr = ESR_BASE + (level << 2);
+
+ /* Mask the ESR to filter any spurious, unwanted interrtupts */
+ status = inl(esr);
+ status &= inl(emr);
+
+ /* Now scan and find the first set bit as the event to map */
+ for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
+ if (status & bit) {
+ irq = HW_EVENT_IRQ_BASE + j + (level << 5);
+ return irq;
+ }
+ }
+
+ /* Not reached */
+ return irq;
+}
diff --git a/arch/sh/boards/dreamcast/mach.c b/arch/sh/boards/dreamcast/mach.c
new file mode 100644
index 000000000000..0f1c45d59980
--- /dev/null
+++ b/arch/sh/boards/dreamcast/mach.c
@@ -0,0 +1,62 @@
+/*
+ * $Id: mach.c,v 1.1.2.5 2002/03/01 11:22:17 lethal Exp $
+ * SEGA Dreamcast machine vector
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/time.h>
+
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_generic.h>
+#include <asm/dreamcast/io.h>
+#include <asm/irq.h>
+
+void __init dreamcast_pcibios_init(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_dreamcast __initmv = {
+ mv_nr_irqs: NR_IRQS,
+
+ mv_inb: generic_inb,
+ mv_inw: generic_inw,
+ mv_inl: generic_inl,
+ mv_outb: generic_outb,
+ mv_outw: generic_outw,
+ mv_outl: generic_outl,
+
+ mv_inb_p: generic_inb_p,
+ mv_inw_p: generic_inw,
+ mv_inl_p: generic_inl,
+ mv_outb_p: generic_outb_p,
+ mv_outw_p: generic_outw,
+ mv_outl_p: generic_outl,
+
+ mv_insb: generic_insb,
+ mv_insw: generic_insw,
+ mv_insl: generic_insl,
+ mv_outsb: generic_outsb,
+ mv_outsw: generic_outsw,
+ mv_outsl: generic_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+
+ mv_isa_port2addr: dreamcast_isa_port2addr,
+ mv_irq_demux: systemasic_irq_demux,
+
+ mv_hw_dreamcast: 1,
+};
+ALIAS_MV(dreamcast)
diff --git a/arch/sh/kernel/pci-dc.c b/arch/sh/boards/dreamcast/pci.c
index ed3bcf26f810..c520f829c91a 100644
--- a/arch/sh/kernel/pci-dc.c
+++ b/arch/sh/boards/dreamcast/pci.c
@@ -1,5 +1,5 @@
/*
- $ $Id: pci-dc.c,v 1.5 2001/08/24 12:38:19 dwmw2 Exp $
+ $ $Id: pci.c,v 1.1.2.4.2.1 2003/03/31 14:33:18 lethal Exp $
* Dreamcast PCI: Supports SEGA Broadband Adaptor only.
*/
@@ -14,7 +14,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/dc_sysasic.h>
+#include <asm/dreamcast/sysasic.h>
#define GAPSPCI_REGS 0x01001400
#define GAPSPCI_DMA_BASE 0x01840000
@@ -25,7 +25,26 @@
static int gapspci_dma_used;
-static struct pci_bus *pci_root_bus;
+/* XXX: Uh... */
+static struct resource gapspci_io_resource = {
+ "GAPSPCI IO",
+ 0x01001600,
+ 0x010016ff,
+ IORESOURCE_IO
+};
+
+static struct resource gapspci_mem_resource = {
+ "GAPSPCI mem",
+ 0x01840000,
+ 0x01847fff,
+ IORESOURCE_MEM
+};
+
+static struct pci_ops gapspci_pci_ops;
+struct pci_channel board_pci_channels[] = {
+ {&gapspci_pci_ops, &gapspci_io_resource, &gapspci_mem_resource, 0, 1},
+ {NULL, NULL, NULL, 0, 0},
+};
struct pci_fixup pcibios_fixups[] = {
{0, 0, 0, NULL}
@@ -39,23 +58,23 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int
case 1:
if (BBA_SELECTED(bus, devfn))
*val = (u8)inb(GAPSPCI_BBA_CONFIG+where);
- else
+ else
*val = (u8)0xff;
break;
case 2:
if (BBA_SELECTED(bus, devfn))
*val = (u16)inw(GAPSPCI_BBA_CONFIG+where);
- else
+ else
*val = (u16)0xffff;
break;
case 4:
if (BBA_SELECTED(bus, devfn))
- *val = inl(GAPSPCI_BBA_CONFIG+where);
- else
- *val = 0xffffffff;
+ *val = inl(GAPSPCI_BBA_CONFIG+where);
+ else
+ *val = 0xffffffff;
break;
}
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_SUCCESSFUL;
}
static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
@@ -72,14 +91,14 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int
break;
case 4:
if (BBA_SELECTED(bus, devfn))
- outl(val, GAPSPCI_BBA_CONFIG+where);
+ outl(val, GAPSPCI_BBA_CONFIG+where);
break;
}
}
- return PCIBIOS_SUCCESSFUL;
+ return PCIBIOS_SUCCESSFUL;
}
-static struct pci_ops pci_config_ops = {
+static struct pci_ops gapspci_pci_ops = {
.read = gapspci_read,
.write = gapspci_write,
};
@@ -122,7 +141,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
dev = pci_dev_b(ln);
if (!BBA_SELECTED(bus, dev->devfn)) continue;
- printk("PCI: MMIO fixup to %s\n", dev->name);
+ printk("PCI: MMIO fixup to %s\n", dev->dev.name);
dev->resource[1].start=0x01001700;
dev->resource[1].end=0x010017ff;
}
@@ -140,22 +159,13 @@ static int __init map_dc_irq(struct pci_dev *dev, u8 slot, u8 pin)
return GAPSPCI_IRQ;
}
+void __init pcibios_fixup(void) { /* Do nothing. */ }
-void __init pcibios_init(void)
+void __init pcibios_fixup_irqs(void)
{
- pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
- /* pci_assign_unassigned_resources(); */
pci_fixup_irqs(no_swizzle, map_dc_irq);
}
-
-/* Haven't done anything here as yet */
-char * __init pcibios_setup(char *str)
-{
- return str;
-}
-
-
int __init gapspci_init(void)
{
int i;
@@ -196,3 +206,9 @@ int __init gapspci_init(void)
return 0;
}
+
+/* Haven't done anything here as yet */
+char * __devinit pcibios_setup(char *str)
+{
+ return str;
+}
diff --git a/arch/sh/kernel/rtc-aica.c b/arch/sh/boards/dreamcast/rtc.c
index 25563c65ed0f..110094272e76 100644
--- a/arch/sh/kernel/rtc-aica.c
+++ b/arch/sh/boards/dreamcast/rtc.c
@@ -2,7 +2,8 @@
*
* Dreamcast AICA RTC routines.
*
- * Copyright (c) 2001 M. R. Brown <mrbrown@0xd6.org>
+ * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
+ * Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org>
*
* Released under the terms of the GNU GPL v2.0.
*
@@ -12,6 +13,9 @@
#include <asm/io.h>
+extern void (*rtc_get_time)(struct timespec *);
+extern int (*rtc_set_time)(const time_t);
+
/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
seconds to get the standard Unix Epoch when getting the time, and add 20
years when setting the time. */
@@ -28,7 +32,7 @@
*
* Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
*/
-void aica_rtc_gettimeofday(struct timeval *tv) {
+void aica_rtc_gettimeofday(struct timespec *ts) {
unsigned long val1, val2;
do {
@@ -39,10 +43,10 @@ void aica_rtc_gettimeofday(struct timeval *tv) {
(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
} while (val1 != val2);
- tv->tv_sec = val1 - TWENTY_YEARS;
+ ts->tv_sec = val1 - TWENTY_YEARS;
- /* Can't get microseconds with just a seconds counter. */
- tv->tv_usec = 0;
+ /* Can't get nanoseconds with just a seconds counter. */
+ ts->tv_nsec = 0;
}
/**
@@ -51,13 +55,13 @@ void aica_rtc_gettimeofday(struct timeval *tv) {
*
* Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
*/
-int aica_rtc_settimeofday(const struct timeval *tv) {
+int aica_rtc_settimeofday(const time_t secs) {
unsigned long val1, val2;
- unsigned long secs = tv->tv_sec + TWENTY_YEARS;
+ unsigned long adj = secs + TWENTY_YEARS;
do {
- ctrl_outl((secs & 0xffff0000) >> 16, AICA_RTC_SECS_H);
- ctrl_outl((secs & 0xffff), AICA_RTC_SECS_L);
+ ctrl_outl((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
+ ctrl_outl((adj & 0xffff), AICA_RTC_SECS_L);
val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
@@ -68,3 +72,10 @@ int aica_rtc_settimeofday(const struct timeval *tv) {
return 0;
}
+
+void aica_time_init(void)
+{
+ rtc_get_time = aica_rtc_gettimeofday;
+ rtc_set_time = aica_rtc_settimeofday;
+}
+
diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c
new file mode 100644
index 000000000000..506009fb7d54
--- /dev/null
+++ b/arch/sh/boards/dreamcast/setup.c
@@ -0,0 +1,64 @@
+/* arch/sh/kernel/setup_dc.c
+ *
+ * Hardware support for the Sega Dreamcast.
+ *
+ * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@linuxdc.org>
+ * Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org>
+ *
+ * This file is part of the LinuxDC project (www.linuxdc.org)
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ * This file originally bore the message (with enclosed-$):
+ * Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
+ * SEGA Dreamcast support
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/dreamcast/sysasic.h>
+
+extern struct hw_interrupt_type systemasic_int;
+/* XXX: Move this into it's proper header. */
+extern void (*board_time_init)(void);
+extern void aica_time_init(void);
+
+const char *get_system_type(void)
+{
+ return "Sega Dreamcast";
+}
+
+#ifdef CONFIG_PCI
+extern int gapspci_init(void);
+#endif
+
+int __init platform_setup(void)
+{
+ int i;
+
+ /* Mask all hardware events */
+ /* XXX */
+
+ /* Acknowledge any previous events */
+ /* XXX */
+
+ /* Assign all virtual IRQs to the System ASIC int. handler */
+ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
+ irq_desc[i].handler = &systemasic_int;
+
+ board_time_init = aica_time_init;
+
+#ifdef CONFIG_PCI
+ if (gapspci_init() < 0)
+ printk(KERN_WARNING "GAPSPCI was not detected.\n");
+#endif
+
+ return 0;
+}
diff --git a/arch/sh/boards/ec3104/Makefile b/arch/sh/boards/ec3104/Makefile
new file mode 100644
index 000000000000..584c46279f42
--- /dev/null
+++ b/arch/sh/boards/ec3104/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the EC3104 specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o
+
diff --git a/arch/sh/kernel/io_ec3104.c b/arch/sh/boards/ec3104/io.c
index f3cbf9b5b1c7..a70928c44753 100644
--- a/arch/sh/kernel/io_ec3104.c
+++ b/arch/sh/boards/ec3104/io.c
@@ -18,7 +18,7 @@
#include <linux/types.h>
#include <asm/io.h>
#include <asm/page.h>
-#include <asm/ec3104.h>
+#include <asm/ec3104/ec3104.h>
/*
* EC3104 has a real ISA bus which we redirect low port accesses to (the
diff --git a/arch/sh/boards/ec3104/irq.c b/arch/sh/boards/ec3104/irq.c
new file mode 100644
index 000000000000..f933e4fd2810
--- /dev/null
+++ b/arch/sh/boards/ec3104/irq.c
@@ -0,0 +1,196 @@
+/*
+ * linux/arch/sh/boards/ec3104/irq.c
+ * EC3104 companion chip support
+ *
+ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ec3104/ec3104.h>
+
+/* This is for debugging mostly; here's the table that I intend to keep
+ * in here:
+ *
+ * index function base addr power interrupt bit
+ * 0 power b0ec0000 --- 00000001 (unused)
+ * 1 irqs b0ec1000 --- 00000002 (unused)
+ * 2 ?? b0ec2000 b0ec0008 00000004
+ * 3 PS2 (1) b0ec3000 b0ec000c 00000008
+ * 4 PS2 (2) b0ec4000 b0ec0010 00000010
+ * 5 ?? b0ec5000 b0ec0014 00000020
+ * 6 I2C b0ec6000 b0ec0018 00000040
+ * 7 serial (1) b0ec7000 b0ec001c 00000080
+ * 8 serial (2) b0ec8000 b0ec0020 00000100
+ * 9 serial (3) b0ec9000 b0ec0024 00000200
+ * 10 serial (4) b0eca000 b0ec0028 00000400
+ * 12 GPIO (1) b0ecc000 b0ec0030
+ * 13 GPIO (2) b0ecc000 b0ec0030
+ * 16 pcmcia (1) b0ed0000 b0ec0040 00010000
+ * 17 pcmcia (2) b0ed1000 b0ec0044 00020000
+ */
+
+/* I used the register names from another interrupt controller I worked with,
+ * since it seems to be identical to the ec3104 except that all bits are
+ * inverted:
+ *
+ * IRR: Interrupt Request Register (pending and enabled interrupts)
+ * IMR: Interrupt Mask Register (which interrupts are enabled)
+ * IPR: Interrupt Pending Register (pending interrupts, even disabled ones)
+ *
+ * 0 bits mean pending or enabled, 1 bits mean not pending or disabled. all
+ * IRQs seem to be level-triggered.
+ */
+
+#define EC3104_IRR (EC3104_BASE + 0x1000)
+#define EC3104_IMR (EC3104_BASE + 0x1004)
+#define EC3104_IPR (EC3104_BASE + 0x1008)
+
+#define ctrl_readl(addr) (*(volatile u32 *)(addr))
+#define ctrl_writel(data,addr) (*(volatile u32 *)(addr) = (data))
+#define ctrl_readb(addr) (*(volatile u8 *)(addr))
+
+static char *ec3104_name(unsigned index)
+{
+ switch(index) {
+ case 0:
+ return "power management";
+ case 1:
+ return "interrupts";
+ case 3:
+ return "PS2 (1)";
+ case 4:
+ return "PS2 (2)";
+ case 5:
+ return "I2C (1)";
+ case 6:
+ return "I2C (2)";
+ case 7:
+ return "serial (1)";
+ case 8:
+ return "serial (2)";
+ case 9:
+ return "serial (3)";
+ case 10:
+ return "serial (4)";
+ case 16:
+ return "pcmcia (1)";
+ case 17:
+ return "pcmcia (2)";
+ default: {
+ static char buf[32];
+
+ sprintf(buf, "unknown (%d)", index);
+
+ return buf;
+ }
+ }
+}
+
+int get_pending_interrupts(char *buf)
+{
+ u32 ipr;
+ u32 bit;
+ char *p = buf;
+
+ p += sprintf(p, "pending: (");
+
+ ipr = ctrl_inl(EC3104_IPR);
+
+ for (bit = 1; bit < 32; bit++)
+ if (!(ipr & (1<<bit)))
+ p += sprintf(p, "%s ", ec3104_name(bit));
+
+ p += sprintf(p, ")\n");
+
+ return p - buf;
+}
+
+static inline u32 ec3104_irq2mask(unsigned int irq)
+{
+ return (1 << (irq - EC3104_IRQBASE));
+}
+
+static inline void mask_ec3104_irq(unsigned int irq)
+{
+ u32 mask;
+
+ mask = ctrl_readl(EC3104_IMR);
+
+ mask |= ec3104_irq2mask(irq);
+
+ ctrl_writel(mask, EC3104_IMR);
+}
+
+static inline void unmask_ec3104_irq(unsigned int irq)
+{
+ u32 mask;
+
+ mask = ctrl_readl(EC3104_IMR);
+
+ mask &= ~ec3104_irq2mask(irq);
+
+ ctrl_writel(mask, EC3104_IMR);
+}
+
+static void disable_ec3104_irq(unsigned int irq)
+{
+ mask_ec3104_irq(irq);
+}
+
+static void enable_ec3104_irq(unsigned int irq)
+{
+ unmask_ec3104_irq(irq);
+}
+
+static void mask_and_ack_ec3104_irq(unsigned int irq)
+{
+ mask_ec3104_irq(irq);
+}
+
+static void end_ec3104_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ unmask_ec3104_irq(irq);
+}
+
+static unsigned int startup_ec3104_irq(unsigned int irq)
+{
+ unmask_ec3104_irq(irq);
+
+ return 0;
+}
+
+static void shutdown_ec3104_irq(unsigned int irq)
+{
+ mask_ec3104_irq(irq);
+
+}
+
+static struct hw_interrupt_type ec3104_int = {
+ typename: "EC3104",
+ enable: enable_ec3104_irq,
+ disable: disable_ec3104_irq,
+ ack: mask_and_ack_ec3104_irq,
+ end: end_ec3104_irq,
+ startup: startup_ec3104_irq,
+ shutdown: shutdown_ec3104_irq,
+};
+
+/* Yuck. the _demux API is ugly */
+int ec3104_irq_demux(int irq)
+{
+ if (irq == EC3104_IRQ) {
+ unsigned int mask;
+
+ mask = ctrl_readl(EC3104_IRR);
+
+ if (mask == 0xffffffff)
+ return EC3104_IRQ;
+ else
+ return EC3104_IRQBASE + ffz(mask);
+ }
+
+ return irq;
+}
diff --git a/arch/sh/boards/ec3104/mach.c b/arch/sh/boards/ec3104/mach.c
new file mode 100644
index 000000000000..3c10b9baeb9d
--- /dev/null
+++ b/arch/sh/boards/ec3104/mach.c
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/sh/kernel/mach_ec3104.c
+ * EC3104 companion chip support
+ *
+ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ *
+ */
+/* EC3104 note:
+ * This code was written without any documentation about the EC3104 chip. While
+ * I hope I got most of the basic functionality right, the register names I use
+ * are most likely completely different from those in the chip documentation.
+ *
+ * If you have any further information about the EC3104, please tell me
+ * (prumpf@tux.org).
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_ec3104 __initmv = {
+ mv_name: "EC3104",
+
+ mv_nr_irqs: 96,
+
+ mv_inb: ec3104_inb,
+ mv_inw: ec3104_inw,
+ mv_inl: ec3104_inl,
+ mv_outb: ec3104_outb,
+ mv_outw: ec3104_outw,
+ mv_outl: ec3104_outl,
+
+ mv_inb_p: generic_inb_p,
+ mv_inw_p: generic_inw,
+ mv_inl_p: generic_inl,
+ mv_outb_p: generic_outb_p,
+ mv_outw_p: generic_outw,
+ mv_outl_p: generic_outl,
+
+ mv_insb: generic_insb,
+ mv_insw: generic_insw,
+ mv_insl: generic_insl,
+ mv_outsb: generic_outsb,
+ mv_outsw: generic_outsw,
+ mv_outsl: generic_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_irq_demux: ec3104_irq_demux,
+
+ mv_rtc_gettimeofday: sh_rtc_gettimeofday,
+ mv_rtc_settimeofday: sh_rtc_settimeofday,
+};
+
+ALIAS_MV(ec3104)
diff --git a/arch/sh/boards/ec3104/setup.c b/arch/sh/boards/ec3104/setup.c
new file mode 100644
index 000000000000..8a30603d3290
--- /dev/null
+++ b/arch/sh/boards/ec3104/setup.c
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/sh/boards/ec3104/setup.c
+ * EC3104 companion chip support
+ *
+ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ *
+ */
+/* EC3104 note:
+ * This code was written without any documentation about the EC3104 chip. While
+ * I hope I got most of the basic functionality right, the register names I use
+ * are most likely completely different from those in the chip documentation.
+ *
+ * If you have any further information about the EC3104, please tell me
+ * (prumpf@tux.org).
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ec3104/ec3104.h>
+
+int __init setup_ec3104(void)
+{
+ char str[8];
+ int i;
+
+ if (!MACH_EC3104)
+ printk("!MACH_EC3104\n");
+
+ if (0)
+ return 0;
+
+ for (i=0; i<8; i++)
+ str[i] = ctrl_readb(EC3104_BASE + i);
+
+ for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
+ irq_desc[i].handler = &ec3104_int;
+
+ printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
+ str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
+
+
+ /* mask all interrupts. this should have been done by the boot
+ * loader for us but we want to be sure ... */
+ ctrl_writel(0xffffffff, EC3104_IMR);
+
+ return 0;
+}
+
+module_init(setup_ec3104);
diff --git a/arch/sh/boards/harp/Makefile b/arch/sh/boards/harp/Makefile
new file mode 100644
index 000000000000..236aad34880a
--- /dev/null
+++ b/arch/sh/boards/harp/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for STMicroelectronics board specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := irq.o setup.o mach.o led.o
+
+obj-$(CONFIG_PCI) += pcidma.o
+
diff --git a/arch/sh/stboards/irq.c b/arch/sh/boards/harp/irq.c
index 46e3ba9b5f18..acd58489970f 100644
--- a/arch/sh/stboards/irq.c
+++ b/arch/sh/boards/harp/irq.c
@@ -15,8 +15,7 @@
#include <asm/system.h>
#include <asm/io.h>
-
-#include "harp.h"
+#include <asm/harp/harp.h>
#define NUM_EXTERNAL_IRQS 16
@@ -68,14 +67,14 @@ static void disable_harp_irq(unsigned int irq)
pri -= 8;
}
- save_and_cli(flags);
+ local_irq_save(flags);
mask = ctrl_inl(maskReg);
mask &= (~(1 << pri));
#if defined(INVERT_INTMASK_WRITES)
mask ^= 0xff;
#endif
ctrl_outl(mask, maskReg);
- restore_flags(flags);
+ local_irq_restore(flags);
}
static void enable_harp_irq(unsigned int irq)
@@ -97,7 +96,7 @@ static void enable_harp_irq(unsigned int irq)
pri -= 8;
}
- save_and_cli(flags);
+ local_irq_save(flags);
mask = ctrl_inl(maskReg);
@@ -108,7 +107,7 @@ static void enable_harp_irq(unsigned int irq)
#endif
ctrl_outl(mask, maskReg);
- restore_flags(flags);
+ local_irq_restore(flags);
}
/* This functions sets the desired irq handler to be an overdrive type */
diff --git a/arch/sh/stboards/led.c b/arch/sh/boards/harp/led.c
index f7831e53ad9d..76ca4ccac703 100644
--- a/arch/sh/stboards/led.c
+++ b/arch/sh/boards/harp/led.c
@@ -11,7 +11,7 @@
#include <linux/config.h>
#include <asm/io.h>
-#include "harp.h"
+#include <asm/harp/harp.h>
/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */
/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */
diff --git a/arch/sh/boards/harp/mach.c b/arch/sh/boards/harp/mach.c
new file mode 100644
index 000000000000..abcb3652256c
--- /dev/null
+++ b/arch/sh/boards/harp/mach.c
@@ -0,0 +1,72 @@
+/*
+ * linux/arch/sh/stboards/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the STMicroelectronics STB1 HARP and compatible boards
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/hd64465.h/io.h>
+#include <asm/hd64465/hd64465.h>
+
+void setup_harp(void);
+void init_harp_irq(void);
+void heartbeat_harp(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_harp __initmv = {
+ mv_nr_irqs: 89 + HD64465_IRQ_NUM,
+
+ mv_inb: hd64465_inb,
+ mv_inw: hd64465_inw,
+ mv_inl: hd64465_inl,
+ mv_outb: hd64465_outb,
+ mv_outw: hd64465_outw,
+ mv_outl: hd64465_outl,
+
+ mv_inb_p: hd64465_inb_p,
+ mv_inw_p: hd64465_inw,
+ mv_inl_p: hd64465_inl,
+ mv_outb_p: hd64465_outb_p,
+ mv_outw_p: hd64465_outw,
+ mv_outl_p: hd64465_outl,
+
+ mv_insb: hd64465_insb,
+ mv_insw: hd64465_insw,
+ mv_insl: hd64465_insl,
+ mv_outsb: hd64465_outsb,
+ mv_outsw: hd64465_outsw,
+ mv_outsl: hd64465_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+
+ mv_isa_port2addr: hd64465_isa_port2addr,
+
+#ifdef CONFIG_PCI
+ mv_init_irq: init_harp_irq,
+#endif
+#ifdef CONFIG_HEARTBEAT
+ mv_heartbeat: heartbeat_harp,
+#endif
+};
+
+ALIAS_MV(harp)
diff --git a/arch/sh/stboards/pcidma.c b/arch/sh/boards/harp/pcidma.c
index bbaaded9cff5..475311390fd6 100644
--- a/arch/sh/stboards/pcidma.c
+++ b/arch/sh/boards/harp/pcidma.c
@@ -24,7 +24,7 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret != NULL) {
- /* Is it necessary to do the memset? */
+ /* Is it neccessary to do the memset? */
memset(ret, 0, size);
*dma_handle = virt_to_bus(ret);
}
diff --git a/arch/sh/stboards/setup.c b/arch/sh/boards/harp/setup.c
index 1d3a484a8189..0d64b28b0c36 100644
--- a/arch/sh/stboards/setup.c
+++ b/arch/sh/boards/harp/setup.c
@@ -13,11 +13,17 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
-#include "harp.h"
+#include <asm/harp/harp.h>
+
+const char *get_system_type(void)
+{
+ return "STB1 Harp";
+}
+
/*
* Initialize the board
*/
-int __init setup_harp(void)
+int __init platform_setup(void)
{
#ifdef CONFIG_SH_STB1_HARP
unsigned long ic8_version, ic36_version;
diff --git a/arch/sh/boards/hp6xx/hp620/Makefile b/arch/sh/boards/hp6xx/hp620/Makefile
new file mode 100644
index 000000000000..6e22814c6a7b
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp620/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HP620 specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o
+
diff --git a/arch/sh/boards/hp6xx/hp620/mach.c b/arch/sh/boards/hp6xx/hp620/mach.c
new file mode 100644
index 000000000000..c530e6bd5067
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp620/mach.c
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/sh/boards/hp6xx/hp620/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the HP620
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io.h>
+#include <asm/hd64461/hd64461.h>
+#include <asm/irq.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_hp620 __initmv = {
+ mv_name: "hp620",
+
+ mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM,
+
+ mv_inb: hd64461_inb,
+ mv_inw: hd64461_inw,
+ mv_inl: hd64461_inl,
+ mv_outb: hd64461_outb,
+ mv_outw: hd64461_outw,
+ mv_outl: hd64461_outl,
+
+ mv_inb_p: hd64461_inb_p,
+ mv_inw_p: hd64461_inw,
+ mv_inl_p: hd64461_inl,
+ mv_outb_p: hd64461_outb_p,
+ mv_outw_p: hd64461_outw,
+ mv_outl_p: hd64461_outl,
+
+ mv_insb: hd64461_insb,
+ mv_insw: hd64461_insw,
+ mv_insl: hd64461_insl,
+ mv_outsb: hd64461_outsb,
+ mv_outsw: hd64461_outsw,
+ mv_outsl: hd64461_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_irq_demux: hd64461_irq_demux,
+
+ mv_rtc_gettimeofday: sh_rtc_gettimeofday,
+ mv_rtc_settimeofday: sh_rtc_settimeofday,
+
+ mv_hw_hp600: 1,
+ mv_hw_hp620: 1,
+ mv_hw_hd64461: 1,
+};
+ALIAS_MV(hp620)
diff --git a/arch/sh/boards/hp6xx/hp680/Makefile b/arch/sh/boards/hp6xx/hp680/Makefile
new file mode 100644
index 000000000000..0470c0284a13
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp680/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HP680 specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o
+
diff --git a/arch/sh/boards/hp6xx/hp680/mach.c b/arch/sh/boards/hp6xx/hp680/mach.c
new file mode 100644
index 000000000000..17441b3f7882
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp680/mach.c
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/sh/boards/hp6xx/hp680/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the HP680
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io.h>
+#include <asm/hd64461/hd64461.h>
+#include <asm/irq.h>
+
+struct sh_machine_vector mv_hp680 __initmv = {
+ mv_name: "hp680",
+
+ mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM,
+
+ mv_inb: hd64461_inb,
+ mv_inw: hd64461_inw,
+ mv_inl: hd64461_inl,
+ mv_outb: hd64461_outb,
+ mv_outw: hd64461_outw,
+ mv_outl: hd64461_outl,
+
+ mv_inb_p: hd64461_inb_p,
+ mv_inw_p: hd64461_inw,
+ mv_inl_p: hd64461_inl,
+ mv_outb_p: hd64461_outb_p,
+ mv_outw_p: hd64461_outw,
+ mv_outl_p: hd64461_outl,
+
+ mv_insb: hd64461_insb,
+ mv_insw: hd64461_insw,
+ mv_insl: hd64461_insl,
+ mv_outsb: hd64461_outsb,
+ mv_outsw: hd64461_outsw,
+ mv_outsl: hd64461_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_irq_demux: hd64461_irq_demux,
+
+ mv_rtc_gettimeofday: sh_rtc_gettimeofday,
+ mv_rtc_settimeofday: sh_rtc_settimeofday,
+
+ mv_hw_hp600: 1,
+ mv_hw_hp680: 1,
+ mv_hw_hd64461: 1,
+};
+ALIAS_MV(hp680)
diff --git a/arch/sh/boards/hp6xx/hp690/Makefile b/arch/sh/boards/hp6xx/hp690/Makefile
new file mode 100644
index 000000000000..3b9dd10b9971
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp690/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HP690 specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o
+
diff --git a/arch/sh/boards/hp6xx/hp690/mach.c b/arch/sh/boards/hp6xx/hp690/mach.c
new file mode 100644
index 000000000000..dd6ac73b15ff
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp690/mach.c
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/sh/boards/hp6xx/hp690/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the HP690
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io.h>
+#include <asm/hd64461/hd64461.h>
+#include <asm/irq.h>
+
+struct sh_machine_vector mv_hp690 __initmv = {
+ mv_name: "hp690",
+
+ mv_nr_irqs: HD64461_IRQBASE+HD64461_IRQ_NUM,
+
+ mv_inb: hd64461_inb,
+ mv_inw: hd64461_inw,
+ mv_inl: hd64461_inl,
+ mv_outb: hd64461_outb,
+ mv_outw: hd64461_outw,
+ mv_outl: hd64461_outl,
+
+ mv_inb_p: hd64461_inb_p,
+ mv_inw_p: hd64461_inw,
+ mv_inl_p: hd64461_inl,
+ mv_outb_p: hd64461_outb_p,
+ mv_outw_p: hd64461_outw,
+ mv_outl_p: hd64461_outl,
+
+ mv_insb: hd64461_insb,
+ mv_insw: hd64461_insw,
+ mv_insl: hd64461_insl,
+ mv_outsb: hd64461_outsb,
+ mv_outsw: hd64461_outsw,
+ mv_outsl: hd64461_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_irq_demux: hd64461_irq_demux,
+
+ mv_rtc_gettimeofday: sh_rtc_gettimeofday,
+ mv_rtc_settimeofday: sh_rtc_settimeofday,
+
+ mv_hw_hp600: 1,
+ mv_hw_hp690: 1,
+ mv_hw_hd64461: 1,
+};
+ALIAS_MV(hp690)
diff --git a/arch/sh/boards/overdrive/Makefile b/arch/sh/boards/overdrive/Makefile
new file mode 100644
index 000000000000..aeab557f44ef
--- /dev/null
+++ b/arch/sh/boards/overdrive/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the STMicroelectronics Overdrive specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o led.o time.o
+
+obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o
+
diff --git a/arch/sh/boards/overdrive/fpga.c b/arch/sh/boards/overdrive/fpga.c
new file mode 100644
index 000000000000..3a1ec9403441
--- /dev/null
+++ b/arch/sh/boards/overdrive/fpga.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * This file handles programming up the Altera Flex10K that interfaces to
+ * the Galileo, and does the PS/2 keyboard and mouse
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+
+#include <asm/overdriver/gt64111.h>
+#include <asm/overdrive/overdrive.h>
+#include <asm/overdrive/fpga.h>
+
+#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT
+#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK
+
+/* I need to find out what (if any) the real delay factor here is */
+/* The delay is definately not critical */
+#define long_delay() {int i;for(i=0;i<10000;i++);}
+#define short_delay() {int i;for(i=0;i<100;i++);}
+
+static void __init program_overdrive_fpga(const unsigned char *fpgacode,
+ int size)
+{
+ int timeout = 0;
+ int i, j;
+ unsigned char b;
+ static volatile unsigned char *FPGA_ControlReg =
+ (volatile unsigned char *) (OVERDRIVE_CTRL);
+ static volatile unsigned char *FPGA_ProgramReg =
+ (volatile unsigned char *) (FPGA_DCLK_ADDRESS);
+
+ printk("FPGA: Commencing FPGA Programming\n");
+
+ /* The PCI reset but MUST be low when programming the FPGA !!! */
+ b = (*FPGA_ControlReg) & RESET_PCI_MASK;
+
+ (*FPGA_ControlReg) = b;
+
+ /* Prepare FPGA to program */
+
+ FPGA_NotConfigHigh();
+ long_delay();
+
+ FPGA_NotConfigLow();
+ short_delay();
+
+ while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) {
+ printk("FPGA: Waiting for NotStatus to go Low ... \n");
+ }
+
+ FPGA_NotConfigHigh();
+
+ /* Wait for FPGA "ready to be programmed" signal */
+ printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n");
+
+ for (timeout = 0;
+ (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0)
+ && (timeout < FPGA_TIMEOUT)); timeout++);
+
+ /* Check if timeout condition occured - i.e. an error */
+
+ if (timeout == FPGA_TIMEOUT) {
+ printk
+ ("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n");
+ return;
+ }
+
+ printk("FPGA: Copying data to FPGA ... %d bytes\n", size);
+
+ /* Copy array to FPGA - bit at a time */
+
+ for (i = 0; i < size; i++) {
+ volatile unsigned w = 0;
+
+ for (j = 0; j < 8; j++) {
+ *FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01;
+ short_delay();
+ }
+ if ((i & 0x3ff) == 0) {
+ printk(".");
+ }
+ }
+
+ /* Waiting for CONFDONE to go high - means the program is complete */
+
+ for (timeout = 0;
+ (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0)
+ && (timeout < FPGA_TIMEOUT)); timeout++) {
+
+ *FPGA_ProgramReg = 0x0;
+ long_delay();
+ }
+
+ if (timeout == FPGA_TIMEOUT) {
+ printk
+ ("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n");
+ return;
+ } else { /* Clock another 10 times - gets the device into a working state */
+ for (i = 0; i < 10; i++) {
+ *FPGA_ProgramReg = 0x0;
+ short_delay();
+ }
+ }
+
+ printk("FPGA: Programming complete\n");
+}
+
+
+static const unsigned char __init fpgacode[] = {
+#include "./overdrive.ttf" /* Code from maxplus2 compiler */
+ , 0, 0
+};
+
+
+int __init init_overdrive_fpga(void)
+{
+ program_overdrive_fpga(fpgacode, sizeof(fpgacode));
+
+ return 0;
+}
diff --git a/arch/sh/boards/overdrive/galileo.c b/arch/sh/boards/overdrive/galileo.c
new file mode 100644
index 000000000000..64ac57e53087
--- /dev/null
+++ b/arch/sh/boards/overdrive/galileo.c
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * This file contains the PCI routines required for the Galileo GT6411
+ * PCI bridge as used on the Orion and Overdrive boards.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+
+#include <asm/overdrive/overdrive.h>
+#include <asm/overdrive/gt64111.h>
+
+
+/* After boot, we shift the Galileo registers so that they appear
+ * in BANK6, along with IO space. This means we can have one contingous
+ * lump of PCI address space without these registers appearing in the
+ * middle of them
+ */
+
+#define GT64111_BASE_ADDRESS 0xbb000000
+#define GT64111_IO_BASE_ADDRESS 0x1000
+/* The GT64111 registers appear at this address to the SH4 after reset */
+#define RESET_GT64111_BASE_ADDRESS 0xb4000000
+
+/* Macros used to access the Galileo registers */
+#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x)
+#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x)
+
+#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x))
+
+#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x))
+
+#define GT_WRITE(x,v) writel((v),GT64111_REG(x))
+#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x))
+#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x))
+
+#define GT_READ(x) readl(GT64111_REG(x))
+#define GT_READ_BYTE(x) readb(GT64111_REG(x))
+#define GT_READ_SHORT(x) readw(GT64111_REG(x))
+
+
+/* Where the various SH banks start at */
+#define SH_BANK4_ADR 0xb0000000
+#define SH_BANK5_ADR 0xb4000000
+#define SH_BANK6_ADR 0xb8000000
+
+/* Masks out everything but lines 28,27,26 */
+#define BANK_SELECT_MASK 0x1c000000
+
+#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK)
+
+/*
+ * Masks used for address conversaion. Bank 6 is used for IO and
+ * has all the address bits zeroed by the FPGA. Special case this
+ */
+#define MEMORY_BANK_MASK 0x1fffffff
+#define IO_BANK_MASK 0x03ffffff
+
+/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code
+ * if you want
+ */
+#define IO_BANK_ADR PCI_GTIO_BASE
+
+/* Will select the correct mask to apply depending on the SH$ address */
+#define SELECT_BANK_MASK(x) \
+ ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK)
+
+/* Converts between PCI space and P2 region */
+#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x))
+
+/* Various macros for figuring out what to stick in the Galileo registers.
+ * You *really* don't want to figure this stuff out by hand, you always get
+ * it wrong
+ */
+#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff)
+#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f)
+#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff)
+
+#define PROGRAM_HI_LO(block,a,s) \
+ GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\
+ GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1))
+
+#define PROGRAM_SUB_HI_LO(block,a,s) \
+ GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\
+ GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1))
+
+/* We need to set the size, and the offset register */
+
+#define GT_BAR_MASK(x) ((x)&~0xfff)
+
+/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */
+#define PROGRAM_GT_BAR(block,a,s) \
+ GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\
+ write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\
+ GT_BAR_MASK(a))
+
+#define DISABLE_GT_BAR(block) \
+ GT_WRITE(PCI_##block##_BANK_SIZE,0),\
+ GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\
+ 0x80000000)
+
+/* Macros to disable things we are not going to use */
+#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\
+ GT_WRITE(x##_HI_DEC_ADR,0x00)
+
+#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\
+ GT_WRITE(x##_HI_DEC_ADR,0x00)
+
+static void __init reset_pci(void)
+{
+ /* Set RESET_PCI bit high */
+ writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
+ udelay(250);
+
+ /* Set RESET_PCI bit low */
+ writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL);
+ udelay(250);
+
+ writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
+ udelay(250);
+}
+
+static int write_config_to_galileo(int where, u32 val);
+#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val)
+
+#define ENABLE_PCI_DRAM
+
+
+#ifdef TEST_DRAM
+/* Test function to check out if the PCI DRAM is working OK */
+static int /* __init */ test_dram(unsigned *base, unsigned size)
+{
+ unsigned *p = base;
+ unsigned *end = (unsigned *) (((unsigned) base) + size);
+ unsigned w;
+
+ for (p = base; p < end; p++) {
+ *p = 0xffffffff;
+ if (*p != 0xffffffff) {
+ printk("AAARGH -write failed!!! at %p is %x\n", p,
+ *p);
+ return 0;
+ }
+ *p = 0x0;
+ if (*p != 0x0) {
+ printk("AAARGH -write failed!!!\n");
+ return 0;
+ }
+ }
+
+ for (p = base; p < end; p++) {
+ *p = (unsigned) p;
+ if (*p != (unsigned) p) {
+ printk("Failed at 0x%p, actually is 0x%x\n", p,
+ *p);
+ return 0;
+ }
+ }
+
+ for (p = base; p < end; p++) {
+ w = ((unsigned) p & 0xffff0000);
+ *p = w | (w >> 16);
+ }
+
+ for (p = base; p < end; p++) {
+ w = ((unsigned) p & 0xffff0000);
+ w |= (w >> 16);
+ if (*p != w) {
+ printk
+ ("Failed at 0x%p, should be 0x%x actually is 0x%x\n",
+ p, w, *p);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+#endif
+
+
+/* Function to set up and initialise the galileo. This sets up the BARS,
+ * maps the DRAM into the address space etc,etc
+ */
+int __init galileo_init(void)
+{
+ reset_pci();
+
+ /* Now shift the galileo regs into this block */
+ RESET_GT_WRITE(INTERNAL_SPACE_DEC,
+ GT_MEM_LO_ADR(GT64111_BASE_ADDRESS));
+
+ /* Should have a sanity check here, that you can read back at the new
+ * address what you just wrote
+ */
+
+ /* Disable decode for all regions */
+ DISABLE_DECODE(RAS10);
+ DISABLE_DECODE(RAS32);
+ DISABLE_DECODE(CS20);
+ DISABLE_DECODE(CS3);
+ DISABLE_DECODE(PCI_IO);
+ DISABLE_DECODE(PCI_MEM0);
+ DISABLE_DECODE(PCI_MEM1);
+
+ /* Disable all BARS */
+ GT_WRITE(BAR_ENABLE_ADR, 0x1ff);
+ DISABLE_GT_BAR(RAS10);
+ DISABLE_GT_BAR(RAS32);
+ DISABLE_GT_BAR(CS20);
+ DISABLE_GT_BAR(CS3);
+
+ /* Tell the BAR where the IO registers now are */
+ GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK(
+ (GT64111_IO_BASE_ADDRESS &
+ IO_BANK_MASK)));
+ /* set up a 112 Mb decode */
+ PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024);
+
+ /* Set up a 32 MB io space decode */
+ PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024);
+
+#ifdef ENABLE_PCI_DRAM
+ /* Program up the DRAM configuration - there is DRAM only in bank 0 */
+ /* Now set up the DRAM decode */
+ PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE);
+ /* And the sub decode */
+ PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE);
+
+ DISABLE_SUB_DECODE(RAS1);
+
+ /* Set refresh rate */
+ GT_WRITE(DRAM_BANK0_PARMS, 0x3f);
+ GT_WRITE(DRAM_CFG, 0x100);
+
+ /* we have to lob off the top bits rememeber!! */
+ PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE);
+
+#endif
+
+ /* We are only interested in decoding RAS10 and the Galileo's internal
+ * registers (as IO) on the PCI bus
+ */
+#ifdef ENABLE_PCI_DRAM
+ GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff);
+#else
+ GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff);
+#endif
+
+ /* Change the class code to host bridge, it actually powers up
+ * as a memory controller
+ */
+ GT_CONFIG_WRITE(8, 0x06000011);
+
+ /* Allow the galileo to master the PCI bus */
+ GT_CONFIG_WRITE(PCI_COMMAND,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_IO);
+
+
+#if 0
+ printk("Testing PCI DRAM - ");
+ if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
+ printk("Passed\n");
+ }else {
+ printk("FAILED\n");
+ }
+#endif
+ return 0;
+
+}
+
+
+#define SET_CONFIG_BITS(bus,devfn,where)\
+ ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3))
+
+#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
+
+/* This write to the galileo config registers, unlike the functions below, can
+ * be used before the PCI subsystem has started up
+ */
+static int __init write_config_to_galileo(int where, u32 val)
+{
+ GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where));
+
+ GT_WRITE(PCI_CFG_DATA, val);
+ return 0;
+}
+
+/* We exclude the galileo and slot 31, the galileo because I don't know how to stop
+ * the setup code shagging up the setup I have done on it, and 31 because the whole
+ * thing locks up if you try to access that slot (which doesn't exist of course anyway
+ */
+
+#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31)))
+
+static int galileo_read_config_byte(struct pci_dev *dev, int where,
+ u8 * val)
+{
+
+
+ /* I suspect this doesn't work because this drives a special cycle ? */
+ if (EXCLUDED_DEV(dev)) {
+ *val = 0xff;
+ return PCIBIOS_SUCCESSFUL;
+ }
+ /* Start the config cycle */
+ GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+ /* Read back the result */
+ *val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3));
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_read_config_word(struct pci_dev *dev, int where,
+ u16 * val)
+{
+
+ if (EXCLUDED_DEV(dev)) {
+ *val = 0xffff;
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+ *val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2));
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_read_config_dword(struct pci_dev *dev, int where,
+ u32 * val)
+{
+ if (EXCLUDED_DEV(dev)) {
+ *val = 0xffffffff;
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+ *val = GT_READ(PCI_CFG_DATA);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_write_config_byte(struct pci_dev *dev, int where,
+ u8 val)
+{
+ GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+
+ GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_write_config_word(struct pci_dev *dev, int where,
+ u16 val)
+{
+ GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+
+ GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_write_config_dword(struct pci_dev *dev, int where,
+ u32 val)
+{
+ GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+
+ GT_WRITE(PCI_CFG_DATA, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_config_ops = {
+ galileo_read_config_byte,
+ galileo_read_config_word,
+ galileo_read_config_dword,
+ galileo_write_config_byte,
+ galileo_write_config_word,
+ galileo_write_config_dword
+};
+
+
+/* Everything hangs off this */
+static struct pci_bus *pci_root_bus;
+
+
+static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+{
+ return PCI_SLOT(dev->devfn);
+}
+
+static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ /* Slot 1: Galileo
+ * Slot 2: PCI Slot 1
+ * Slot 3: PCI Slot 2
+ * Slot 4: ESS
+ */
+ switch (slot) {
+ case 2:
+ return OVERDRIVE_PCI_IRQ1;
+ case 3:
+ /* Note this assumes you have a hacked card in slot 2 */
+ return OVERDRIVE_PCI_IRQ2;
+ case 4:
+ return OVERDRIVE_ESS_IRQ;
+ default:
+ /* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */
+ return -1;
+ }
+}
+
+
+
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+ ranges->io_start -= bus->resource[0]->start;
+ ranges->io_end -= bus->resource[0]->start;
+ ranges->mem_start -= bus->resource[1]->start;
+ ranges->mem_end -= bus->resource[1]->start;
+}
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+ int i;
+
+ /*
+ * PCI IDE controllers use non-standard I/O port decoding, respect it.
+ */
+ if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+ return;
+ printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+ for(i=0; i<4; i++) {
+ struct resource *r = &d->resource[i];
+ if ((r->start & ~0x80) == 0x374) {
+ r->start |= 2;
+ r->end = r->start;
+ }
+ }
+}
+
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
+ { 0 }
+};
+
+void __init pcibios_init(void)
+{
+ static struct resource galio,galmem;
+
+ /* Allocate the registers used by the Galileo */
+ galio.flags = IORESOURCE_IO;
+ galio.name = "Galileo GT64011";
+ galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH;
+ galmem.name = "Galileo GT64011 DRAM";
+
+ allocate_resource(&ioport_resource, &galio, 256,
+ GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL);
+ allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE,
+ PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE,
+ PCI_DRAM_SIZE, NULL, NULL);
+
+ /* ok, do the scan man */
+ pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+
+ pci_assign_unassigned_resources();
+ pci_fixup_irqs(no_swizzle, map_od_irq);
+
+#ifdef TEST_DRAM
+ printk("Testing PCI DRAM - ");
+ if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
+ printk("Passed\n");
+ }else {
+ printk("FAILED\n");
+ }
+#endif
+
+}
+
+char * __init pcibios_setup(char *str)
+{
+ return str;
+}
+
+
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for (idx = 0; idx < 6; idx++) {
+ r = dev->resource + idx;
+ if (!r->start && r->end) {
+ printk(KERN_ERR
+ "PCI: Device %s not available because"
+ " of resource collisions\n",
+ dev->slot_name);
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ printk("PCI: enabling device %s (%04x -> %04x)\n",
+ dev->slot_name, old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+
+}
+
+/* We should do some optimisation work here I think. Ok for now though */
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size)
+{
+}
+
+void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
+{
+
+ unsigned long where, size;
+ u32 reg;
+
+
+ printk("PCI: Assigning %3s %08lx to %s\n",
+ res->flags & IORESOURCE_IO ? "IO" : "MEM",
+ res->start, dev->name);
+
+ where = PCI_BASE_ADDRESS_0 + resource * 4;
+ size = res->end - res->start;
+
+ pci_read_config_dword(dev, where, &reg);
+ reg = (reg & size) | (((u32) (res->start - root->start)) & ~size);
+ pci_write_config_dword(dev, where, reg);
+}
+
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+ printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+ u8 lat;
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+ if (lat < 16)
+ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+ else if (lat > pcibios_max_latency)
+ lat = pcibios_max_latency;
+ else
+ return;
+ printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
diff --git a/arch/sh/boards/overdrive/io.c b/arch/sh/boards/overdrive/io.c
new file mode 100644
index 000000000000..65f3fd0563d3
--- /dev/null
+++ b/arch/sh/boards/overdrive/io.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * This file contains the I/O routines for use on the overdrive board
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+#include <asm/overdrive/overdrive.h>
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the SuperH architecture, we just read/write the
+ * memory location directly.
+ */
+
+#define dprintk(x...)
+
+/* Translates an IO address to where it is mapped in memory */
+
+#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE)
+
+unsigned char od_inb(unsigned long port)
+{
+dprintk("od_inb(%x)\n", port);
+ return readb(io_addr(port)) & 0xff;
+}
+
+
+unsigned short od_inw(unsigned long port)
+{
+dprintk("od_inw(%x)\n", port);
+ return readw(io_addr(port)) & 0xffff;
+}
+
+unsigned int od_inl(unsigned long port)
+{
+dprintk("od_inl(%x)\n", port);
+ return readl(io_addr(port));
+}
+
+void od_outb(unsigned char value, unsigned long port)
+{
+dprintk("od_outb(%x, %x)\n", value, port);
+ writeb(value, io_addr(port));
+}
+
+void od_outw(unsigned short value, unsigned long port)
+{
+dprintk("od_outw(%x, %x)\n", value, port);
+ writew(value, io_addr(port));
+}
+
+void od_outl(unsigned int value, unsigned long port)
+{
+dprintk("od_outl(%x, %x)\n", value, port);
+ writel(value, io_addr(port));
+}
+
+/* This is horrible at the moment - needs more work to do something sensible */
+#define IO_DELAY() udelay(10)
+
+#define OUT_DELAY(x,type) \
+void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();}
+
+#define IN_DELAY(x,type) \
+unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;}
+
+
+OUT_DELAY(b,char)
+OUT_DELAY(w,short)
+OUT_DELAY(l,int)
+
+IN_DELAY(b,char)
+IN_DELAY(w,short)
+IN_DELAY(l,int)
+
+
+/* Now for the string version of these functions */
+void od_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+ int i;
+ unsigned char *p = (unsigned char *) addr;
+
+ for (i = 0; i < count; i++, p++) {
+ outb(*p, port);
+ }
+}
+
+
+void od_insb(unsigned long port, void *addr, unsigned long count)
+{
+ int i;
+ unsigned char *p = (unsigned char *) addr;
+
+ for (i = 0; i < count; i++, p++) {
+ *p = inb(port);
+ }
+}
+
+/* For the 16 and 32 bit string functions, we have to worry about alignment.
+ * The SH does not do unaligned accesses, so we have to read as bytes and
+ * then write as a word or dword.
+ * This can be optimised a lot more, especially in the case where the data
+ * is aligned
+ */
+
+void od_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+ int i;
+ unsigned short tmp;
+ unsigned char *p = (unsigned char *) addr;
+
+ for (i = 0; i < count; i++, p += 2) {
+ tmp = (*p) | ((*(p + 1)) << 8);
+ outw(tmp, port);
+ }
+}
+
+
+void od_insw(unsigned long port, void *addr, unsigned long count)
+{
+ int i;
+ unsigned short tmp;
+ unsigned char *p = (unsigned char *) addr;
+
+ for (i = 0; i < count; i++, p += 2) {
+ tmp = inw(port);
+ p[0] = tmp & 0xff;
+ p[1] = (tmp >> 8) & 0xff;
+ }
+}
+
+
+void od_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+ int i;
+ unsigned tmp;
+ unsigned char *p = (unsigned char *) addr;
+
+ for (i = 0; i < count; i++, p += 4) {
+ tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
+ ((*(p + 3)) << 24);
+ outl(tmp, port);
+ }
+}
+
+
+void od_insl(unsigned long port, void *addr, unsigned long count)
+{
+ int i;
+ unsigned tmp;
+ unsigned char *p = (unsigned char *) addr;
+
+ for (i = 0; i < count; i++, p += 4) {
+ tmp = inl(port);
+ p[0] = tmp & 0xff;
+ p[1] = (tmp >> 8) & 0xff;
+ p[2] = (tmp >> 16) & 0xff;
+ p[3] = (tmp >> 24) & 0xff;
+
+ }
+}
diff --git a/arch/sh/boards/overdrive/irq.c b/arch/sh/boards/overdrive/irq.c
new file mode 100644
index 000000000000..23adc6be71e7
--- /dev/null
+++ b/arch/sh/boards/overdrive/irq.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Looks after interrupts on the overdrive board.
+ *
+ * Bases on the IPR irq system
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <asm/overdrive/overdrive.h>
+
+struct od_data {
+ int overdrive_irq;
+ int irq_mask;
+};
+
+#define NUM_EXTERNAL_IRQS 16
+#define EXTERNAL_IRQ_NOT_IN_USE (-1)
+#define EXTERNAL_IRQ_NOT_ASSIGNED (-1)
+
+/*
+ * This table is used to determine what to program into the FPGA's CT register
+ * for the specified Linux IRQ.
+ *
+ * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0))
+ * but is one greater than that because the because the FPGA treats 0
+ * as disabled, a value of 1 asserts PCI_Int0, and so on.
+ *
+ * The overdrive_irq specifies which of the eight interrupt sources generates
+ * that interrupt, and but is multiplied by four to give the bit offset into
+ * the CT register.
+ *
+ * The seven interrupts levels (SH4 IRL's) we have available here is hardwired
+ * by the EPLD. The assignments here of which PCI interrupt generates each
+ * level is arbitary.
+ */
+static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = {
+ /* overdrive_irq , irq_mask */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */
+ {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */
+};
+
+static void set_od_data(int overdrive_irq, int irq)
+{
+ if (irq >= NUM_EXTERNAL_IRQS || irq < 0)
+ return;
+ od_data_table[irq].overdrive_irq = overdrive_irq << 2;
+}
+
+static void enable_od_irq(unsigned int irq);
+void disable_od_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_od_irq disable_od_irq
+
+static void mask_and_ack_od(unsigned int);
+static void end_od_irq(unsigned int irq);
+
+static unsigned int startup_od_irq(unsigned int irq)
+{
+ enable_od_irq(irq);
+ return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type od_irq_type = {
+ "Overdrive-IRQ",
+ startup_od_irq,
+ shutdown_od_irq,
+ enable_od_irq,
+ disable_od_irq,
+ mask_and_ack_od,
+ end_od_irq
+};
+
+static void disable_od_irq(unsigned int irq)
+{
+ unsigned val, flags;
+ int overdrive_irq;
+ unsigned mask;
+
+ /* Not a valid interrupt */
+ if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
+ return;
+
+ /* Is is necessary to use a cli here? Would a spinlock not be
+ * mroe efficient?
+ */
+ local_irq_save(flags);
+ overdrive_irq = od_data_table[irq].overdrive_irq;
+ if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
+ mask = ~(0x7 << overdrive_irq);
+ val = ctrl_inl(OVERDRIVE_INT_CT);
+ val &= mask;
+ ctrl_outl(val, OVERDRIVE_INT_CT);
+ }
+ local_irq_restore(flags);
+}
+
+static void enable_od_irq(unsigned int irq)
+{
+ unsigned val, flags;
+ int overdrive_irq;
+ unsigned mask;
+
+ /* Not a valid interrupt */
+ if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
+ return;
+
+ /* Set priority in OD back to original value */
+ local_irq_save(flags);
+ /* This one is not in use currently */
+ overdrive_irq = od_data_table[irq].overdrive_irq;
+ if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
+ val = ctrl_inl(OVERDRIVE_INT_CT);
+ mask = ~(0x7 << overdrive_irq);
+ val &= mask;
+ mask = od_data_table[irq].irq_mask << overdrive_irq;
+ val |= mask;
+ ctrl_outl(val, OVERDRIVE_INT_CT);
+ }
+ local_irq_restore(flags);
+}
+
+
+
+/* this functions sets the desired irq handler to be an overdrive type */
+static void __init make_od_irq(unsigned int irq)
+{
+ disable_irq_nosync(irq);
+ irq_desc[irq].handler = &od_irq_type;
+ disable_od_irq(irq);
+}
+
+
+static void mask_and_ack_od(unsigned int irq)
+{
+ disable_od_irq(irq);
+}
+
+static void end_od_irq(unsigned int irq)
+{
+ enable_od_irq(irq);
+}
+
+void __init init_overdrive_irq(void)
+{
+ int i;
+
+ /* Disable all interrupts */
+ ctrl_outl(0, OVERDRIVE_INT_CT);
+
+ /* Update interrupt pin mode to use encoded interrupts */
+ i = ctrl_inw(INTC_ICR);
+ i &= ~INTC_ICR_IRLM;
+ ctrl_outw(i, INTC_ICR);
+
+ for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
+ if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) {
+ make_od_irq(i);
+ } else if (i != 15) { // Cannot use imask on level 15
+ make_imask_irq(i);
+ }
+ }
+
+ /* Set up the interrupts */
+ set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1);
+ set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2);
+ set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ);
+}
diff --git a/arch/sh/boards/overdrive/led.c b/arch/sh/boards/overdrive/led.c
new file mode 100644
index 000000000000..734742e92279
--- /dev/null
+++ b/arch/sh/boards/overdrive/led.c
@@ -0,0 +1,59 @@
+/*
+ * linux/arch/sh/overdrive/led.c
+ *
+ * Copyright (C) 1999 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * This file contains an Overdrive specific LED feature.
+ */
+
+#include <linux/config.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/overdrive/overdrive.h>
+
+static void mach_led(int position, int value)
+{
+ unsigned long flags;
+ unsigned long reg;
+
+ local_irq_save(flags);
+
+ reg = readl(OVERDRIVE_CTRL);
+ if (value) {
+ reg |= (1<<3);
+ } else {
+ reg &= ~(1<<3);
+ }
+ writel(reg, OVERDRIVE_CTRL);
+
+ local_irq_restore(flags);
+}
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* acts like an actual heart beat -- ie thump-thump-pause... */
+void heartbeat_od(void)
+{
+ static unsigned cnt = 0, period = 0, dist = 0;
+
+ if (cnt == 0 || cnt == dist)
+ mach_led( -1, 1);
+ else if (cnt == 7 || cnt == dist+7)
+ mach_led( -1, 0);
+
+ if (++cnt > period) {
+ cnt = 0;
+ /* The hyperbolic function below modifies the heartbeat period
+ * length in dependency of the current (5min) load. It goes
+ * through the points f(0)=126, f(1)=86, f(5)=51,
+ * f(inf)->30. */
+ period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+ dist = period / 4;
+ }
+}
+#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/overdrive/mach.c b/arch/sh/boards/overdrive/mach.c
new file mode 100644
index 000000000000..81c292e03580
--- /dev/null
+++ b/arch/sh/boards/overdrive/mach.c
@@ -0,0 +1,74 @@
+/*
+ * linux/arch/sh/overdrive/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the STMicroelectronics Overdrive
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_unknown.h>
+#include <asm/io_generic.h>
+#include <asm/overdrive/io.h>
+
+void heartbeat_od(void);
+void init_overdrive_irq(void);
+void galileo_pcibios_init(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_od __initmv = {
+ mv_nr_irqs: 48,
+
+ mv_inb: od_inb,
+ mv_inw: od_inw,
+ mv_inl: od_inl,
+ mv_outb: od_outb,
+ mv_outw: od_outw,
+ mv_outl: od_outl,
+
+ mv_inb_p: od_inb_p,
+ mv_inw_p: od_inw_p,
+ mv_inl_p: od_inl_p,
+ mv_outb_p: od_outb_p,
+ mv_outw_p: od_outw_p,
+ mv_outl_p: od_outl_p,
+
+ mv_insb: od_insb,
+ mv_insw: od_insw,
+ mv_insl: od_insl,
+ mv_outsb: od_outsb,
+ mv_outsw: od_outsw,
+ mv_outsl: od_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+
+ mv_isa_port2addr: generic_isa_port2addr,
+
+#ifdef CONFIG_PCI
+ mv_init_irq: init_overdrive_irq,
+#endif
+#ifdef CONFIG_HEARTBEAT
+ mv_heartbeat: heartbeat_od,
+#endif
+};
+
+ALIAS_MV(od)
diff --git a/arch/sh/boards/overdrive/pcidma.c b/arch/sh/boards/overdrive/pcidma.c
new file mode 100644
index 000000000000..275ea1a7eacf
--- /dev/null
+++ b/arch/sh/boards/overdrive/pcidma.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Dynamic DMA mapping support.
+ *
+ * On the overdrive, we can only DMA from memory behind the PCI bus!
+ * this means that all DMA'able memory must come from there.
+ * this restriction will not apply to later boards.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t * dma_handle)
+{
+ void *ret;
+ int gfp = GFP_ATOMIC;
+
+ printk("BUG: pci_alloc_consistent() called - not yet supported\n");
+ /* We ALWAYS need DMA memory on the overdrive hardware,
+ * due to it's extreme wierdness
+ * Need to flush the cache here as well, since the memory
+ * can still be seen through the cache!
+ */
+ gfp |= GFP_DMA;
+ ret = (void *) __get_free_pages(gfp, get_order(size));
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_bus(ret);
+ }
+ return ret;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long) vaddr, get_order(size));
+}
diff --git a/arch/sh/boards/overdrive/setup.c b/arch/sh/boards/overdrive/setup.c
new file mode 100644
index 000000000000..a36ce0284ed3
--- /dev/null
+++ b/arch/sh/boards/overdrive/setup.c
@@ -0,0 +1,41 @@
+/*
+ * arch/sh/overdrive/setup.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * STMicroelectronics Overdrive Support.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include <asm/overdrive/overdrive.h>
+#include <asm/overdrive/fpga.h>
+
+extern void od_time_init(void);
+
+const char *get_system_type(void)
+{
+ return "SH7750 Overdrive";
+}
+
+/*
+ * Initialize the board
+ */
+int __init platform_setup(void)
+{
+#ifdef CONFIG_PCI
+ init_overdrive_fpga();
+ galileo_init();
+#endif
+
+ board_time_init = od_time_init;
+
+ /* Enable RS232 receive buffers */
+ writel(0x1e, OVERDRIVE_CTRL);
+}
diff --git a/arch/sh/boards/overdrive/time.c b/arch/sh/boards/overdrive/time.c
new file mode 100644
index 000000000000..68533690e097
--- /dev/null
+++ b/arch/sh/boards/overdrive/time.c
@@ -0,0 +1,119 @@
+/*
+ * arch/sh/boards/overdrive/time.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ * Copyright (C) 2002 Paul Mundt (lethal@chaoticdreams.org)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * STMicroelectronics Overdrive Support.
+ */
+
+void od_time_init(void)
+{
+ struct frqcr_data {
+ unsigned short frqcr;
+ struct {
+ unsigned char multiplier;
+ unsigned char divisor;
+ } factor[3];
+ };
+
+ static struct frqcr_data st40_frqcr_table[] = {
+ { 0x000, {{1,1}, {1,1}, {1,2}}},
+ { 0x002, {{1,1}, {1,1}, {1,4}}},
+ { 0x004, {{1,1}, {1,1}, {1,8}}},
+ { 0x008, {{1,1}, {1,2}, {1,2}}},
+ { 0x00A, {{1,1}, {1,2}, {1,4}}},
+ { 0x00C, {{1,1}, {1,2}, {1,8}}},
+ { 0x011, {{1,1}, {2,3}, {1,6}}},
+ { 0x013, {{1,1}, {2,3}, {1,3}}},
+ { 0x01A, {{1,1}, {1,2}, {1,4}}},
+ { 0x01C, {{1,1}, {1,2}, {1,8}}},
+ { 0x023, {{1,1}, {2,3}, {1,3}}},
+ { 0x02C, {{1,1}, {1,2}, {1,8}}},
+ { 0x048, {{1,2}, {1,2}, {1,4}}},
+ { 0x04A, {{1,2}, {1,2}, {1,6}}},
+ { 0x04C, {{1,2}, {1,2}, {1,8}}},
+ { 0x05A, {{1,2}, {1,3}, {1,6}}},
+ { 0x05C, {{1,2}, {1,3}, {1,6}}},
+ { 0x063, {{1,2}, {1,4}, {1,4}}},
+ { 0x06C, {{1,2}, {1,4}, {1,8}}},
+ { 0x091, {{1,3}, {1,3}, {1,6}}},
+ { 0x093, {{1,3}, {1,3}, {1,6}}},
+ { 0x0A3, {{1,3}, {1,6}, {1,6}}},
+ { 0x0DA, {{1,4}, {1,4}, {1,8}}},
+ { 0x0DC, {{1,4}, {1,4}, {1,8}}},
+ { 0x0EC, {{1,4}, {1,8}, {1,8}}},
+ { 0x123, {{1,4}, {1,4}, {1,8}}},
+ { 0x16C, {{1,4}, {1,8}, {1,8}}},
+ };
+
+ struct memclk_data {
+ unsigned char multiplier;
+ unsigned char divisor;
+ };
+ static struct memclk_data st40_memclk_table[8] = {
+ {1,1}, // 000
+ {1,2}, // 001
+ {1,3}, // 010
+ {2,3}, // 011
+ {1,4}, // 100
+ {1,6}, // 101
+ {1,8}, // 110
+ {1,8} // 111
+ };
+
+ unsigned long pvr;
+
+ /*
+ * This should probably be moved into the SH3 probing code, and then
+ * use the processor structure to determine which CPU we are running
+ * on.
+ */
+ pvr = ctrl_inl(CCN_PVR);
+ printk("PVR %08x\n", pvr);
+
+ if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) {
+ /*
+ * Unfortunatly the STB1 FRQCR values are different from the
+ * 7750 ones.
+ */
+ struct frqcr_data *d;
+ int a;
+ unsigned long memclkcr;
+ struct memclk_data *e;
+
+ for (a=0; a<ARRAY_SIZE(st40_frqcr_table); a++) {
+ d = &st40_frqcr_table[a];
+ if (d->frqcr == (frqcr & 0x1ff))
+ break;
+ }
+ if (a == ARRAY_SIZE(st40_frqcr_table)) {
+ d = st40_frqcr_table;
+ printk("ERROR: Unrecognised FRQCR value, using default multipliers\n");
+ }
+
+ memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
+ e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
+
+ printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n",
+ d->factor[0].multiplier, d->factor[0].divisor,
+ d->factor[1].multiplier, d->factor[1].divisor,
+ e->multiplier, e->divisor,
+ d->factor[2].multiplier, d->factor[2].divisor);
+
+ current_cpu_data.master_clock = current_cpu_data.module_clock *
+ d->factor[2].divisor /
+ d->factor[2].multiplier;
+ current_cpu_data.bus_clock = current_cpu_data.master_clock *
+ d->factor[1].multiplier /
+ d->factor[1].divisor;
+ current_cpu_data.memory_clock = current_cpu_data.master_clock *
+ e->multiplier / e->divisor;
+ current_cpu_data.cpu_clock = current_cpu_data.master_clock *
+ d->factor[0].multiplier /
+ d->factor[0].divisor;
+}
+
diff --git a/arch/sh/boards/saturn/Makefile b/arch/sh/boards/saturn/Makefile
new file mode 100644
index 000000000000..5ffe02905bf0
--- /dev/null
+++ b/arch/sh/boards/saturn/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the Sega Saturn specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o
+
+obj-$(CONFIG_SMP) += smp.o
+
diff --git a/arch/sh/boards/saturn/io.c b/arch/sh/boards/saturn/io.c
new file mode 100644
index 000000000000..c6e4f7f2e686
--- /dev/null
+++ b/arch/sh/boards/saturn/io.c
@@ -0,0 +1,26 @@
+/*
+ * arch/sh/boards/saturn/io.c
+ *
+ * I/O routines for the Sega Saturn.
+ *
+ * Copyright (C) 2002 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <asm/saturn/io.h>
+#include <asm/machvec.h>
+
+unsigned long saturn_isa_port2addr(unsigned long offset)
+{
+ return offset;
+}
+
+void *saturn_ioremap(unsigned long offset, unsigned long size)
+{
+ return (void *)offset;
+}
+
+void saturn_iounmap(void *addr)
+{
+}
+
diff --git a/arch/sh/boards/saturn/irq.c b/arch/sh/boards/saturn/irq.c
new file mode 100644
index 000000000000..9950fa122b01
--- /dev/null
+++ b/arch/sh/boards/saturn/irq.c
@@ -0,0 +1,119 @@
+/*
+ * arch/sh/boards/saturn/irq.c
+ *
+ * Copyright (C) 2002 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/saturn/saturn.h>
+#include <asm/saturn/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+/*
+ * Interrupts map out as follows:
+ *
+ * Vector Name Mask
+ *
+ * 64 VBLANKIN 0x0001
+ * 65 VBLANKOUT 0x0002
+ * 66 HBLANKIN 0x0004
+ * 67 TIMER0 0x0008
+ * 68 TIMER1 0x0010
+ * 69 DSPEND 0x0020
+ * 70 SOUNDREQUEST 0x0040
+ * 71 SYSTEMMANAGER 0x0080
+ * 72 PAD 0x0100
+ * 73 LEVEL2DMAEND 0x0200
+ * 74 LEVEL1DMAEND 0x0400
+ * 75 LEVEL0DMAEND 0x0800
+ * 76 DMAILLEGAL 0x1000
+ * 77 SRITEDRAWEND 0x2000
+ * 78 ABUS 0x8000
+ *
+ */
+#define SATURN_IRQ_MIN 64 /* VBLANKIN */
+#define SATURN_IRQ_MAX 78 /* ABUS */
+
+#define SATURN_IRQ_MASK 0xbfff
+
+static inline u32 saturn_irq_mask(unsigned int irq_nr)
+{
+ u32 mask;
+
+ mask = (1 << (irq_nr - SATURN_IRQ_MIN));
+ mask <<= (irq_nr == SATURN_IRQ_MAX);
+ mask &= SATURN_IRQ_MASK;
+
+ return mask;
+}
+
+static inline void mask_saturn_irq(unsigned int irq_nr)
+{
+ u32 mask;
+
+ mask = ctrl_inl(SATURN_IMR);
+ mask |= saturn_irq_mask(irq_nr);
+ ctrl_outl(mask, SATURN_IMR);
+}
+
+static inline void unmask_saturn_irq(unsigned int irq_nr)
+{
+ u32 mask;
+
+ mask = ctrl_inl(SATURN_IMR);
+ mask &= ~saturn_irq_mask(irq_nr);
+ ctrl_outl(SATURN_IMR);
+}
+
+static void disable_saturn_irq(unsigned int irq_nr)
+{
+ mask_saturn_irq(irq_nr);
+}
+
+static void enable_saturn_irq(unsigned int irq_nr)
+{
+ unmask_saturn_irq(irq_nr);
+}
+
+static void mask_and_ack_saturn_irq(unsigned int irq_nr)
+{
+ mask_saturn_irq(irq_nr);
+}
+
+static void end_saturn_irq(unsigned int irq_nr)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ unmask_saturn_irq(irq_nr);
+}
+
+static unsigned int startup_saturn_irq(unsigned int irq_nr)
+{
+ unmask_saturn_irq(irq_nr);
+
+ return 0;
+}
+
+static void shutdown_saturn_irq(unsigned int irq_nr)
+{
+ mask_saturn_irq(irq_nr);
+}
+
+static struct hw_interrupt_type saturn_int = {
+ typename: "Saturn",
+ enable: enable_saturn_irq,
+ disable: disable_saturn_irq,
+ ack: mask_and_ack_saturn_irq,
+ end: end_saturn_irq,
+ startup: startup_saturn_irq,
+ shutdown: shutdown_saturn_irq,
+};
+
+int saturn_irq_demux(int irq_nr)
+{
+ /* FIXME */
+ return irq_nr;
+}
+
diff --git a/arch/sh/boards/saturn/mach.c b/arch/sh/boards/saturn/mach.c
new file mode 100644
index 000000000000..73b55c732a43
--- /dev/null
+++ b/arch/sh/boards/saturn/mach.c
@@ -0,0 +1,61 @@
+/*
+ * arch/sh/boards/saturn/mach.c
+ *
+ * machvec definitions for the Sega Saturn.
+ *
+ * Copyright (C) 2002 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <asm/io.h>
+#include <asm/io_generic.h>
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+#include <asm/rtc.h>
+#include <asm/saturn/io.h>
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_saturn __initmv = {
+ mv_nr_irqs: 80, /* Fix this later */
+
+ mv_inb: generic_inb,
+ mv_inw: generic_inw,
+ mv_inl: generic_inl,
+ mv_outb: generic_outb,
+ mv_outw: generic_outw,
+ mv_outl: generic_outl,
+
+ mv_inb_p: generic_inb_p,
+ mv_inw_p: generic_inw_p,
+ mv_inl_p: generic_inl_p,
+ mv_outb_p: generic_outb_p,
+ mv_outw_p: generic_outw_p,
+ mv_outl_p: generic_outl_p,
+
+ mv_insb: generic_insb,
+ mv_insw: generic_insw,
+ mv_insl: generic_insl,
+ mv_outsb: generic_outsb,
+ mv_outsw: generic_outsw,
+ mv_outsl: generic_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_isa_port2addr: saturn_isa_port2addr,
+ mv_irq_demux: saturn_irq_demux,
+
+ mv_ioremap: saturn_ioremap,
+ mv_iounmap: saturn_iounmap,
+
+ mv_hw_saturn: 1,
+};
+
+ALIAS_MV(saturn)
+
diff --git a/arch/sh/boards/saturn/setup.c b/arch/sh/boards/saturn/setup.c
new file mode 100644
index 000000000000..d2ce5dc0708c
--- /dev/null
+++ b/arch/sh/boards/saturn/setup.c
@@ -0,0 +1,22 @@
+/*
+ * arch/sh/boards/saturn/setup.c
+ *
+ * Hardware support for the Sega Saturn.
+ *
+ * Copyright (c) 2002 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+const char *get_system_type(void)
+{
+ return "Sega Saturn";
+}
+
+int __init platform_setup(void)
+{
+ return 0;
+}
+
diff --git a/arch/sh/boards/saturn/smp.c b/arch/sh/boards/saturn/smp.c
new file mode 100644
index 000000000000..94fbb5fa7944
--- /dev/null
+++ b/arch/sh/boards/saturn/smp.c
@@ -0,0 +1,68 @@
+/*
+ * arch/sh/boards/saturn/smp.c
+ *
+ * SMP support for the Sega Saturn.
+ *
+ * Copyright (c) 2002 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/saturn/smpc.h>
+
+extern void start_secondary(void);
+
+void __smp_send_ipi(unsigned int cpu, unsigned int action)
+{
+ /* Nothing here yet .. */
+}
+
+unsigned int __smp_probe_cpus(void)
+{
+ /*
+ * This is just a straightforward master/slave configuration,
+ * and probing isn't really supported..
+ */
+ return 2;
+}
+
+/*
+ * We're only allowed to do byte-access to SMPC registers. In
+ * addition to which, we treat them as write-only, since
+ * reading from them will return undefined data.
+ */
+static inline void smpc_slave_off(unsigned int cpu)
+{
+ smpc_barrier();
+ ctrl_outb(1, SMPC_STATUS);
+
+ ctrl_outb(SMPC_CMD_SSHOFF, SMPC_COMMAND);
+ smpc_barrier();
+}
+
+static inline void smpc_slave_on(unsigned int cpu)
+{
+ ctrl_outb(1, SMPC_STATUS);
+ ctrl_outb(SMPC_CMD_SSHON, SMPC_COMMAND);
+
+ smpc_barrier();
+}
+
+void __smp_slave_init(unsigned int cpu)
+{
+ register unsigned long vbr;
+ void **entry;
+
+ __asm__ __volatile__ ("stc vbr, %0\n\t" : "=r" (vbr));
+ entry = (void **)(vbr + 0x310 + 0x94);
+
+ smpc_slave_stop(cpu);
+
+ *(void **)entry = (void *)start_secondary;
+
+ smpc_slave_start(cpu);
+}
+
diff --git a/arch/sh/boards/se/770x/Makefile b/arch/sh/boards/se/770x/Makefile
new file mode 100644
index 000000000000..01f9e92916e4
--- /dev/null
+++ b/arch/sh/boards/se/770x/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the 770x SolutionEngine specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o led.o
+
diff --git a/arch/sh/kernel/io_se.c b/arch/sh/boards/se/770x/io.c
index 3771823b5cc9..68bb6a7a0e90 100644
--- a/arch/sh/kernel/io_se.c
+++ b/arch/sh/boards/se/770x/io.c
@@ -1,4 +1,4 @@
-/* $Id: io_se.c,v 1.12 2001/08/11 01:23:28 jzs Exp $
+/* $Id: io.c,v 1.1.2.2 2002/01/20 05:03:25 mrbrown Exp $
*
* linux/arch/sh/kernel/io_se.c
*
@@ -11,7 +11,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
-#include <asm/hitachi_se.h>
+#include <asm/se/se.h>
/* SH pcmcia io window base, start and end. */
int sh_pcic_io_wbase = 0xb8400000;
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
new file mode 100644
index 000000000000..f8ce43f61020
--- /dev/null
+++ b/arch/sh/boards/se/770x/irq.c
@@ -0,0 +1,53 @@
+/* $Id: irq.c,v 1.1.2.2 2002/10/29 00:56:09 lethal Exp $
+ *
+ * linux/arch/sh/boards/se/770x/irq.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/hitachi_se.h>
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se_IRQ(void)
+{
+ /*
+ * Super I/O (Just mimic PC):
+ * 1: keyboard
+ * 3: serial 0
+ * 4: serial 1
+ * 5: printer
+ * 6: floppy
+ * 8: rtc
+ * 12: mouse
+ * 14: ide0
+ */
+ make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
+ make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
+ make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
+ make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
+ make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
+ make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
+ make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
+ make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
+
+ make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
+
+ make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
+ make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
+ make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
+ make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
+
+ /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+ /* NOTE: #2 and #13 are not used on PC */
+ make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
+ make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
+}
diff --git a/arch/sh/kernel/led_se.c b/arch/sh/boards/se/770x/led.c
index 12070522fe3b..5c64e8ab2cfb 100644
--- a/arch/sh/kernel/led_se.c
+++ b/arch/sh/boards/se/770x/led.c
@@ -10,7 +10,7 @@
*/
#include <linux/config.h>
-#include <asm/hitachi_se.h>
+#include <asm/se/se.h>
static void mach_led(int position, int value)
{
diff --git a/arch/sh/boards/se/770x/mach.c b/arch/sh/boards/se/770x/mach.c
new file mode 100644
index 000000000000..33f64851ab96
--- /dev/null
+++ b/arch/sh/boards/se/770x/mach.c
@@ -0,0 +1,77 @@
+/*
+ * linux/arch/sh/kernel/mach_se.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi SolutionEngine
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/se/io.h>
+
+void heartbeat_se(void);
+void setup_se(void);
+void init_se_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_se __initmv = {
+#if defined(CONFIG_CPU_SH4)
+ mv_nr_irqs: 48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+ mv_nr_irqs: 32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+ mv_nr_irqs: 61,
+#endif
+
+ mv_inb: se_inb,
+ mv_inw: se_inw,
+ mv_inl: se_inl,
+ mv_outb: se_outb,
+ mv_outw: se_outw,
+ mv_outl: se_outl,
+
+ mv_inb_p: se_inb_p,
+ mv_inw_p: se_inw,
+ mv_inl_p: se_inl,
+ mv_outb_p: se_outb_p,
+ mv_outw_p: se_outw,
+ mv_outl_p: se_outl,
+
+ mv_insb: se_insb,
+ mv_insw: se_insw,
+ mv_insl: se_insl,
+ mv_outsb: se_outsb,
+ mv_outsw: se_outsw,
+ mv_outsl: se_outsl,
+
+ mv_readb: se_readb,
+ mv_readw: se_readw,
+ mv_readl: se_readl,
+ mv_writeb: se_writeb,
+ mv_writew: se_writew,
+ mv_writel: se_writel,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+
+ mv_isa_port2addr: se_isa_port2addr,
+
+ mv_init_irq: init_se_IRQ,
+#ifdef CONFIG_HEARTBEAT
+ mv_heartbeat: heartbeat_se,
+#endif
+ mv_hw_se: 1,
+};
+ALIAS_MV(se)
diff --git a/arch/sh/kernel/setup_se.c b/arch/sh/boards/se/770x/setup.c
index 8b2f599723fa..2bed46fb607d 100644
--- a/arch/sh/kernel/setup_se.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -1,6 +1,6 @@
-/* $Id: setup_se.c,v 1.6 2000/05/14 08:41:25 gniibe Exp $
+/* $Id: setup.c,v 1.1.2.4 2002/03/02 21:57:07 lethal Exp $
*
- * linux/arch/sh/kernel/setup_se.c
+ * linux/arch/sh/boards/se/770x/setup.c
*
* Copyright (C) 2000 Kazumoto Kojima
*
@@ -15,8 +15,8 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <asm/io.h>
-#include <asm/hitachi_se.h>
-#include <asm/smc37c93x.h>
+#include <asm/se/se.h>
+#include <asm/se/smc37c93x.h>
/*
* Configure the Super I/O chip
@@ -70,49 +70,15 @@ static void __init init_smsc(void)
outb_p(CONFIG_EXIT, CONFIG_PORT);
}
-/*
- * Initialize IRQ setting
- */
-void __init init_se_IRQ(void)
+const char *get_system_type(void)
{
- /*
- * Super I/O (Just mimic PC):
- * 1: keyboard
- * 3: serial 0
- * 4: serial 1
- * 5: printer
- * 6: floppy
- * 8: rtc
- * 12: mouse
- * 14: ide0
- */
- make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
- make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
- make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
- make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
- make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
- make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
- make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
- make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
-
- make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
-
- make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
- make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
- make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
- make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
-
- /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
- /* NOTE: #2 and #13 are not used on PC */
- make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
- make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
+ return "SolutionEngine";
}
-
/*
* Initialize the board
*/
-void __init setup_se(void)
+void __init platform_setup(void)
{
init_smsc();
/* XXX: RTC setting comes here */
diff --git a/arch/sh/boards/se/7751/Makefile b/arch/sh/boards/se/7751/Makefile
new file mode 100644
index 000000000000..006a3bff1da2
--- /dev/null
+++ b/arch/sh/boards/se/7751/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the 7751 SolutionEngine specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o irq.o led.o
+
+obj-$(CONFIG_PCI) += pci.o
+
diff --git a/arch/sh/kernel/io_7751se.c b/arch/sh/boards/se/7751/io.c
index 2e3155f70ed7..9df6511a39ef 100644
--- a/arch/sh/kernel/io_7751se.c
+++ b/arch/sh/boards/se/7751/io.c
@@ -14,7 +14,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
-#include <asm/hitachi_7751se.h>
+#include <asm/se7751/se7751.h>
#include <asm/addrspace.h>
#include <linux/pci.h>
@@ -97,7 +97,7 @@ shifted_port(unsigned long port)
#define CHECK_SH7751_PCIIO(port) \
((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#else
-#define CHECK_SH_7751_PCIIO(port) (0)
+#define CHECK_SH7751_PCIIO(port) (0)
#endif
/*
diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c
new file mode 100644
index 000000000000..ad71f3e66c11
--- /dev/null
+++ b/arch/sh/boards/se/7751/irq.c
@@ -0,0 +1,67 @@
+/*
+ * linux/arch/sh/boards/se/7751/irq.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/se7751/se7751.h>
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_7751se_IRQ(void)
+{
+
+ /* Leave old Solution Engine code in for reference. */
+#if defined(CONFIG_SH_SOLUTION_ENGINE)
+ /*
+ * Super I/O (Just mimic PC):
+ * 1: keyboard
+ * 3: serial 0
+ * 4: serial 1
+ * 5: printer
+ * 6: floppy
+ * 8: rtc
+ * 12: mouse
+ * 14: ide0
+ */
+ make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
+ make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
+ make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
+ make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
+ make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
+ make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
+ make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
+ make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
+
+ make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
+
+ make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
+ make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
+ make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
+ make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
+
+ /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+ /* NOTE: #2 and #13 are not used on PC */
+ make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
+ make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
+
+#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
+
+ make_ipr_irq(13, BCR_ILCRD, 3, 2);
+
+ /* Add additional calls to make_ipr_irq() as drivers are added
+ * and tested.
+ */
+#endif
+
+}
diff --git a/arch/sh/kernel/led_7751se.c b/arch/sh/boards/se/7751/led.c
index b9cb53cfc7b2..0c788230cf8f 100644
--- a/arch/sh/kernel/led_7751se.c
+++ b/arch/sh/boards/se/7751/led.c
@@ -10,7 +10,7 @@
*/
#include <linux/config.h>
-#include <asm/hitachi_7751se.h>
+#include <asm/se7751/se7751.h>
static void mach_led(int position, int value)
{
diff --git a/arch/sh/boards/se/7751/mach.c b/arch/sh/boards/se/7751/mach.c
new file mode 100644
index 000000000000..af1936a3e4bf
--- /dev/null
+++ b/arch/sh/boards/se/7751/mach.c
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/sh/kernel/mach_7751se.c
+ *
+ * Minor tweak of mach_se.c file to reference 7751se-specific items.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi 7751 SolutionEngine
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/se7751/io.h>
+
+void heartbeat_7751se(void);
+void init_7751se_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_7751se __initmv = {
+ mv_nr_irqs: 72,
+
+ mv_inb: sh7751se_inb,
+ mv_inw: sh7751se_inw,
+ mv_inl: sh7751se_inl,
+ mv_outb: sh7751se_outb,
+ mv_outw: sh7751se_outw,
+ mv_outl: sh7751se_outl,
+
+ mv_inb_p: sh7751se_inb_p,
+ mv_inw_p: sh7751se_inw,
+ mv_inl_p: sh7751se_inl,
+ mv_outb_p: sh7751se_outb_p,
+ mv_outw_p: sh7751se_outw,
+ mv_outl_p: sh7751se_outl,
+
+ mv_insb: sh7751se_insb,
+ mv_insw: sh7751se_insw,
+ mv_insl: sh7751se_insl,
+ mv_outsb: sh7751se_outsb,
+ mv_outsw: sh7751se_outsw,
+ mv_outsl: sh7751se_outsl,
+
+ mv_readb: sh7751se_readb,
+ mv_readw: sh7751se_readw,
+ mv_readl: sh7751se_readl,
+ mv_writeb: sh7751se_writeb,
+ mv_writew: sh7751se_writew,
+ mv_writel: sh7751se_writel,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+
+ mv_isa_port2addr: sh7751se_isa_port2addr,
+
+ mv_init_irq: init_7751se_IRQ,
+#ifdef CONFIG_HEARTBEAT
+ mv_heartbeat: heartbeat_7751se,
+#endif
+ mv_hw_7751se: 1,
+};
+ALIAS_MV(7751se)
diff --git a/arch/sh/kernel/pci-7751se.c b/arch/sh/boards/se/7751/pci.c
index b861ebd65f53..b861ebd65f53 100644
--- a/arch/sh/kernel/pci-7751se.c
+++ b/arch/sh/boards/se/7751/pci.c
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
new file mode 100644
index 000000000000..9d111bb884f9
--- /dev/null
+++ b/arch/sh/boards/se/7751/setup.c
@@ -0,0 +1,228 @@
+/*
+ * linux/arch/sh/kernel/setup_7751se.c
+ *
+ * Copyright (C) 2000 Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <asm/io.h>
+#include <asm/se7751/se7751.h>
+
+#ifdef CONFIG_SH_KGDB
+#include <asm/kgdb.h>
+#endif
+
+/*
+ * Configure the Super I/O chip
+ */
+#if 0
+/* Leftover code from regular Solution Engine, for reference. */
+/* The SH7751 Solution Engine has a different SuperIO. */
+static void __init smsc_config(int index, int data)
+{
+ outb_p(index, INDEX_PORT);
+ outb_p(data, DATA_PORT);
+}
+
+static void __init init_smsc(void)
+{
+ outb_p(CONFIG_ENTER, CONFIG_PORT);
+ outb_p(CONFIG_ENTER, CONFIG_PORT);
+
+ /* FDC */
+ smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
+
+ /* IDE1 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
+
+ /* AUXIO (GPIO): to use IDE1 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
+ smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
+ smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
+
+ /* COM1 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IO_BASE_HI_INDEX, 0x03);
+ smsc_config(IO_BASE_LO_INDEX, 0xf8);
+ smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
+
+ /* COM2 */
+ smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IO_BASE_HI_INDEX, 0x02);
+ smsc_config(IO_BASE_LO_INDEX, 0xf8);
+ smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
+
+ /* RTC */
+ smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
+ smsc_config(ACTIVATE_INDEX, 0x01);
+ smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
+
+ /* XXX: PARPORT, KBD, and MOUSE will come here... */
+ outb_p(CONFIG_EXIT, CONFIG_PORT);
+}
+#endif
+
+const char *get_system_type(void)
+{
+ return "7751 SolutionEngine";
+}
+
+#ifdef CONFIG_SH_KGDB
+static int kgdb_uart_setup(void);
+static struct kgdb_sermap kgdb_uart_sermap =
+{ "ttyS", 0, kgdb_uart_setup, NULL };
+#endif
+
+/*
+ * Initialize the board
+ */
+void __init platform_setup(void)
+{
+ /* Call init_smsc() replacement to set up SuperIO. */
+ /* XXX: RTC setting comes here */
+#ifdef CONFIG_SH_KGDB
+ kgdb_register_sermap(&kgdb_uart_sermap);
+#endif
+}
+
+/*********************************************************************
+ * Currently a hack (e.g. does not interact well w/serial.c, lots of *
+ * hardcoded stuff) but may be useful if SCI/F needs debugging. *
+ * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and *
+ * arch/i386/lib/kgdb_serial.c). *
+ *********************************************************************/
+
+#ifdef CONFIG_SH_KGDB
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#define COM1_PORT 0x3f8 /* Base I/O address */
+#define COM1_IRQ 4 /* IRQ not used yet */
+#define COM2_PORT 0x2f8 /* Base I/O address */
+#define COM2_IRQ 3 /* IRQ not used yet */
+
+#define SB_CLOCK 1843200 /* Serial baud clock */
+#define SB_BASE (SB_CLOCK/16)
+#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
+
+struct uart_port {
+ int base;
+};
+#define UART_NPORTS 2
+struct uart_port uart_ports[] = {
+ { COM1_PORT },
+ { COM2_PORT },
+};
+struct uart_port *kgdb_uart_port;
+
+#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg)
+#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
+
+/* Basic read/write functions for the UART */
+#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
+static int kgdb_uart_getchar(void)
+{
+ int lsr;
+ int c = -1;
+
+ while (c == -1) {
+ lsr = UART_IN(UART_LSR);
+ if (lsr & UART_LSR_DR)
+ c = UART_IN(UART_RX);
+ if ((lsr & UART_LSR_RXCERR))
+ c = -1;
+ }
+ return c;
+}
+
+static void kgdb_uart_putchar(int c)
+{
+ while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+ UART_OUT(UART_TX, c);
+}
+
+/*
+ * Initialize UART to configured/requested values.
+ * (But we don't interrupts yet, or interact w/serial.c)
+ */
+static int kgdb_uart_setup(void)
+{
+ int port;
+ int lcr = 0;
+ int bdiv = 0;
+
+ if (kgdb_portnum >= UART_NPORTS) {
+ KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
+ return -1;
+ }
+
+ kgdb_uart_port = &uart_ports[kgdb_portnum];
+
+ /* Init sequence from gdb_hook_interrupt */
+ UART_IN(UART_RX);
+ UART_OUT(UART_IER, 0);
+
+ UART_IN(UART_RX); /* Serial driver comments say */
+ UART_IN(UART_IIR); /* this clears interrupt regs */
+ UART_IN(UART_MSR);
+
+ /* Figure basic LCR values */
+ switch (kgdb_bits) {
+ case '7':
+ lcr |= UART_LCR_WLEN7;
+ break;
+ default: case '8':
+ lcr |= UART_LCR_WLEN8;
+ break;
+ }
+ switch (kgdb_parity) {
+ case 'O':
+ lcr |= UART_LCR_PARITY;
+ break;
+ case 'E':
+ lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
+ break;
+ default: break;
+ }
+
+ /* Figure the baud rate divisor */
+ bdiv = (SB_BASE/kgdb_baud);
+
+ /* Set the baud rate and LCR values */
+ UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
+ UART_OUT(UART_DLL, (bdiv & 0xff));
+ UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
+ UART_OUT(UART_LCR, lcr);
+
+ /* Set the MCR */
+ UART_OUT(UART_MCR, SB_MCR);
+
+ /* Turn off FIFOs for now */
+ UART_OUT(UART_FCR, 0);
+
+ /* Setup complete: initialize function pointers */
+ kgdb_getchar = kgdb_uart_getchar;
+ kgdb_putchar = kgdb_uart_putchar;
+
+ return 0;
+}
+#endif /* CONFIG_SH_KGDB */
diff --git a/arch/sh/boards/sh2000/Makefile b/arch/sh/boards/sh2000/Makefile
new file mode 100644
index 000000000000..39a974d7bc0e
--- /dev/null
+++ b/arch/sh/boards/sh2000/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the SH2000 specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o setup.o io.o
+
diff --git a/arch/sh/kernel/io_sh2000.c b/arch/sh/boards/sh2000/io.c
index f83067520485..f83067520485 100644
--- a/arch/sh/kernel/io_sh2000.c
+++ b/arch/sh/boards/sh2000/io.c
diff --git a/arch/sh/boards/sh2000/mach.c b/arch/sh/boards/sh2000/mach.c
new file mode 100644
index 000000000000..3f1604d46b4f
--- /dev/null
+++ b/arch/sh/boards/sh2000/mach.c
@@ -0,0 +1,59 @@
+/*
+ * linux/arch/sh/boards/sh2000/mach.c
+ *
+ * Original copyright message:
+ * Copyright (C) 2001 SUGIOKA Tochinobu
+ *
+ * Split into mach.c from setup.c by M. R. Brown <mrbrown@0xd6.org>
+ */
+
+#include <asm/io.h>
+#include <asm/io_generic.h>
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+#include <asm/rtc.h>
+#include <asm/sh2000/sh2000.h>
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_sh2000 __initmv = {
+ mv_nr_irqs: 80,
+
+ mv_inb: generic_inb,
+ mv_inw: generic_inw,
+ mv_inl: generic_inl,
+ mv_outb: generic_outb,
+ mv_outw: generic_outw,
+ mv_outl: generic_outl,
+
+ mv_inb_p: generic_inb_p,
+ mv_inw_p: generic_inw_p,
+ mv_inl_p: generic_inl_p,
+ mv_outb_p: generic_outb_p,
+ mv_outw_p: generic_outw_p,
+ mv_outl_p: generic_outl_p,
+
+ mv_insb: generic_insb,
+ mv_insw: generic_insw,
+ mv_insl: generic_insl,
+ mv_outsb: generic_outsb,
+ mv_outsw: generic_outsw,
+ mv_outsl: generic_outsl,
+
+ mv_readb: generic_readb,
+ mv_readw: generic_readw,
+ mv_readl: generic_readl,
+ mv_writeb: generic_writeb,
+ mv_writew: generic_writew,
+ mv_writel: generic_writel,
+
+ mv_isa_port2addr: sh2000_isa_port2addr,
+
+ mv_ioremap: generic_ioremap,
+ mv_iounmap: generic_iounmap,
+
+ mv_hw_sh2000: 1,
+};
+ALIAS_MV(sh2000)
diff --git a/arch/sh/boards/sh2000/setup.c b/arch/sh/boards/sh2000/setup.c
new file mode 100644
index 000000000000..7717db6a8250
--- /dev/null
+++ b/arch/sh/boards/sh2000/setup.c
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/sh/kernel/setup_sh2000.c
+ *
+ * Copyright (C) 2001 SUGIOKA Tochinobu
+ *
+ * SH-2000 Support.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+
+#define CF_CIS_BASE 0xb4200000
+
+#define PORT_PECR 0xa4000108
+#define PORT_PHCR 0xa400010E
+#define PORT_ICR1 0xa4000010
+#define PORT_IRR0 0xa4000004
+
+const char *get_system_type(void)
+{
+ return "sh2000";
+}
+
+/*
+ * Initialize the board
+ */
+int __init platform_setup(void)
+{
+ /* XXX: RTC setting comes here */
+
+ /* These should be done by BIOS/IPL ... */
+ /* Enable nCE2A, nCE2B output */
+ ctrl_outw(ctrl_inw(PORT_PECR) & ~0xf00, PORT_PECR);
+ /* Enable the Compact Flash card, and set the level interrupt */
+ ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
+ /* Enable interrupt */
+ ctrl_outw(ctrl_inw(PORT_PHCR) & ~0x03f3, PORT_PHCR);
+ ctrl_outw(1, PORT_ICR1);
+ ctrl_outw(ctrl_inw(PORT_IRR0) & ~0xff3f, PORT_IRR0);
+ printk(KERN_INFO "SH-2000 Setup...done\n");
+ return 0;
+}
diff --git a/arch/sh/boards/unknown/Makefile b/arch/sh/boards/unknown/Makefile
new file mode 100644
index 000000000000..a7ee9275a08b
--- /dev/null
+++ b/arch/sh/boards/unknown/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for unknown SH boards
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := mach.o io.o setup.o
+
diff --git a/arch/sh/kernel/io_unknown.c b/arch/sh/boards/unknown/io.c
index 8f3f17267bd9..8f3f17267bd9 100644
--- a/arch/sh/kernel/io_unknown.c
+++ b/arch/sh/boards/unknown/io.c
diff --git a/arch/sh/boards/unknown/mach.c b/arch/sh/boards/unknown/mach.c
new file mode 100644
index 000000000000..1b8eeb80fae4
--- /dev/null
+++ b/arch/sh/boards/unknown/mach.c
@@ -0,0 +1,67 @@
+/*
+ * linux/arch/sh/kernel/mach_unknown.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Machine specific code for an unknown machine (internal peripherials only)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_unknown.h>
+
+#include <asm/rtc.h>
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_unknown __initmv = {
+#if defined(CONFIG_CPU_SH4)
+ mv_nr_irqs: 48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+ mv_nr_irqs: 32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+ mv_nr_irqs: 61,
+#endif
+
+ mv_inb: unknown_inb,
+ mv_inw: unknown_inw,
+ mv_inl: unknown_inl,
+ mv_outb: unknown_outb,
+ mv_outw: unknown_outw,
+ mv_outl: unknown_outl,
+
+ mv_inb_p: unknown_inb_p,
+ mv_inw_p: unknown_inw_p,
+ mv_inl_p: unknown_inl_p,
+ mv_outb_p: unknown_outb_p,
+ mv_outw_p: unknown_outw_p,
+ mv_outl_p: unknown_outl_p,
+
+ mv_insb: unknown_insb,
+ mv_insw: unknown_insw,
+ mv_insl: unknown_insl,
+ mv_outsb: unknown_outsb,
+ mv_outsw: unknown_outsw,
+ mv_outsl: unknown_outsl,
+
+ mv_readb: unknown_readb,
+ mv_readw: unknown_readw,
+ mv_readl: unknown_readl,
+ mv_writeb: unknown_writeb,
+ mv_writew: unknown_writew,
+ mv_writel: unknown_writel,
+
+ mv_ioremap: unknown_ioremap,
+ mv_iounmap: unknown_iounmap,
+
+ mv_isa_port2addr: unknown_isa_port2addr,
+};
+ALIAS_MV(unknown)
diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c
new file mode 100644
index 000000000000..7d772a6f8865
--- /dev/null
+++ b/arch/sh/boards/unknown/setup.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/sh/boards/unknown/setup.c
+ *
+ * Copyright (C) 2002 Paul Mundt
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Setup code for an unknown machine (internal peripherials only)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+const char *get_system_type(void)
+{
+ return "Unknown";
+}
+
+void __init platform_setup(void)
+{
+}
+
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index b2efc40bf86d..7d159ab7c5b0 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -4,40 +4,34 @@
# create a compressed vmlinux image from the original vmlinux
#
-HEAD = head.o
-SYSTEM = $(TOPDIR)/vmlinux
+targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+EXTRA_AFLAGS := -traditional
-OBJECTS = $(HEAD) misc.o
+OBJECTS = $(obj)/head.o $(obj)/misc.o
ifdef CONFIG_SH_STANDARD_BIOS
-OBJECTS += ../../kernel/sh_bios.o
+OBJECTS += $(obj)/../../kernel/sh_bios.o
endif
-ZLDFLAGS = -e startup -T $(TOPDIR)/arch/sh/vmlinux.lds
-
#
-# ZIMAGE_OFFSET is the load offset of the compression loader
+# IMAGE_OFFSET is the load offset of the compression loader
#
-ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x200000+0x10000])
+IMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x200000+0x10000])
-ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
+LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../vmlinux.lds.s
-all: vmlinux
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
+ $(call if_changed,ld)
+ @:
-vmlinux: piggy.o $(OBJECTS)
- $(LD) $(LDFLAGS) $(ZLINKFLAGS) -o vmlinux $(OBJECTS) piggy.o
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
-head.o: head.S
- $(CC) $(AFLAGS) -traditional -c head.S
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
-piggy.o: $(SYSTEM)
- tmppiggy=_tmp_$$$$piggy; \
- rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
- $(OBJCOPY) $(OBJCOPYFLAGS) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \
- gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
- echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
- $(LD) $(LDFLAGS) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-sh-linux -T $$tmppiggy.lnk; \
- rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-sh-linux -T
+OBJCOPYFLAGS += -R .empty_zero_page
-clean:
- rm -f vmlinux _tmp_*
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+ $(call if_changed,ld)
diff --git a/arch/sh/cchips/hd6446x/hd64461/Makefile b/arch/sh/cchips/hd6446x/hd64461/Makefile
new file mode 100644
index 000000000000..d5c1b7e5d3a2
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64461/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HD64461
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := setup.o io.o
+
diff --git a/arch/sh/kernel/io_hd64461.c b/arch/sh/cchips/hd6446x/hd64461/io.c
index 5273edd44970..a41068a64a37 100644
--- a/arch/sh/kernel/io_hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461/io.c
@@ -1,12 +1,12 @@
/*
- * $Id: io_hd64461.c,v 1.6 2000/11/16 23:28:44 yaegashi Exp $
+ * $Id: io.c,v 1.1.2.2 2002/01/20 05:03:25 mrbrown Exp $
* Copyright (C) 2000 YAEGASHI Takeshi
* Typical I/O routines for HD64461 system.
*/
#include <linux/config.h>
#include <asm/io.h>
-#include <asm/hd64461.h>
+#include <asm/hd64461/hd64461.h>
static __inline__ unsigned long PORT2ADDR(unsigned long port)
{
diff --git a/arch/sh/kernel/setup_hd64461.c b/arch/sh/cchips/hd6446x/hd64461/setup.c
index 1474b9c97a52..beaff79080fa 100644
--- a/arch/sh/kernel/setup_hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461/setup.c
@@ -1,5 +1,5 @@
/*
- * $Id: setup_hd64461.c,v 1.9 2001/07/15 23:26:56 gniibe Exp $
+ * $Id: setup.c,v 1.1.2.3 2002/11/04 20:33:57 lethal Exp $
* Copyright (C) 2000 YAEGASHI Takeshi
* Hitachi HD64461 companion chip support
*/
@@ -15,7 +15,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hd64461.h>
+#include <asm/hd64461/hd64461.h>
static void disable_hd64461_irq(unsigned int irq)
{
@@ -23,11 +23,11 @@ static void disable_hd64461_irq(unsigned int irq)
unsigned short nimr;
unsigned short mask = 1 << (irq - HD64461_IRQBASE);
- save_and_cli(flags);
+ local_irq_save(flags);
nimr = inw(HD64461_NIMR);
nimr |= mask;
outw(nimr, HD64461_NIMR);
- restore_flags(flags);
+ local_irq_restore(flags);
}
@@ -37,11 +37,11 @@ static void enable_hd64461_irq(unsigned int irq)
unsigned short nimr;
unsigned short mask = 1 << (irq - HD64461_IRQBASE);
- save_and_cli(flags);
+ local_irq_save(flags);
nimr = inw(HD64461_NIMR);
nimr &= ~mask;
outw(nimr, HD64461_NIMR);
- restore_flags(flags);
+ local_irq_restore(flags);
}
diff --git a/arch/sh/cchips/hd6446x/hd64465/Makefile b/arch/sh/cchips/hd6446x/hd64465/Makefile
new file mode 100644
index 000000000000..01a7b1acdfc8
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64465/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HD64465
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y := setup.o io.o gpio.o
+
diff --git a/arch/sh/kernel/hd64465_gpio.c b/arch/sh/cchips/hd6446x/hd64465/gpio.c
index 594c73b4bf4f..a905ee4e3af8 100644
--- a/arch/sh/kernel/hd64465_gpio.c
+++ b/arch/sh/cchips/hd6446x/hd64465/gpio.c
@@ -1,5 +1,5 @@
/*
- * $Id: hd64465_gpio.c,v 1.2 2001/05/24 00:13:47 gniibe Exp $
+ * $Id: gpio.c,v 1.1.2.3 2002/11/04 20:33:57 lethal Exp $
* by Greg Banks <gbanks@pocketpenguins.com>
* (c) 2000 PocketPenguins Inc
*
@@ -12,7 +12,7 @@
#include <linux/sched.h>
#include <linux/ioport.h>
#include <asm/io.h>
-#include <asm/hd64465_gpio.h>
+#include <asm/hd64465/gpio.h>
#define _PORTOF(portpin) (((portpin)>>3)&0x7)
#define _PINOF(portpin) ((portpin)&0x7)
@@ -118,7 +118,7 @@ void hd64465_gpio_register_irq(int portpin, int mode,
if (handler == 0)
return;
- save_and_cli(flags);
+ local_irq_save(flags);
handlers[portpin].func = handler;
handlers[portpin].dev = dev;
@@ -140,7 +140,7 @@ void hd64465_gpio_register_irq(int portpin, int mode,
outw(icr, GPIO_ICR(_PORTOF(portpin)));
- restore_flags(flags);
+ local_irq_restore(flags);
}
void hd64465_gpio_unregister_irq(int portpin)
@@ -148,7 +148,7 @@ void hd64465_gpio_unregister_irq(int portpin)
unsigned long flags;
unsigned short icr;
- save_and_cli(flags);
+ local_irq_save(flags);
/*
* Configure Interrupt Control Register
@@ -160,24 +160,17 @@ void hd64465_gpio_unregister_irq(int portpin)
handlers[portpin].func = 0;
handlers[portpin].dev = 0;
- restore_flags(flags);
+ local_irq_restore(flags);
}
static int __init hd64465_gpio_init(void)
{
- int err;
-
- if (!request_region(HD64465_REG_GPACR, 0x1000, MODNAME))
- return -EIO;
- err = request_irq (HD64465_IRQ_GPIO, hd64465_gpio_interrupt,
- SA_INTERRUPT, MODNAME, 0);
- if (err) {
- printk(KERN_ERR"HD64465: Unable to get irq %d.\n", HD64465_IRQ_GPIO);
- release_region(HD64465_REG_GPACR, 0x1000);
- return err;
- }
+ /* TODO: check return values */
+ request_region(HD64465_REG_GPACR, 0x1000, MODNAME);
+ request_irq(HD64465_IRQ_GPIO, hd64465_gpio_interrupt,
+ SA_INTERRUPT, MODNAME, 0);
- printk("HD64465 GPIO layer on irq %d\n", HD64465_IRQ_GPIO);
+ printk("HD64465 GPIO layer on irq %d\n", HD64465_IRQ_GPIO);
return 0;
}
diff --git a/arch/sh/kernel/io_hd64465.c b/arch/sh/cchips/hd6446x/hd64465/io.c
index 3944a73b2979..e0da9e70db46 100644
--- a/arch/sh/kernel/io_hd64465.c
+++ b/arch/sh/cchips/hd6446x/hd64465/io.c
@@ -1,5 +1,5 @@
/*
- * $Id: io_hd64465.c,v 1.7 2001/05/09 07:39:36 gniibe Exp $
+ * $Id: io.c,v 1.1.2.2 2002/01/20 05:03:25 mrbrown Exp $
* by Greg Banks <gbanks@pocketpenguins.com>
* (c) 2000 PocketPenguins Inc
*
@@ -13,7 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/io.h>
-#include <asm/hd64465.h>
+#include <asm/hd64465/hd64465.h>
#define HD64465_DEBUG 0
diff --git a/arch/sh/kernel/setup_hd64465.c b/arch/sh/cchips/hd6446x/hd64465/setup.c
index 857f9da68834..8458df626f74 100644
--- a/arch/sh/kernel/setup_hd64465.c
+++ b/arch/sh/cchips/hd6446x/hd64465/setup.c
@@ -1,5 +1,5 @@
/*
- * $Id: setup_hd64465.c,v 1.4 2001/07/15 23:26:56 gniibe Exp $
+ * $Id: setup.c,v 1.1.2.3 2002/11/04 20:33:57 lethal Exp $
*
* Setup and IRQ handling code for the HD64465 companion chip.
* by Greg Banks <gbanks@pocketpenguins.com>
@@ -22,7 +22,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hd64465.h>
+#include <asm/hd64465/hd64465.h>
#undef HD64465_DEBUG
@@ -39,11 +39,11 @@ static void disable_hd64465_irq(unsigned int irq)
unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
DPRINTK("disable_hd64465_irq(%d): mask=%x\n", irq, mask);
- save_and_cli(flags);
+ local_irq_save(flags);
nimr = inw(HD64465_REG_NIMR);
nimr |= mask;
outw(nimr, HD64465_REG_NIMR);
- restore_flags(flags);
+ local_irq_restore(flags);
}
@@ -54,11 +54,11 @@ static void enable_hd64465_irq(unsigned int irq)
unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
DPRINTK("enable_hd64465_irq(%d): mask=%x\n", irq, mask);
- save_and_cli(flags);
+ local_irq_save(flags);
nimr = inw(HD64465_REG_NIMR);
nimr &= ~mask;
outw(nimr, HD64465_REG_NIMR);
- restore_flags(flags);
+ local_irq_restore(flags);
}
@@ -89,13 +89,13 @@ static void shutdown_hd64465_irq(unsigned int irq)
static struct hw_interrupt_type hd64465_irq_type = {
- .typename = "HD64465-IRQ",
- .startup = startup_hd64465_irq,
- .shutdown = shutdown_hd64465_irq,
- .enable = enable_hd64465_irq,
- .disable = disable_hd64465_irq,
- .ack = mask_and_ack_hd64465,
- .end = end_hd64465_irq
+ typename: "HD64465-IRQ",
+ startup: startup_hd64465_irq,
+ shutdown: shutdown_hd64465_irq,
+ enable: enable_hd64465_irq,
+ disable: disable_hd64465_irq,
+ ack: mask_and_ack_hd64465,
+ end: end_hd64465_irq
};
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index cd46351053dc..c680c404cfb2 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -4,68 +4,23 @@
extra-y := head.o init_task.o
-obj-y := process.o signal.o entry.o traps.o irq.o irq_ipr.o \
+obj-y := process.o signal.o entry.o traps.o irq.o \
ptrace.o setup.o time.o sys_sh.o semaphore.o \
- irq_imask.o io.o io_generic.o sh_ksyms.o
+ io.o io_generic.o sh_ksyms.o
+obj-y += cpu/
+
+obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
-obj-$(CONFIG_CPU_SH4) += fpu.o
-obj-$(CONFIG_SH_RTC) += rtc.o
-obj-$(CONFIG_SH_DMA) += dma.o
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
+obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
-ifeq ($(CONFIG_PCI),y)
-ifeq ($(CONFIG_SH_DREAMCAST),y)
-obj-y += pci-dc.o pcibios.o
-else
-obj-y += pci-dma.o pcibios.o
-obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)+= pci_st40.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7751)+= pci-sh7751.o
-obj-$(CONFIG_SH_BIGSUR)+= pci-bigsur.o
-obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= pci-7751se.o
-endif
+ifneq ($(CONFIG_SH_DREAMCAST),y)
+obj-$(CONFIG_PCI) += pci-dma.o
endif
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_PCI_AUTO) += pci_auto.o
-obj-$(CONFIG_SH_HP600) += mach_hp600.o
-machine-specific-objs += mach_hp600.o
-
-obj-$(CONFIG_SH_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o
-machine-specific-objs += mach_se.o setup_se.o io_se.o led_se.o
-
-obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_7751se.o setup_7751se.o \
- io_7751se.o led_7751se.o
-machine-specific-objs += mach_7751se.o 7751setup_se.o \
- io_7751se.o led_7751se.o pci-7751se.o
-
-obj-$(CONFIG_SH_BIGSUR) += mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
-machine-specific-objs += mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
-
-obj-$(CONFIG_SH_SH2000) += setup_sh2000.o io_sh2000.o
-machine-specific-objs += setup_sh2000.o io_sh2000.o
-
-obj-$(CONFIG_SH_CAT68701) += mach_cat68701.o io_cat68701.o
-machine-specific-objs += mach_cat68701.o io_cat68701.o
+USE_STANDARD_AS_RULE := true
-obj-$(CONFIG_SH_CQREEK) += setup_cqreek.o
-machine-specific-objs += setup_cqreek.o
-
-obj-$(CONFIG_SH_UNKNOWN) += mach_unknown.o io_unknown.o
-machine-specific-objs += mach_unknown.o io_unknown.o
-
-obj-$(CONFIG_HD64461) += setup_hd64461.o io_hd64461.o
-machine-specific-objs += setup_hd64461.o io_hd64461.o
-
-obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) +=irq_intc2.o
-
-obj-$(CONFIG_SH_ADX) += mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
-machine-specific-objs += mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
-
-# Doesn't compile well, so don't include in machine-specific-objs
-obj-$(CONFIG_HD64465) += setup_hd64465.o io_hd64465.o hd64465_gpio.o
-obj-$(CONFIG_SH_DMIDA) += mach_dmida.o
-obj-$(CONFIG_SH_EC3104) += setup_ec3104.o io_ec3104.o mach_ec3104.o
-obj-$(CONFIG_SH_DREAMCAST) += mach_dc.o setup_dc.o io_dc.o rtc-aica.o
-
-ifeq ($(CONFIG_SH_GENERIC),y)
-obj-y += $(machine-specific-objs)
-endif
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 4840456c4d45..e920a5954788 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -1,4 +1,4 @@
-/* $Id: io_generic.c,v 1.12 2000/11/14 16:45:11 sugioka Exp $
+/* $Id: io_generic.c,v 1.1.1.1.4.2.2.1 2003/01/10 17:26:56 lethal Exp $
*
* linux/arch/sh/kernel/io_generic.c
*
@@ -17,7 +17,7 @@
#include <asm/machvec.h>
#include <linux/module.h>
-#if defined(__sh3__)
+#if defined(CONFIG_CPU_SH3)
/* I'm not sure SH7709 has this kind of bug */
#define SH3_PCMCIA_BUG_WORKAROUND 1
#define DUMMY_READ_AREA6 0xba000000
diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c
deleted file mode 100644
index 7de64f4d4974..000000000000
--- a/arch/sh/kernel/irq_imask.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* $Id: irq_imask.c,v 1.13 2001/07/12 08:13:56 gniibe Exp $
- *
- * linux/arch/sh/kernel/irq_imask.c
- *
- * Copyright (C) 1999, 2000 Niibe Yutaka
- *
- * Simple interrupt handling using IMASK of SR register.
- *
- */
-
-/* NOTE: Will not work on level 15 */
-
-
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/bitops.h>
-
-#include <linux/spinlock.h>
-#include <linux/cache.h>
-#include <linux/irq.h>
-
-/* Bitmap of IRQ masked */
-static unsigned long imask_mask = 0x7fff;
-static int interrupt_priority = 0;
-
-static void enable_imask_irq(unsigned int irq);
-static void disable_imask_irq(unsigned int irq);
-static void shutdown_imask_irq(unsigned int irq);
-static void mask_and_ack_imask(unsigned int);
-static void end_imask_irq(unsigned int irq);
-
-#define IMASK_PRIORITY 15
-
-static unsigned int startup_imask_irq(unsigned int irq)
-{
- /* Nothing to do */
- return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type imask_irq_type = {
- "SR.IMASK",
- startup_imask_irq,
- shutdown_imask_irq,
- enable_imask_irq,
- disable_imask_irq,
- mask_and_ack_imask,
- end_imask_irq
-};
-
-void static inline set_interrupt_registers(int ip)
-{
- unsigned long __dummy;
-
- asm volatile("ldc %2, r6_bank\n\t"
- "stc sr, %0\n\t"
- "and #0xf0, %0\n\t"
- "shlr2 %0\n\t"
- "cmp/eq #0x3c, %0\n\t"
- "bt/s 1f ! CLI-ed\n\t"
- " stc sr, %0\n\t"
- "and %1, %0\n\t"
- "or %2, %0\n\t"
- "ldc %0, sr\n"
- "1:"
- : "=&z" (__dummy)
- : "r" (~0xf0), "r" (ip << 4)
- : "t");
-}
-
-static void disable_imask_irq(unsigned int irq)
-{
- clear_bit(irq, &imask_mask);
- if (interrupt_priority < IMASK_PRIORITY - irq)
- interrupt_priority = IMASK_PRIORITY - irq;
-
- set_interrupt_registers(interrupt_priority);
-}
-
-static void enable_imask_irq(unsigned int irq)
-{
- set_bit(irq, &imask_mask);
- interrupt_priority = IMASK_PRIORITY - ffz(imask_mask);
-
- set_interrupt_registers(interrupt_priority);
-}
-
-static void mask_and_ack_imask(unsigned int irq)
-{
- disable_imask_irq(irq);
-}
-
-static void end_imask_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_imask_irq(irq);
-}
-
-static void shutdown_imask_irq(unsigned int irq)
-{
- /* Nothing to do */
-}
-
-void make_imask_irq(unsigned int irq)
-{
- disable_irq_nosync(irq);
- irq_desc[irq].handler = &imask_irq_type;
- enable_irq(irq);
-}
diff --git a/arch/sh/kernel/irq_intc2.c b/arch/sh/kernel/irq_intc2.c
deleted file mode 100644
index e74110fe51b8..000000000000
--- a/arch/sh/kernel/irq_intc2.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * linux/arch/sh/kernel/irq_intc2.c
- *
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Interrupt handling for INTC2-based IRQ.
- *
- * These are the "new Hitachi style" interrupts, as present on the
- * Hitachi 7751 and the STM ST40 STB1.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/machvec.h>
-
-
-struct intc2_data {
- unsigned int addr; /* Address of Interrupt Priority Register */
- int mask; /*Mask to apply */
-};
-
-
-static struct intc2_data intc2_data[NR_INTC2_IRQS];
-
-static void enable_intc2_irq(unsigned int irq);
-static void disable_intc2_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_intc2_irq disable_intc2_irq
-
-static void mask_and_ack_intc2(unsigned int);
-static void end_intc2_irq(unsigned int irq);
-
-static unsigned int startup_intc2_irq(unsigned int irq)
-{
- enable_intc2_irq(irq);
- return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type intc2_irq_type = {
- "INTC2-IRQ",
- startup_intc2_irq,
- shutdown_intc2_irq,
- enable_intc2_irq,
- disable_intc2_irq,
- mask_and_ack_intc2,
- end_intc2_irq
-};
-
-static void disable_intc2_irq(unsigned int irq)
-{
- unsigned addr;
- int offset=irq-INTC2_FIRST_IRQ;
- unsigned val,flags;
-
- // Sanity check
- if(offset<0 || offset>=NR_INTC2_IRQS) return;
-
- addr=intc2_data[offset].addr+INTC2_INTMSK_OFFSET;
-
- save_and_cli(flags);
- val=ctrl_inl(addr);
- val|=intc2_data[offset].mask;
- ctrl_outl(val,addr);
-
- restore_flags(flags);
-}
-
-static void enable_intc2_irq(unsigned int irq)
-{
- int offset=irq-INTC2_FIRST_IRQ;
-
- // Sanity check
- if(offset<0 || offset>=NR_INTC2_IRQS) return;
-
- ctrl_outl(intc2_data[offset].mask,
- intc2_data[offset].addr+INTC2_INTMSKCLR_OFFSET);
-
-}
-
-static void mask_and_ack_intc2(unsigned int irq)
-{
- disable_intc2_irq(irq);
-}
-
-static void end_intc2_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_intc2_irq(irq);
-}
-
-void make_intc2_irq(unsigned int irq, unsigned int addr,
- unsigned int group,int pos, int priority)
-{
- int offset=irq-INTC2_FIRST_IRQ;
- unsigned flags,val;
-
- if(offset<0 || offset>=NR_INTC2_IRQS) {
- return;
- }
-
- disable_irq_nosync(irq);
- /* Fill the data we need */
- intc2_data[offset].addr=addr;
- intc2_data[offset].mask=1<<pos;
-
- /* Set the priority level */
- save_and_cli(flags);
- val=ctrl_inl(addr+INTC2_INTPRI_OFFSET);
- val|=(priority)<< (group<<4);
- ctrl_outl(val,addr+INTC2_INTPRI_OFFSET);
- restore_flags(flags);
-
- irq_desc[irq].handler=&intc2_irq_type;
-
- disable_intc2_irq(irq);
-}
-
-
-
diff --git a/arch/sh/kernel/irq_ipr.c b/arch/sh/kernel/irq_ipr.c
deleted file mode 100644
index e43e505a6fe4..000000000000
--- a/arch/sh/kernel/irq_ipr.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/* $Id: irq_ipr.c,v 1.20 2001/07/15 23:26:56 gniibe Exp $
- *
- * linux/arch/sh/kernel/irq_ipr.c
- *
- * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi
- * Copyright (C) 2000 Kazumoto Kojima
- *
- * Interrupt handling for IPR-based IRQ.
- *
- * Supported system:
- * On-chip supporting modules (TMU, RTC, etc.).
- * On-chip supporting modules for SH7709/SH7709A/SH7729.
- * Hitachi SolutionEngine external I/O:
- * MS7709SE01, MS7709ASE01, and MS7750SE01
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/machvec.h>
-
-struct ipr_data {
- unsigned int addr; /* Address of Interrupt Priority Register */
- int shift; /* Shifts of the 16-bit data */
- int priority; /* The priority */
-};
-static struct ipr_data ipr_data[NR_IRQS];
-
-static void enable_ipr_irq(unsigned int irq);
-static void disable_ipr_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_ipr_irq disable_ipr_irq
-
-static void mask_and_ack_ipr(unsigned int);
-static void end_ipr_irq(unsigned int irq);
-
-static unsigned int startup_ipr_irq(unsigned int irq)
-{
- enable_ipr_irq(irq);
- return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type ipr_irq_type = {
- "IPR-IRQ",
- startup_ipr_irq,
- shutdown_ipr_irq,
- enable_ipr_irq,
- disable_ipr_irq,
- mask_and_ack_ipr,
- end_ipr_irq
-};
-
-static void disable_ipr_irq(unsigned int irq)
-{
- unsigned long val, flags;
- unsigned int addr = ipr_data[irq].addr;
- unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
-
- /* Set the priority in IPR to 0 */
- save_and_cli(flags);
- val = ctrl_inw(addr);
- val &= mask;
- ctrl_outw(val, addr);
- restore_flags(flags);
-}
-
-static void enable_ipr_irq(unsigned int irq)
-{
- unsigned long val, flags;
- unsigned int addr = ipr_data[irq].addr;
- int priority = ipr_data[irq].priority;
- unsigned short value = (priority << ipr_data[irq].shift);
-
- /* Set priority in IPR back to original value */
- save_and_cli(flags);
- val = ctrl_inw(addr);
- val |= value;
- ctrl_outw(val, addr);
- restore_flags(flags);
-}
-
-static void mask_and_ack_ipr(unsigned int irq)
-{
- disable_ipr_irq(irq);
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
- /* This is needed when we use edge triggered setting */
- /* XXX: Is it really needed? */
- if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
- /* Clear external interrupt request */
- int a = ctrl_inb(INTC_IRR0);
- a &= ~(1 << (irq - IRQ0_IRQ));
- ctrl_outb(a, INTC_IRR0);
- }
-#endif
-}
-
-static void end_ipr_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_ipr_irq(irq);
-}
-
-void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
-{
- disable_irq_nosync(irq);
- ipr_data[irq].addr = addr;
- ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
- ipr_data[irq].priority = priority;
-
- irq_desc[irq].handler = &ipr_irq_type;
- disable_ipr_irq(irq);
-}
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
-static unsigned char pint_map[256];
-static unsigned long portcr_mask = 0;
-
-static void enable_pint_irq(unsigned int irq);
-static void disable_pint_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_pint_irq disable_pint_irq
-
-static void mask_and_ack_pint(unsigned int);
-static void end_pint_irq(unsigned int irq);
-
-static unsigned int startup_pint_irq(unsigned int irq)
-{
- enable_pint_irq(irq);
- return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type pint_irq_type = {
- "PINT-IRQ",
- startup_pint_irq,
- shutdown_pint_irq,
- enable_pint_irq,
- disable_pint_irq,
- mask_and_ack_pint,
- end_pint_irq
-};
-
-static void disable_pint_irq(unsigned int irq)
-{
- unsigned long val, flags;
-
- save_and_cli(flags);
- val = ctrl_inw(INTC_INTER);
- val &= ~(1 << (irq - PINT_IRQ_BASE));
- ctrl_outw(val, INTC_INTER); /* disable PINTn */
- portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2);
- restore_flags(flags);
-}
-
-static void enable_pint_irq(unsigned int irq)
-{
- unsigned long val, flags;
-
- save_and_cli(flags);
- val = ctrl_inw(INTC_INTER);
- val |= 1 << (irq - PINT_IRQ_BASE);
- ctrl_outw(val, INTC_INTER); /* enable PINTn */
- portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2;
- restore_flags(flags);
-}
-
-static void mask_and_ack_pint(unsigned int irq)
-{
- disable_pint_irq(irq);
-}
-
-static void end_pint_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_pint_irq(irq);
-}
-
-void make_pint_irq(unsigned int irq)
-{
- disable_irq_nosync(irq);
- irq_desc[irq].handler = &pint_irq_type;
- disable_pint_irq(irq);
-}
-#endif
-
-void __init init_IRQ(void)
-{
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
- int i;
-#endif
-
- make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
- make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
-
-#ifdef SCI_ERI_IRQ
- make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
- make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
- make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-#endif
-
-#ifdef SCIF1_ERI_IRQ
- make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
- make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
- make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
- make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-#endif
-
-#ifdef SCIF_ERI_IRQ
- make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
- make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
- make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
- make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-#endif
-
-#ifdef IRDA_ERI_IRQ
- make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
- make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
- make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
- make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-#endif
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
- /*
- * Initialize the Interrupt Controller (INTC)
- * registers to their power on values
- */
-
- /*
- * Enable external irq (INTC IRQ mode).
- * You should set corresponding bits of PFC to "00"
- * to enable these interrupts.
- */
- make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
- make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
- make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
- make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
- make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
- make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
- make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY);
- make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY);
- enable_ipr_irq(PINT0_IRQ);
- enable_ipr_irq(PINT8_IRQ);
-
- for(i = 0; i < 16; i++)
- make_pint_irq(PINT_IRQ_BASE + i);
- for(i = 0; i < 256; i++)
- {
- if(i & 1) pint_map[i] = 0;
- else if(i & 2) pint_map[i] = 1;
- else if(i & 4) pint_map[i] = 2;
- else if(i & 8) pint_map[i] = 3;
- else if(i & 0x10) pint_map[i] = 4;
- else if(i & 0x20) pint_map[i] = 5;
- else if(i & 0x40) pint_map[i] = 6;
- else if(i & 0x80) pint_map[i] = 7;
- }
-#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */
-
- /* Perform the machine specific initialisation */
- if (sh_mv.mv_init_irq != NULL) {
- sh_mv.mv_init_irq();
- }
-}
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
-int ipr_irq_demux(int irq)
-{
- unsigned long creg, dreg, d, sav;
-
- if(irq == PINT0_IRQ)
- {
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
- creg = PORT_PACR;
- dreg = PORT_PADR;
-#else
- creg = PORT_PCCR;
- dreg = PORT_PCDR;
-#endif
- sav = ctrl_inw(creg);
- ctrl_outw(sav | portcr_mask, creg);
- d = (~ctrl_inb(dreg) ^ ctrl_inw(INTC_ICR2)) & ctrl_inw(INTC_INTER) & 0xff;
- ctrl_outw(sav, creg);
- if(d == 0) return irq;
- return PINT_IRQ_BASE + pint_map[d];
- }
- else if(irq == PINT8_IRQ)
- {
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
- creg = PORT_PBCR;
- dreg = PORT_PBDR;
-#else
- creg = PORT_PFCR;
- dreg = PORT_PFDR;
-#endif
- sav = ctrl_inw(creg);
- ctrl_outw(sav | (portcr_mask >> 16), creg);
- d = (~ctrl_inb(dreg) ^ (ctrl_inw(INTC_ICR2) >> 8)) & (ctrl_inw(INTC_INTER) >> 8) & 0xff;
- ctrl_outw(sav, creg);
- if(d == 0) return irq;
- return PINT_IRQ_BASE + 8 + pint_map[d];
- }
- return irq;
-}
-#endif
diff --git a/arch/sh/kernel/mach_7751se.c b/arch/sh/kernel/mach_7751se.c
deleted file mode 100644
index d3f5aaf8d271..000000000000
--- a/arch/sh/kernel/mach_7751se.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_7751se.c
- *
- * Minor tweak of mach_se.c file to reference 7751se-specific items.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine vector for the Hitachi 7751 SolutionEngine
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io_7751se.h>
-
-void heartbeat_7751se(void);
-void setup_7751se(void);
-void init_7751se_IRQ(void);
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_7751se __initmv = {
- .mv_name = "7751 SolutionEngine",
-
- .mv_nr_irqs = 72,
-
- .mv_inb = sh7751se_inb,
- .mv_inw = sh7751se_inw,
- .mv_inl = sh7751se_inl,
- .mv_outb = sh7751se_outb,
- .mv_outw = sh7751se_outw,
- .mv_outl = sh7751se_outl,
-
- .mv_inb_p = sh7751se_inb_p,
- .mv_inw_p = sh7751se_inw,
- .mv_inl_p = sh7751se_inl,
- .mv_outb_p = sh7751se_outb_p,
- .mv_outw_p = sh7751se_outw,
- .mv_outl_p = sh7751se_outl,
-
- .mv_insb = sh7751se_insb,
- .mv_insw = sh7751se_insw,
- .mv_insl = sh7751se_insl,
- .mv_outsb = sh7751se_outsb,
- .mv_outsw = sh7751se_outsw,
- .mv_outsl = sh7751se_outsl,
-
- .mv_readb = sh7751se_readb,
- .mv_readw = sh7751se_readw,
- .mv_readl = sh7751se_readl,
- .mv_writeb = sh7751se_writeb,
- .mv_writew = sh7751se_writew,
- .mv_writel = sh7751se_writel,
-
- .mv_ioremap = generic_ioremap,
- .mv_iounmap = generic_iounmap,
-
- .mv_isa_port2addr = sh7751se_isa_port2addr,
-
- .mv_init_arch = setup_7751se,
- .mv_init_irq = init_7751se_IRQ,
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_7751se,
-#endif
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_7751se = 1,
-};
-ALIAS_MV(7751se)
diff --git a/arch/sh/kernel/mach_adx.c b/arch/sh/kernel/mach_adx.c
deleted file mode 100644
index 4aec80cf1e35..000000000000
--- a/arch/sh/kernel/mach_adx.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_adx.c
- *
- * Copyright (C) 2001 A&D Co., Ltd.
- *
- * This file may be copied or modified under the terms of the GNU
- * General Public License. See linux/COPYING for more information.
- *
- * Machine vector for the A&D ADX Board
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-#include <asm/io_adx.h>
-
-extern void setup_adx(void);
-extern void init_adx_IRQ(void);
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_adx __initmv = {
- .mv_name = "A&D_ADX",
-
- .mv_nr_irqs = 48,
-
- .mv_inb = adx_inb,
- .mv_inw = adx_inw,
- .mv_inl = adx_inl,
- .mv_outb = adx_outb,
- .mv_outw = adx_outw,
- .mv_outl = adx_outl,
-
- .mv_inb_p = adx_inb_p,
- .mv_inw_p = adx_inw,
- .mv_inl_p = adx_inl,
- .mv_outb_p = adx_outb_p,
- .mv_outw_p = adx_outw,
- .mv_outl_p = adx_outl,
-
- .mv_insb = adx_insb,
- .mv_insw = adx_insw,
- .mv_insl = adx_insl,
- .mv_outsb = adx_outsb,
- .mv_outsw = adx_outsw,
- .mv_outsl = adx_outsl,
-
- .mv_readb = adx_readb,
- .mv_readw = adx_readw,
- .mv_readl = adx_readl,
- .mv_writeb = adx_writeb,
- .mv_writew = adx_writew,
- .mv_writel = adx_writel,
-
- .mv_ioremap = adx_ioremap,
- .mv_iounmap = adx_iounmap,
-
- .mv_isa_port2addr = adx_isa_port2addr,
-
- .mv_init_arch = setup_adx,
- .mv_init_irq = init_adx_IRQ,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_adx = 1,
-};
-ALIAS_MV(adx)
diff --git a/arch/sh/kernel/mach_bigsur.c b/arch/sh/kernel/mach_bigsur.c
deleted file mode 100644
index e4a419c1b22f..000000000000
--- a/arch/sh/kernel/mach_bigsur.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_bigsur.c
- *
- * By Dustin McIntire (dustin@sensoria.com) (c)2001
- * Derived from mach_se.h, which bore the message:
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine vector for the Hitachi Big Sur Evaluation Board
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-#include <asm/io.h>
-#include <asm/io_bigsur.h>
-#include <asm/irq.h>
-
-/*
- * The Machine Vector
- */
-extern void heartbeat_bigsur(void);
-extern void setup_bigsur(void);
-extern void init_bigsur_IRQ(void);
-
-struct sh_machine_vector mv_bigsur __initmv = {
- .mv_name = "Big Sur",
- .mv_nr_irqs = NR_IRQS, // Defined in <asm/irq.h>
- .mv_inb = bigsur_inb,
- .mv_inw = bigsur_inw,
- .mv_inl = bigsur_inl,
- .mv_outb = bigsur_outb,
- .mv_outw = bigsur_outw,
- .mv_outl = bigsur_outl,
-
- .mv_inb_p = bigsur_inb_p,
- .mv_inw_p = bigsur_inw,
- .mv_inl_p = bigsur_inl,
- .mv_outb_p = bigsur_outb_p,
- .mv_outw_p = bigsur_outw,
- .mv_outl_p = bigsur_outl,
-
- .mv_insb = bigsur_insb,
- .mv_insw = bigsur_insw,
- .mv_insl = bigsur_insl,
- .mv_outsb = bigsur_outsb,
- .mv_outsw = bigsur_outsw,
- .mv_outsl = bigsur_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_ioremap = generic_ioremap,
- .mv_iounmap = generic_iounmap,
-
- .mv_isa_port2addr = bigsur_isa_port2addr,
- .mv_irq_demux = bigsur_irq_demux,
-
- .mv_init_arch = setup_bigsur,
- .mv_init_irq = init_bigsur_IRQ,
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_bigsur,
-#endif
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
-};
-ALIAS_MV(bigsur)
diff --git a/arch/sh/kernel/mach_cat68701.c b/arch/sh/kernel/mach_cat68701.c
deleted file mode 100644
index 352419ece2b4..000000000000
--- a/arch/sh/kernel/mach_cat68701.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_cat68701.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- * 2001 Yutaro Ebihara (ebihara@si-linux.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine vector for the A-ONE corp. CAT-68701 SH7708 board
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-#include <asm/io_cat68701.h>
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_cat68701 __initmv = {
- .mv_name = "CAT-68701",
- .mv_nr_irqs = 32,
- .mv_inb = cat68701_inb,
- .mv_inw = cat68701_inw,
- .mv_inl = cat68701_inl,
- .mv_outb = cat68701_outb,
- .mv_outw = cat68701_outw,
- .mv_outl = cat68701_outl,
-
- .mv_inb_p = cat68701_inb_p,
- .mv_inw_p = cat68701_inw,
- .mv_inl_p = cat68701_inl,
- .mv_outb_p = cat68701_outb_p,
- .mv_outw_p = cat68701_outw,
- .mv_outl_p = cat68701_outl,
-
- .mv_insb = cat68701_insb,
- .mv_insw = cat68701_insw,
- .mv_insl = cat68701_insl,
- .mv_outsb = cat68701_outsb,
- .mv_outsw = cat68701_outsw,
- .mv_outsl = cat68701_outsl,
-
- .mv_readb = cat68701_readb,
- .mv_readw = cat68701_readw,
- .mv_readl = cat68701_readl,
- .mv_writeb = cat68701_writeb,
- .mv_writew = cat68701_writew,
- .mv_writel = cat68701_writel,
-
- .mv_ioremap = cat68701_ioremap,
- .mv_iounmap = cat68701_iounmap,
-
- .mv_isa_port2addr = cat68701_isa_port2addr,
- .mv_irq_demux = cat68701_irq_demux,
-
- .mv_init_arch = setup_cat68701,
- .mv_init_irq = init_cat68701_IRQ,
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_cat68701,
-#endif
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
-};
-ALIAS_MV(cat68701)
diff --git a/arch/sh/kernel/mach_dc.c b/arch/sh/kernel/mach_dc.c
deleted file mode 100644
index f9eccfad100f..000000000000
--- a/arch/sh/kernel/mach_dc.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * $Id: mach_dc.c,v 1.5 2001/09/01 14:34:31 mrbrown Exp $
- * SEGA Dreamcast machine vector
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/time.h>
-
-#include <asm/machvec.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io_generic.h>
-#include <asm/io_dc.h>
-#include <asm/irq.h>
-
-void __init setup_dreamcast(void);
-void __init dreamcast_pcibios_init(void);
-
-/* Custom Dreamcast RTC routines */
-void aica_rtc_gettimeofday(struct timeval *tv);
-int aica_rtc_settimeofday(const struct timeval *tv);
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_dreamcast __initmv = {
- .mv_name = "dreamcast",
-
- .mv_nr_irqs = NR_IRQS,
-
- .mv_inb = generic_inb,
- .mv_inw = generic_inw,
- .mv_inl = generic_inl,
- .mv_outb = generic_outb,
- .mv_outw = generic_outw,
- .mv_outl = generic_outl,
-
- .mv_inb_p = generic_inb_p,
- .mv_inw_p = generic_inw,
- .mv_inl_p = generic_inl,
- .mv_outb_p = generic_outb_p,
- .mv_outw_p = generic_outw,
- .mv_outl_p = generic_outl,
-
- .mv_insb = generic_insb,
- .mv_insw = generic_insw,
- .mv_insl = generic_insl,
- .mv_outsb = generic_outsb,
- .mv_outsw = generic_outsw,
- .mv_outsl = generic_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_ioremap = generic_ioremap,
- .mv_iounmap = generic_iounmap,
-
- .mv_init_arch = setup_dreamcast,
- .mv_isa_port2addr = dreamcast_isa_port2addr,
- .mv_irq_demux = systemasic_irq_demux,
-
- .mv_rtc_gettimeofday = aica_rtc_gettimeofday,
- .mv_rtc_settimeofday = aica_rtc_settimeofday,
-
- .mv_hw_dreamcast = 1,
-};
-ALIAS_MV(dreamcast)
diff --git a/arch/sh/kernel/mach_dmida.c b/arch/sh/kernel/mach_dmida.c
deleted file mode 100644
index a94a9d7e9ce4..000000000000
--- a/arch/sh/kernel/mach_dmida.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_dmida.c
- *
- * by Greg Banks <gbanks@pocketpenguins.com>
- * (c) 2000 PocketPenguins Inc
- *
- * Derived from mach_hp600.c, which bore the message:
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine vector for the DataMyte Industrial Digital Assistant(tm).
- * See http://www.dmida.com
- *
- */
-
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io.h>
-#include <asm/hd64465.h>
-#include <asm/irq.h>
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_dmida __initmv = {
- .mv_name = "DMIDA",
-
- .mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM,
-
- .mv_inb = hd64465_inb,
- .mv_inw = hd64465_inw,
- .mv_inl = hd64465_inl,
- .mv_outb = hd64465_outb,
- .mv_outw = hd64465_outw,
- .mv_outl = hd64465_outl,
-
- .mv_inb_p = hd64465_inb_p,
- .mv_inw_p = hd64465_inw,
- .mv_inl_p = hd64465_inl,
- .mv_outb_p = hd64465_outb_p,
- .mv_outw_p = hd64465_outw,
- .mv_outl_p = hd64465_outl,
-
- .mv_insb = hd64465_insb,
- .mv_insw = hd64465_insw,
- .mv_insl = hd64465_insl,
- .mv_outsb = hd64465_outsb,
- .mv_outsw = hd64465_outsw,
- .mv_outsl = hd64465_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_irq_demux = hd64465_irq_demux,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_hd64465 = 1,
-};
-ALIAS_MV(dmida)
-
diff --git a/arch/sh/kernel/mach_ec3104.c b/arch/sh/kernel/mach_ec3104.c
deleted file mode 100644
index 46df3a051227..000000000000
--- a/arch/sh/kernel/mach_ec3104.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_ec3104.c
- * EC3104 companion chip support
- *
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- */
-/* EC3104 note:
- * This code was written without any documentation about the EC3104 chip. While
- * I hope I got most of the basic functionality right, the register names I use
- * are most likely completely different from those in the chip documentation.
- *
- * If you have any further information about the EC3104, please tell me
- * (prumpf@tux.org).
- */
-
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_ec3104 __initmv = {
- .mv_name = "EC3104",
-
- .mv_nr_irqs = 96,
-
- .mv_inb = ec3104_inb,
- .mv_inw = ec3104_inw,
- .mv_inl = ec3104_inl,
- .mv_outb = ec3104_outb,
- .mv_outw = ec3104_outw,
- .mv_outl = ec3104_outl,
-
- .mv_inb_p = generic_inb_p,
- .mv_inw_p = generic_inw,
- .mv_inl_p = generic_inl,
- .mv_outb_p = generic_outb_p,
- .mv_outw_p = generic_outw,
- .mv_outl_p = generic_outl,
-
- .mv_insb = generic_insb,
- .mv_insw = generic_insw,
- .mv_insl = generic_insl,
- .mv_outsb = generic_outsb,
- .mv_outsw = generic_outsw,
- .mv_outsl = generic_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_irq_demux = ec3104_irq_demux,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-};
-
-ALIAS_MV(ec3104)
diff --git a/arch/sh/kernel/mach_hp600.c b/arch/sh/kernel/mach_hp600.c
deleted file mode 100644
index 50ca56ce6b89..000000000000
--- a/arch/sh/kernel/mach_hp600.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_hp600.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine vector for the HP600
- */
-
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io.h>
-#include <asm/hd64461.h>
-#include <asm/irq.h>
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_hp620 __initmv = {
- .mv_name = "hp620",
-
- .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM,
-
- .mv_inb = hd64461_inb,
- .mv_inw = hd64461_inw,
- .mv_inl = hd64461_inl,
- .mv_outb = hd64461_outb,
- .mv_outw = hd64461_outw,
- .mv_outl = hd64461_outl,
-
- .mv_inb_p = hd64461_inb_p,
- .mv_inw_p = hd64461_inw,
- .mv_inl_p = hd64461_inl,
- .mv_outb_p = hd64461_outb_p,
- .mv_outw_p = hd64461_outw,
- .mv_outl_p = hd64461_outl,
-
- .mv_insb = hd64461_insb,
- .mv_insw = hd64461_insw,
- .mv_insl = hd64461_insl,
- .mv_outsb = hd64461_outsb,
- .mv_outsw = hd64461_outsw,
- .mv_outsl = hd64461_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_irq_demux = hd64461_irq_demux,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_hp600 = 1,
- .mv_hw_hp620 = 1,
- .mv_hw_hd64461 = 1,
-};
-ALIAS_MV(hp620)
-
-
-struct sh_machine_vector mv_hp680 __initmv = {
- .mv_name = "hp680",
-
- .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM,
-
- .mv_inb = hd64461_inb,
- .mv_inw = hd64461_inw,
- .mv_inl = hd64461_inl,
- .mv_outb = hd64461_outb,
- .mv_outw = hd64461_outw,
- .mv_outl = hd64461_outl,
-
- .mv_inb_p = hd64461_inb_p,
- .mv_inw_p = hd64461_inw,
- .mv_inl_p = hd64461_inl,
- .mv_outb_p = hd64461_outb_p,
- .mv_outw_p = hd64461_outw,
- .mv_outl_p = hd64461_outl,
-
- .mv_insb = hd64461_insb,
- .mv_insw = hd64461_insw,
- .mv_insl = hd64461_insl,
- .mv_outsb = hd64461_outsb,
- .mv_outsw = hd64461_outsw,
- .mv_outsl = hd64461_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_irq_demux = hd64461_irq_demux,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_hp600 = 1,
- .mv_hw_hp680 = 1,
- .mv_hw_hd64461 = 1,
-};
-ALIAS_MV(hp680)
-
-
-struct sh_machine_vector mv_hp690 __initmv = {
- .mv_name = "hp690",
-
- .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM,
-
- .mv_inb = hd64461_inb,
- .mv_inw = hd64461_inw,
- .mv_inl = hd64461_inl,
- .mv_outb = hd64461_outb,
- .mv_outw = hd64461_outw,
- .mv_outl = hd64461_outl,
-
- .mv_inb_p = hd64461_inb_p,
- .mv_inw_p = hd64461_inw,
- .mv_inl_p = hd64461_inl,
- .mv_outb_p = hd64461_outb_p,
- .mv_outw_p = hd64461_outw,
- .mv_outl_p = hd64461_outl,
-
- .mv_insb = hd64461_insb,
- .mv_insw = hd64461_insw,
- .mv_insl = hd64461_insl,
- .mv_outsb = hd64461_outsb,
- .mv_outsw = hd64461_outsw,
- .mv_outsl = hd64461_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_irq_demux = hd64461_irq_demux,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_hp600 = 1,
- .mv_hw_hp690 = 1,
- .mv_hw_hd64461 = 1,
-};
-ALIAS_MV(hp690)
diff --git a/arch/sh/kernel/mach_se.c b/arch/sh/kernel/mach_se.c
deleted file mode 100644
index c1241da421cb..000000000000
--- a/arch/sh/kernel/mach_se.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_se.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine vector for the Hitachi SolutionEngine
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io_se.h>
-
-void heartbeat_se(void);
-void setup_se(void);
-void init_se_IRQ(void);
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_se __initmv = {
- .mv_name = "SolutionEngine",
-
-#if defined(__SH4__)
- .mv_nr_irqs = 48,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
- .mv_nr_irqs = 32,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
- .mv_nr_irqs = 61,
-#endif
-
- .mv_inb = se_inb,
- .mv_inw = se_inw,
- .mv_inl = se_inl,
- .mv_outb = se_outb,
- .mv_outw = se_outw,
- .mv_outl = se_outl,
-
- .mv_inb_p = se_inb_p,
- .mv_inw_p = se_inw,
- .mv_inl_p = se_inl,
- .mv_outb_p = se_outb_p,
- .mv_outw_p = se_outw,
- .mv_outl_p = se_outl,
-
- .mv_insb = se_insb,
- .mv_insw = se_insw,
- .mv_insl = se_insl,
- .mv_outsb = se_outsb,
- .mv_outsw = se_outsw,
- .mv_outsl = se_outsl,
-
- .mv_readb = se_readb,
- .mv_readw = se_readw,
- .mv_readl = se_readl,
- .mv_writeb = se_writeb,
- .mv_writew = se_writew,
- .mv_writel = se_writel,
-
- .mv_ioremap = generic_ioremap,
- .mv_iounmap = generic_iounmap,
-
- .mv_isa_port2addr = se_isa_port2addr,
-
- .mv_init_arch = setup_se,
- .mv_init_irq = init_se_IRQ,
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_se,
-#endif
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_se = 1,
-};
-ALIAS_MV(se)
diff --git a/arch/sh/kernel/mach_unknown.c b/arch/sh/kernel/mach_unknown.c
deleted file mode 100644
index 75cff0d139af..000000000000
--- a/arch/sh/kernel/mach_unknown.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * linux/arch/sh/kernel/mach_unknown.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine specific code for an unknown machine (internal peripherials only)
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/machvec_init.h>
-
-#include <asm/io_unknown.h>
-
-#include <asm/rtc.h>
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_unknown __initmv = {
- .mv_name = "Unknown",
-
-#if defined(__SH4__)
- .mv_nr_irqs = 48,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
- .mv_nr_irqs = 32,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
- .mv_nr_irqs = 61,
-#endif
-
- .mv_inb = unknown_inb,
- .mv_inw = unknown_inw,
- .mv_inl = unknown_inl,
- .mv_outb = unknown_outb,
- .mv_outw = unknown_outw,
- .mv_outl = unknown_outl,
-
- .mv_inb_p = unknown_inb_p,
- .mv_inw_p = unknown_inw_p,
- .mv_inl_p = unknown_inl_p,
- .mv_outb_p = unknown_outb_p,
- .mv_outw_p = unknown_outw_p,
- .mv_outl_p = unknown_outl_p,
-
- .mv_insb = unknown_insb,
- .mv_insw = unknown_insw,
- .mv_insl = unknown_insl,
- .mv_outsb = unknown_outsb,
- .mv_outsw = unknown_outsw,
- .mv_outsl = unknown_outsl,
-
- .mv_readb = unknown_readb,
- .mv_readw = unknown_readw,
- .mv_readl = unknown_readl,
- .mv_writeb = unknown_writeb,
- .mv_writew = unknown_writew,
- .mv_writel = unknown_writel,
-
- .mv_ioremap = unknown_ioremap,
- .mv_iounmap = unknown_iounmap,
-
- .mv_isa_port2addr = unknown_isa_port2addr,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-};
-ALIAS_MV(unknown)
diff --git a/arch/sh/kernel/pci-sh7751.c b/arch/sh/kernel/pci-sh7751.c
deleted file mode 100644
index b1638f9501c2..000000000000
--- a/arch/sh/kernel/pci-sh7751.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Low-Level PCI Support for the SH7751
- *
- * Dustin McIntire (dustin@sensoria.com)
- * Derived from arch/i386/kernel/pci-*.c which bore the message:
- * (c) 1999--2000 Martin Mares <mj@ucw.cz>
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
-*/
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
-
-#include <asm/machvec.h>
-#include <asm/io.h>
-#include <asm/pci-sh7751.h>
-
-struct pci_ops *pci_check_direct(void);
-void pcibios_resource_survey(void);
-static u8 pcibios_swizzle(struct pci_dev *dev, u8 *pin);
-static int pcibios_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin);
-
-unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1;
-int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus;
-struct pci_ops *pci_root_ops;
-
-/*
- * Direct access to PCI hardware...
- */
-
-#ifdef CONFIG_PCI_DIRECT
-
-
-#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
-
-#define PCI_REG(reg) (SH7751_PCIREG_BASE+reg)
-
-/*
- * Functions for accessing PCI configuration space with type 1 accesses
- */
-static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
- u32 word;
- unsigned long flags;
-
- /* PCIPDR may only be accessed as 32 bit words,
- * so we must do byte alignment by hand
- */
- save_and_cli(flags);
- outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
- word = inl(PCI_REG(SH7751_PCIPDR));
- restore_flags(flags);
-
- switch (size) {
- case 1:
- switch (where & 0x3) {
- case 3:
- *value = (u8)(word >> 24);
- break;
- case 2:
- *value = (u8)(word >> 16);
- break;
- case 1:
- *value = (u8)(word >> 8);
- break;
- default:
- *value = (u8)word;
- break;
- }
- case 2:
- switch (where & 0x3) {
- case 3: /*This should never happen.*/
- printk(KERN_ERR "PCI BIOS: read_config: Illegal u16 alignment");
- return PCIBIOS_BAD_REGISTER_NUMBER;
- case 2:
- *value = (u16)(word >> 16);
- break;
- case 1:
- *value = (u16)(word >> 8);
- break;
- default:
- *value = (u16)word;
- break;
- }
- case 4:
- *value = word;
- break;
- }
- PCIDBG(4,"pci_conf1_read@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),*value);
- return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * Since SH7751 only does 32bit access we'll have to do a read,mask,write operation.
- * We'll allow an odd byte offset, though it should be illegal.
- */
-static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
- u32 word,mask;
- unsigned long flags;
- u32 shift = (where & 3) * 8;
-
- if(size == 1) {
- mask = ((1 << 8) - 1) << shift; // create the byte mask
- } else if(size == 2){
- if(shift == 24)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- mask = ((1 << 16) - 1) << shift; // create the word mask
- }
- save_and_cli(flags);
- outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
- if(size == 4){
- outl(value, PCI_REG(SH7751_PCIPDR));
- restore_flags(flags);
- PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),value);
- return PCIBIOS_SUCCESSFUL;
- }
- word = inl(PCI_REG(SH7751_PCIPDR)) ;
- word &= ~mask;
- word |= value << shift;
- outl(word, PCI_REG(SH7751_PCIPDR));
- restore_flags(flags);
- PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),word);
- return PCIBIOS_SUCCESSFUL;
-}
-
-#undef CONFIG_CMD
-
-static struct pci_ops pci_direct_conf1 = {
- .read = pci_conf1_read,
- .write = pci_conf1_write,
-};
-
-struct pci_ops * __init pci_check_direct(void)
-{
- unsigned int tmp, id;
-
- /* check for SH7751 hardware */
- id = (SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID;
- if(inl(SH7751_PCIREG_BASE+SH7751_PCICONF0) != id) {
- PCIDBG(2,"PCI: This is not an SH7751\n");
- return NULL;
- }
- /*
- * Check if configuration works.
- */
- if (pci_probe & PCI_PROBE_CONF1) {
- tmp = inl (PCI_REG(SH7751_PCIPAR));
- outl (0x80000000, PCI_REG(SH7751_PCIPAR));
- if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) {
- outl (tmp, PCI_REG(SH7751_PCIPAR));
- printk(KERN_INFO "PCI: Using configuration type 1\n");
- request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1");
- return &pci_direct_conf1;
- }
- outl (tmp, PCI_REG(SH7751_PCIPAR));
- }
-
- PCIDBG(2,"PCI: pci_check_direct failed\n");
- return NULL;
-}
-
-#endif
-
-/*
- * BIOS32 and PCI BIOS handling.
- *
- * The BIOS version of the pci functions is not yet implemented but it is left
- * in for completeness. Currently an error will be generated at compile time.
- */
-
-#ifdef CONFIG_PCI_BIOS
-
-#error PCI BIOS is not yet supported on SH7751
-
-#endif /* CONFIG_PCI_BIOS */
-
-/***************************************************************************************/
-
-/*
- * Handle bus scanning and fixups ....
- */
-
-
-/*
- * Discover remaining PCI buses in case there are peer host bridges.
- * We use the number of last PCI bus provided by the PCI BIOS.
- */
-static void __init pcibios_fixup_peer_bridges(void)
-{
- int n;
- struct pci_bus bus;
- struct pci_dev dev;
- u16 l;
-
- if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
- return;
- PCIDBG(2,"PCI: Peer bridge fixup\n");
- for (n=0; n <= pcibios_last_bus; n++) {
- if (pci_bus_exists(&pci_root_buses, n))
- continue;
- bus.number = n;
- bus.ops = pci_root_ops;
- dev.bus = &bus;
- for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
- if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
- l != 0x0000 && l != 0xffff) {
- PCIDBG(3,"Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
- printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
- pci_scan_bus(n, pci_root_ops, NULL);
- break;
- }
- }
-}
-
-
-static void __init pci_fixup_ide_bases(struct pci_dev *d)
-{
- int i;
-
- /*
- * PCI IDE controllers use non-standard I/O port decoding, respect it.
- */
- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- PCIDBG(3,"PCI: IDE base address fixup for %s\n", d->slot_name);
- for(i=0; i<4; i++) {
- struct resource *r = &d->resource[i];
- if ((r->start & ~0x80) == 0x374) {
- r->start |= 2;
- r->end = r->start;
- }
- }
-}
-
-
-/* Add future fixups here... */
-struct pci_fixup pcibios_fixups[] = {
- { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
- { 0 }
-};
-
-/*
- * Called after each bus is probed, but before its children
- * are examined.
- */
-
-void __init pcibios_fixup_bus(struct pci_bus *b)
-{
- pci_read_bridge_bases(b);
-}
-
-/*
- * Initialization. Try all known PCI access methods. Note that we support
- * using both PCI BIOS and direct access: in such cases, we use I/O ports
- * to access config space.
- *
- * Note that the platform specific initialization (BSC registers, and memory
- * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it
- * exitst and via the platform defined function pcibios_init_platform().
- * See pci_bigsur.c for implementation;
- *
- * The BIOS version of the pci functions is not yet implemented but it is left
- * in for completeness. Currently an error will be genereated at compile time.
- */
-
-void __init pcibios_init(void)
-{
- struct pci_ops *bios = NULL;
- struct pci_ops *dir = NULL;
-
- PCIDBG(1,"PCI: Starting initialization.\n");
-#ifdef CONFIG_PCI_BIOS
- if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) {
- pci_probe |= PCI_BIOS_SORT;
- pci_bios_present = 1;
- }
-#endif
-#ifdef CONFIG_PCI_DIRECT
- if (pci_probe & PCI_PROBE_CONF1 )
- dir = pci_check_direct();
-#endif
- if (dir) {
- pci_root_ops = dir;
- if(!pcibios_init_platform())
- PCIDBG(1,"PCI: Initialization failed\n");
- if (sh_mv.mv_init_pci != NULL)
- sh_mv.mv_init_pci();
- }
- else if (bios)
- pci_root_ops = bios;
- else {
- PCIDBG(1,"PCI: No PCI bus detected\n");
- return;
- }
-
- PCIDBG(1,"PCI: Probing PCI hardware\n");
- pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
- //pci_assign_unassigned_resources();
- pci_fixup_irqs(pcibios_swizzle, pcibios_lookup_irq);
- pcibios_fixup_peer_bridges();
- pcibios_resource_survey();
-
-#ifdef CONFIG_PCI_BIOS
- if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
- pcibios_sort();
-#endif
-}
-
-char * __init pcibios_setup(char *str)
-{
- if (!strcmp(str, "off")) {
- pci_probe = 0;
- return NULL;
- }
-#ifdef CONFIG_PCI_BIOS
- else if (!strcmp(str, "bios")) {
- pci_probe = PCI_PROBE_BIOS;
- return NULL;
- } else if (!strcmp(str, "nobios")) {
- pci_probe &= ~PCI_PROBE_BIOS;
- return NULL;
- } else if (!strcmp(str, "nosort")) {
- pci_probe |= PCI_NO_SORT;
- return NULL;
- } else if (!strcmp(str, "biosirq")) {
- pci_probe |= PCI_BIOS_IRQ_SCAN;
- return NULL;
- }
-#endif
-#ifdef CONFIG_PCI_DIRECT
- else if (!strcmp(str, "conf1")) {
- pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
- return NULL;
- }
-#endif
- else if (!strcmp(str, "rom")) {
- pci_probe |= PCI_ASSIGN_ROMS;
- return NULL;
- } else if (!strncmp(str, "lastbus=", 8)) {
- pcibios_last_bus = simple_strtol(str+8, NULL, 0);
- return NULL;
- }
- return str;
-}
-
-/*
- * Allocate the bridge and device resources
- */
-
-static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
-{
- struct list_head *ln;
- struct pci_bus *bus;
- struct pci_dev *dev;
- int idx;
- struct resource *r, *pr;
-
- PCIDBG(2,"PCI: pcibios_allocate_bus_reasources called\n" );
- /* Depth-First Search on bus tree */
- for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
- bus = pci_bus_b(ln);
- if ((dev = bus->self)) {
- for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
- r = &dev->resource[idx];
- if (!r->start)
- continue;
- pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0)
- printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
- }
- }
- pcibios_allocate_bus_resources(&bus->children);
- }
-}
-
-static void __init pcibios_allocate_resources(int pass)
-{
- struct pci_dev *dev = NULL;
- int idx, disabled;
- u16 command;
- struct resource *r, *pr;
-
- PCIDBG(2,"PCI: pcibios_allocate_resources pass %d called\n", pass);
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- pci_read_config_word(dev, PCI_COMMAND, &command);
- for(idx = 0; idx < 6; idx++) {
- r = &dev->resource[idx];
- if (r->parent) /* Already allocated */
- continue;
- if (!r->start) /* Address not assigned at all */
- continue;
- if (r->flags & IORESOURCE_IO)
- disabled = !(command & PCI_COMMAND_IO);
- else
- disabled = !(command & PCI_COMMAND_MEMORY);
- if (pass == disabled) {
- PCIDBG(3,"PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
- r->start, r->end, r->flags, disabled, pass);
- pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0) {
- printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
- /* We'll assign a new address later */
- r->end -= r->start;
- r->start = 0;
- }
- }
- }
- if (!pass) {
- r = &dev->resource[PCI_ROM_RESOURCE];
- if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
- /* Turn the ROM off, leave the resource region, but keep it unregistered. */
- u32 reg;
- PCIDBG(3,"PCI: Switching off ROM of %s\n", dev->slot_name);
- r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
- pci_read_config_dword(dev, dev->rom_base_reg, &reg);
- pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
- }
- }
- }
-}
-
-static void __init pcibios_assign_resources(void)
-{
- struct pci_dev *devn = NULL;
- int idx;
- struct resource *r;
-
- PCIDBG(2,"PCI: pcibios_assign_resources called\n");
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- int class = dev->class >> 8;
-
- /* Don't touch classless devices and host bridges */
- if (!class || class == PCI_CLASS_BRIDGE_HOST)
- continue;
-
- for(idx=0; idx<6; idx++) {
- r = &dev->resource[idx];
-
- /*
- * Don't touch IDE controllers and I/O ports of video cards!
- */
- if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
- (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
- continue;
-
- /*
- * We shall assign a new address to this resource, either because
- * the BIOS forgot to do so or because we have decided the old
- * address was unusable for some reason.
- */
- if (!r->start && r->end)
- pci_assign_resource(dev, idx);
- }
-
- if (pci_probe & PCI_ASSIGN_ROMS) {
- r = &dev->resource[PCI_ROM_RESOURCE];
- r->end -= r->start;
- r->start = 0;
- if (r->end)
- pci_assign_resource(dev, PCI_ROM_RESOURCE);
- }
- }
-}
-
-void __init pcibios_resource_survey(void)
-{
- PCIDBG(1,"PCI: Allocating resources\n");
- pcibios_allocate_bus_resources(&pci_root_buses);
- pcibios_allocate_resources(0);
- pcibios_allocate_resources(1);
- pcibios_assign_resources();
-}
-
-
-/***************************************************************************************/
-/*
- * IRQ functions
- */
-static u8 __init pcibios_swizzle(struct pci_dev *dev, u8 *pin)
-{
- /* no swizzling */
- return PCI_SLOT(dev->devfn);
-}
-
-static int pcibios_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- int irq = -1;
-
- /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
- irq = pcibios_map_platform_irq(slot,pin);
- if( irq < 0 ) {
- PCIDBG(3,"PCI: Error mapping IRQ on device %s\n", dev->name);
- return irq;
- }
-
- PCIDBG(2,"Setting IRQ for slot %s to %d\n", dev->slot_name, irq);
-
- return irq;
-}
diff --git a/arch/sh/kernel/pci_st40.c b/arch/sh/kernel/pci_st40.c
deleted file mode 100644
index b1e8e2b1c1f8..000000000000
--- a/arch/sh/kernel/pci_st40.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Support functions for the ST40 PCI hardware.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <asm/pci.h>
-#include <linux/irq.h>
-
-#include "pci_st40.h"
-
-/* This is in P2 of course */
-#define ST40PCI_BASE_ADDRESS (0xb0000000)
-#define ST40PCI_MEM_ADDRESS (ST40PCI_BASE_ADDRESS+0x0)
-#define ST40PCI_IO_ADDRESS (ST40PCI_BASE_ADDRESS+0x06000000)
-#define ST40PCI_REG_ADDRESS (ST40PCI_BASE_ADDRESS+0x07000000)
-
-#define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
-
-#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
-
-#define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
-#define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
-#define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
-
-#define ST40PCI_SERR_IRQ 64
-#define ST40PCI_SERR_INT_GROUP 0
-#define ST40PCI_SERR_INT_POS 0
-#define ST40PCI_SERR_INT_PRI 15
-
-#define ST40PCI_ERR_IRQ 65
-#define ST40PCI_ERR_INT_GROUP 1
-#define ST40PCI_ERR_INT_POS 1
-#define ST40PCI_ERR_INT_PRI 14
-
-
-/* Macros to extract PLL params */
-#define PLL_MDIV(reg) ( ((unsigned)reg) & 0xff )
-#define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
-#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
-#define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
-
-/* Build up the appropriate settings */
-#define PLL_SET(mdiv,ndiv,pdiv,setup) \
-( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
-
-#define PLLPCICR (0xbb040000+0x10)
-
-#define PLLPCICR_POWERON (1<<28)
-#define PLLPCICR_OUT_EN (1<<29)
-#define PLLPCICR_LOCKSELECT (1<<30)
-#define PLLPCICR_LOCK (1<<31)
-
-
-#define PLL_25MHZ 0x793c8512
-#define PLL_33MHZ PLL_SET(18,88,3,295)
-
-
-static __init void SetPCIPLL(void)
-{
- /* Stop the PLL */
- writel(0, PLLPCICR);
-
- /* Always run at 33Mhz. The PCI clock is totally async
- * to the rest of the system
- */
- writel(PLL_33MHZ | PLLPCICR_POWERON, PLLPCICR);
-
- printk("ST40PCI: Waiting for PCI PLL to lock\n");
- while ((readl(PLLPCICR) & PLLPCICR_LOCK) == 0);
- writel(readl(PLLPCICR) | PLLPCICR_OUT_EN, PLLPCICR);
-}
-
-
-static void st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs)
-{
-
- unsigned pci_int, pci_air, pci_cir, pci_aint;
-
- pci_int = ST40PCI_READ(INT);
- pci_cir = ST40PCI_READ(CIR);
- pci_air = ST40PCI_READ(AIR);
-
- if (pci_int) {
- printk("PCI INTERRUPT!\n");
- printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
- printk("PCI AIR -> 0x%x\n", pci_air);
- printk("PCI CIR -> 0x%x\n", pci_cir);
- ST40PCI_WRITE(INT, ~0);
- }
-
- pci_aint = ST40PCI_READ(AINT);
- if (pci_aint) {
- printk("PCI ARB INTERRUPT!\n");
- printk("PCI AINT -> 0x%x\n", pci_aint);
- printk("PCI AIR -> 0x%x\n", pci_air);
- printk("PCI CIR -> 0x%x\n", pci_cir);
- ST40PCI_WRITE(AINT, ~0);
- }
-
-}
-
-
-/* Rounds a number UP to the nearest power of two. Used for
- * sizing the PCI window.
- */
-static u32 __init r2p2(u32 num)
-{
- int i = 31;
- u32 tmp = num;
-
- if (num == 0)
- return 0;
-
- do {
- if (tmp & (1 << 31))
- break;
- i--;
- tmp <<= 1;
- } while (i >= 0);
-
- tmp = 1 << i;
- /* If the original number isn't a power of 2, round it up */
- if (tmp != num)
- tmp <<= 1;
-
- return tmp;
-}
-
-static void __init pci_fixup_ide_bases(struct pci_dev *d)
-{
- int i;
-
- /*
- * PCI IDE controllers use non-standard I/O port decoding, respect it.
- */
- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- printk("PCI: IDE base address fixup for %s\n", d->slot_name);
- for(i=0; i<4; i++) {
- struct resource *r = &d->resource[i];
- if ((r->start & ~0x80) == 0x374) {
- r->start |= 2;
- r->end = r->start;
- }
- }
-}
-
-
-/* Add future fixups here... */
-struct pci_fixup pcibios_fixups[] = {
- { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
- { 0 }
-};
-
-int __init st40pci_init(unsigned memStart, unsigned memSize)
-{
- u32 lsr0;
-
- SetPCIPLL();
-
- /* Initialises the ST40 pci subsystem, performing a reset, then programming
- * up the address space decoders appropriately
- */
-
- /* Should reset core here as well methink */
-
- ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_SOFT_RESET);
-
- /* Loop while core resets */
- while (ST40PCI_READ(CR) & CR_SOFT_RESET);
-
- /* Now, lets reset all the cards on the bus with extreme prejudice */
- ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
- udelay(250);
-
- /* Set bus active, take it out of reset */
- ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_CFINT | CR_PFCS | CR_PFE);
-
- /* The PCI spec says that no access must be made to the bus until 1 second
- * after reset. This seem ludicrously long, but some delay is needed here
- */
- mdelay(1000);
-
- /* Switch off interrupts */
- ST40PCI_WRITE(INTM, 0);
- ST40PCI_WRITE(AINT, 0);
-
- /* Allow it to be a master */
-
- ST40PCI_WRITE_SHORT(CSR_CMD,
- PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
- PCI_COMMAND_IO);
-
- /* Accesse to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
- * on the PCI bus. This allows a nice 1-1 bus to phys mapping.
- */
-
-
- ST40PCI_WRITE(MBR, 0x10000000);
- /* Always set the max size 128M (actually, it is only 96MB wide) */
- ST40PCI_WRITE(MBMR, 0x07ff0000);
-
- /* I/O addresses are mapped at 0xb6000000 -> 0xb7000000. These are changed to 0, to
- * allow cards that have legacy io such as vga to function correctly. This gives a
- * maximum of 64K of io/space as only the bottom 16 bits of the address are copied
- * over to the bus when the transaction is made. 64K of io space is more than enough
- */
- ST40PCI_WRITE(IOBR, 0x0);
- /* Set up the 64K window */
- ST40PCI_WRITE(IOBMR, 0x0);
-
- /* Now we set up the mbars so the PCI bus can see the memory of the machine */
-
- if (memSize < (64 * 1024)) {
- printk("Ridiculous memory size of 0x%x?\n",memSize);
- return 0;
- }
-
- lsr0 =
- (memSize >
- (512 * 1024 * 1024)) ? 0x1fff0001 : ((r2p2(memSize) -
- 0x10000) | 0x1);
-
- ST40PCI_WRITE(LSR0, lsr0);
-
- ST40PCI_WRITE(CSR_MBAR0, memStart);
- ST40PCI_WRITE(LAR0, memStart);
-
- /* Maximise timeout values */
- ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
- ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
- ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
-
-
- /* Install the pci interrupt handlers */
- make_intc2_irq(ST40PCI_SERR_IRQ, INTC2_BASE0,
- ST40PCI_SERR_INT_GROUP, ST40PCI_SERR_INT_POS,
- ST40PCI_SERR_INT_PRI);
-
- make_intc2_irq(ST40PCI_ERR_IRQ, INTC2_BASE0, ST40PCI_ERR_INT_GROUP,
- ST40PCI_ERR_INT_POS, ST40PCI_ERR_INT_PRI);
-
-
- return 1;
-}
-
-char * __init pcibios_setup(char *str)
-{
- return str;
-}
-
-
-#define SET_CONFIG_BITS(bus,devfn,where)\
- (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
-
-#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
-
-
-static int CheckForMasterAbort(void)
-{
- if (ST40PCI_READ(INT) & INT_MADIM) {
- /* Should we clear config space version as well ??? */
- ST40PCI_WRITE(INT, INT_MADIM);
- ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
- return 1;
- }
-
- return 0;
-}
-
-/* Write to config register */
-static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
-{
- ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
- switch (size) {
- case 1:
- *val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
- break;
- case 2:
- *val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
- break;
- case 4:
- *val = ST40PCI_READ(PDR);
- break;
- }
-
- if (CheckForMasterAbort()){
- switch (size) {
- case 1:
- *val = (u8)0xff;
- break;
- case 2:
- *val = (u16)0xffff;
- break;
- case 4:
- *val = 0xffffffff;
- break;
- }
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int st40pci_write(struct pci_bus *bus, unsigned int devfn; int where, int size, u32 val)
-{
- ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
-
- switch (size) {
- case 1:
- ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
- break;
- case 2:
- ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
- break;
- case 4:
- ST40PCI_WRITE(PDR, val);
- break;
- }
-
- CheckForMasterAbort();
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops pci_config_ops = {
- .read = st40pci_read,
- .write = st40pci_write,
-};
-
-
-/* Everything hangs off this */
-static struct pci_bus *pci_root_bus;
-
-
-static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
-{
- return PCI_SLOT(dev->devfn);
-}
-
-
-/* This needs to be shunted out of here into the board specific bit */
-#define HARP_PCI_IRQ 1
-#define HARP_BRIDGE_IRQ 2
-#define OVERDRIVE_SLOT0_IRQ 0
-
-static int __init map_harp_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- switch (slot) {
-#ifdef CONFIG_SH_STB1_HARP
- case 2: /*This is the PCI slot on the */
- return HARP_PCI_IRQ;
- case 1: /* this is the bridge */
- return HARP_BRIDGE_IRQ;
-#elif defined(CONFIG_SH_STB1_OVERDRIVE)
- case 1:
- case 2:
- case 3:
- return slot - 1;
-#else
-#error Unknown board
-#endif
- default:
- return -1;
- }
-}
-
-
-void __init pcibios_init(void)
-{
- extern unsigned long memory_start, memory_end;
-
- if (sh_mv.mv_init_pci != NULL) {
- sh_mv.mv_init_pci();
- }
-
- /* The pci subsytem needs to know where memory is and how much
- * of it there is. I've simply made these globals. A better mechanism
- * is probably needed.
- */
- st40pci_init(PHYSADDR(memory_start),
- PHYSADDR(memory_end) - PHYSADDR(memory_start));
-
- if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq,
- SA_INTERRUPT, "st40pci", NULL)) {
- printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
- return;
- }
-
- /* Enable the PCI interrupts on the device */
- ST40PCI_WRITE(INTM, ~0);
- ST40PCI_WRITE(AINT, ~0);
-
- /* Map the io address apprioately */
-#ifdef CONFIG_HD64465
- hd64465_port_map(PCIBIOS_MIN_IO, (64 * 1024) - PCIBIOS_MIN_IO + 1,
- ST40_IO_ADDR + PCIBIOS_MIN_IO, 0);
-#endif
-
- /* ok, do the scan man */
- pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
- pci_assign_unassigned_resources();
- pci_fixup_irqs(no_swizzle, map_harp_irq);
-
-}
-
-void __init pcibios_fixup_bus(struct pci_bus *bus)
-{
-}
diff --git a/arch/sh/kernel/pci_st40.h b/arch/sh/kernel/pci_st40.h
deleted file mode 100644
index 2e3451a97c7f..000000000000
--- a/arch/sh/kernel/pci_st40.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Defintions for the ST40 PCI hardware.
- */
-
-#ifndef __PCI_ST40_H__
-#define __PCI_ST40_H__
-
-#define ST40PCI_VCR_STATUS 0x00
-
-#define ST40PCI_VCR_VERSION 0x08
-
-#define ST40PCI_CR 0x10
-
-#define CR_SOFT_RESET (1<<12)
-#define CR_PFCS (1<<11)
-#define CR_PFE (1<<9)
-#define CR_BMAM (1<<6)
-#define CR_HOST (1<<5)
-#define CR_CLKEN (1<<4)
-#define CR_SOCS (1<<3)
-#define CR_IOCS (1<<2)
-#define CR_RSTCTL (1<<1)
-#define CR_CFINT (1<<0)
-#define CR_LOCK_MASK 0x5a000000
-
-
-#define ST40PCI_LSR0 0X14
-#define ST40PCI_LAR0 0x1c
-
-#define ST40PCI_INT 0x24
-#define INT_MADIM (1<<2)
-
-
-#define ST40PCI_INTM 0x28
-#define ST40PCI_AIR 0x2c
-#define ST40PCI_CIR 0x30
-#define ST40PCI_AINT 0x40
-#define ST40PCI_AINTM 0x44
-#define ST40PCI_BMIR 0x48
-#define ST40PCI_PAR 0x4c
-#define ST40PCI_MBR 0x50
-#define ST40PCI_IOBR 0x54
-#define ST40PCI_PINT 0x58
-#define ST40PCI_PINTM 0x5c
-#define ST40PCI_MBMR 0x70
-#define ST40PCI_IOBMR 0x74
-#define ST40PCI_PDR 0x78
-
-/* These are configs space registers */
-#define ST40PCI_CSR_VID 0x10000
-#define ST40PCI_CSR_DID 0x10002
-#define ST40PCI_CSR_CMD 0x10004
-#define ST40PCI_CSR_STATUS 0x10006
-#define ST40PCI_CSR_MBAR0 0x10010
-#define ST40PCI_CSR_TRDY 0x10040
-#define ST40PCI_CSR_RETRY 0x10041
-#define ST40PCI_CSR_MIT 0x1000d
-
-#define ST40_IO_ADDR 0xb6000000
-
-#endif /* __PCI_ST40_H__ */
diff --git a/arch/sh/kernel/setup_7751se.c b/arch/sh/kernel/setup_7751se.c
deleted file mode 100644
index 08222c4cf65c..000000000000
--- a/arch/sh/kernel/setup_7751se.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * linux/arch/sh/kernel/setup_7751se.c
- *
- * Copyright (C) 2000 Kazumoto Kojima
- *
- * Hitachi SolutionEngine Support.
- *
- * Modified for 7751 Solution Engine by
- * Ian da Silva and Jeremy Siegel, 2001.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <asm/io.h>
-#include <asm/hitachi_7751se.h>
-
-/*
- * Configure the Super I/O chip
- */
-#if 0
-/* Leftover code from regular Solution Engine, for reference. */
-/* The SH7751 Solution Engine has a different SuperIO. */
-static void __init smsc_config(int index, int data)
-{
- outb_p(index, INDEX_PORT);
- outb_p(data, DATA_PORT);
-}
-
-static void __init init_smsc(void)
-{
- outb_p(CONFIG_ENTER, CONFIG_PORT);
- outb_p(CONFIG_ENTER, CONFIG_PORT);
-
- /* FDC */
- smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
- smsc_config(ACTIVATE_INDEX, 0x01);
- smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
-
- /* IDE1 */
- smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
- smsc_config(ACTIVATE_INDEX, 0x01);
- smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
-
- /* AUXIO (GPIO): to use IDE1 */
- smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
- smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
- smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
-
- /* COM1 */
- smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
- smsc_config(ACTIVATE_INDEX, 0x01);
- smsc_config(IO_BASE_HI_INDEX, 0x03);
- smsc_config(IO_BASE_LO_INDEX, 0xf8);
- smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
-
- /* COM2 */
- smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
- smsc_config(ACTIVATE_INDEX, 0x01);
- smsc_config(IO_BASE_HI_INDEX, 0x02);
- smsc_config(IO_BASE_LO_INDEX, 0xf8);
- smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
-
- /* RTC */
- smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
- smsc_config(ACTIVATE_INDEX, 0x01);
- smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
-
- /* XXX: PARPORT, KBD, and MOUSE will come here... */
- outb_p(CONFIG_EXIT, CONFIG_PORT);
-}
-#endif
-
-/*
- * Initialize IRQ setting
- */
-void __init init_7751se_IRQ(void)
-{
-
- /* Leave old Solution Engine code in for reference. */
-#if defined(CONFIG_SH_SOLUTION_ENGINE)
- /*
- * Super I/O (Just mimic PC):
- * 1: keyboard
- * 3: serial 0
- * 4: serial 1
- * 5: printer
- * 6: floppy
- * 8: rtc
- * 12: mouse
- * 14: ide0
- */
- make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
- make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
- make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
- make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
- make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
- make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
- make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
- make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
-
- make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
-
- make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
- make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
- make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
- make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
-
- /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
- /* NOTE: #2 and #13 are not used on PC */
- make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
- make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
-
-#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
-
- make_ipr_irq(13, BCR_ILCRD, 3, 2);
-
- /* Add additional calls to make_ipr_irq() as drivers are added
- * and tested.
- */
-#endif
-
-}
-
-
-/*
- * Initialize the board
- */
-void __init setup_7751se(void)
-{
- /* Call init_smsc() replacement to set up SuperIO. */
- /* XXX: RTC setting comes here */
-}
diff --git a/arch/sh/kernel/setup_adx.c b/arch/sh/kernel/setup_adx.c
deleted file mode 100644
index e38633e228c7..000000000000
--- a/arch/sh/kernel/setup_adx.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * linux/arch/sh/kernel/setup_adx.c
- *
- * Copyright (C) 2001 A&D Co., Ltd.
- *
- * I/O routine and setup routines for A&D ADX Board
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- */
-
-#include <asm/io.h>
-#include <asm/machvec.h>
-#include <asm/irq.h>
-#include <linux/module.h>
-
-void setup_adx(void)
-{
- /* nothing to do just yet */
-/* printk("setup_adx()\n");*/
-}
-
-void init_adx_IRQ(void)
-{
- int i;
-
-/* printk("init_adx_IRQ()\n");*/
- /* setup irq_mask_register */
- irq_mask_register = (unsigned short *)0xa6000008;
-
- /* cover all external interrupt area by maskreg_irq_type
- * (Actually, irq15 doesn't exist)
- */
- for (i = 0; i < 16; i++) {
- make_maskreg_irq(i);
- disable_irq(i);
- }
-}
diff --git a/arch/sh/kernel/setup_bigsur.c b/arch/sh/kernel/setup_bigsur.c
deleted file mode 100644
index 0f80df3e7016..000000000000
--- a/arch/sh/kernel/setup_bigsur.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- *
- * By Dustin McIntire (dustin@sensoria.com) (c)2001
- *
- * Setup and IRQ handling code for the HD64465 companion chip.
- * by Greg Banks <gbanks@pocketpenguins.com>
- * Copyright (c) 2000 PocketPenguins Inc
- *
- * Derived from setup_hd64465.c which bore the message:
- * Greg Banks <gbanks@pocketpenguins.com>
- * Copyright (c) 2000 PocketPenguins Inc and
- * Copyright (C) 2000 YAEGASHI Takeshi
- * and setup_cqreek.c which bore message:
- * Copyright (C) 2000 Niibe Yutaka
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Setup and IRQ functions for a Hitachi Big Sur Evaluation Board.
- *
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/bitops.h>
-
-#include <asm/io_bigsur.h>
-#include <asm/hd64465.h>
-#include <asm/bigsur.h>
-
-//#define BIGSUR_DEBUG 3
-#undef BIGSUR_DEBUG
-
-#ifdef BIGSUR_DEBUG
-#define DPRINTK(args...) printk(args)
-#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
-#else
-#define DPRINTK(args...)
-#define DIPRINTK(n, args...)
-#endif /* BIGSUR_DEBUG */
-
-#ifdef CONFIG_HD64465
-extern int hd64465_irq_demux(int irq);
-#endif /* CONFIG_HD64465 */
-
-
-/*===========================================================*/
-// Big Sur CPLD IRQ Routines
-/*===========================================================*/
-
-/* Level 1 IRQ routines */
-static void disable_bigsur_l1irq(unsigned int irq)
-{
- unsigned long flags;
- unsigned char mask;
- unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
- unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
-
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
- DPRINTK("Disable L1 IRQ %d\n", irq);
- DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
- mask_port, bit);
- save_and_cli(flags);
-
- /* Disable IRQ - set mask bit */
- mask = inb(mask_port) | bit;
- outb(mask, mask_port);
- restore_flags(flags);
- return;
- }
- DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
-}
-
-static void enable_bigsur_l1irq(unsigned int irq)
-{
- unsigned long flags;
- unsigned char mask;
- unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
- unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
-
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
- DPRINTK("Enable L1 IRQ %d\n", irq);
- DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
- mask_port, bit);
- save_and_cli(flags);
- /* Enable L1 IRQ - clear mask bit */
- mask = inb(mask_port) & ~bit;
- outb(mask, mask_port);
- restore_flags(flags);
- return;
- }
- DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
-}
-
-
-/* Level 2 irq masks and registers for L2 decoding */
-/* Level2 bitmasks for each level 1 IRQ */
-const u32 bigsur_l2irq_mask[] =
- {0x40,0x80,0x08,0x01,0x01,0x3C,0x3E,0xFF,0x40,0x80,0x06,0x03};
-/* Level2 to ISR[n] map for each level 1 IRQ */
-const u32 bigsur_l2irq_reg[] =
- { 2, 2, 3, 3, 1, 2, 1, 0, 1, 1, 3, 2};
-/* Level2 to Level 1 IRQ map */
-const u32 bigsur_l2_l1_map[] =
- {7,7,7,7,7,7,7,7, 4,6,6,6,6,6,8,9, 11,11,5,5,5,5,0,1, 3,10,10,2,-1,-1,-1,-1};
-/* IRQ inactive level (high or low) */
-const u32 bigsur_l2_inactv_state[] = {0x00, 0xBE, 0xFC, 0xF7};
-
-/* CPLD external status and mask registers base and offsets */
-static const u32 isr_base = BIGSUR_IRQ0;
-static const u32 isr_offset = BIGSUR_IRQ0 - BIGSUR_IRQ1;
-static const u32 imr_base = BIGSUR_IMR0;
-static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;
-
-#define REG_NUM(irq) ((irq-BIGSUR_2NDLVL_IRQ_LOW)/8 )
-
-/* Level 2 IRQ routines */
-static void disable_bigsur_l2irq(unsigned int irq)
-{
- unsigned long flags;
- unsigned char mask;
- unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
- unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
-
- if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
- DPRINTK("Disable L2 IRQ %d\n", irq);
- DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
- mask_port, bit);
- save_and_cli(flags);
-
- /* Disable L2 IRQ - set mask bit */
- mask = inb(mask_port) | bit;
- outb(mask, mask_port);
- restore_flags(flags);
- return;
- }
- DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
-}
-
-static void enable_bigsur_l2irq(unsigned int irq)
-{
- unsigned long flags;
- unsigned char mask;
- unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
- unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
-
- if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
- DPRINTK("Enable L2 IRQ %d\n", irq);
- DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
- mask_port, bit);
- save_and_cli(flags);
-
- /* Enable L2 IRQ - clear mask bit */
- mask = inb(mask_port) & ~bit;
- outb(mask, mask_port);
- restore_flags(flags);
- return;
- }
- DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
-}
-
-static void mask_and_ack_bigsur(unsigned int irq)
-{
- DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq);
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
- disable_bigsur_l1irq(irq);
- else
- disable_bigsur_l2irq(irq);
-}
-
-static void end_bigsur_irq(unsigned int irq)
-{
- DPRINTK("end_bigsur_irq IRQ %d\n", irq);
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
- enable_bigsur_l1irq(irq);
- else
- enable_bigsur_l2irq(irq);
- }
-}
-
-static unsigned int startup_bigsur_irq(unsigned int irq)
-{
- u8 mask;
- u32 reg;
-
- DPRINTK("startup_bigsur_irq IRQ %d\n", irq);
-
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
- /* Enable the L1 IRQ */
- enable_bigsur_l1irq(irq);
- /* Enable all L2 IRQs in this L1 IRQ */
- mask = ~(bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW]);
- reg = imr_base - bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW] * imr_offset;
- mask &= inb(reg);
- outb(mask,reg);
- DIPRINTK(2,"startup_bigsur_irq: IMR=0x%08x mask=0x%x\n",reg,inb(reg));
- }
- else {
- /* Enable the L2 IRQ - clear mask bit */
- enable_bigsur_l2irq(irq);
- /* Enable the L1 bit masking this L2 IRQ */
- enable_bigsur_l1irq(bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW]);
- DIPRINTK(2,"startup_bigsur_irq: L1=%d L2=%d\n",
- bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW],irq);
- }
- return 0;
-}
-
-static void shutdown_bigsur_irq(unsigned int irq)
-{
- DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq);
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
- disable_bigsur_l1irq(irq);
- else
- disable_bigsur_l2irq(irq);
-}
-
-/* Define the IRQ structures for the L1 and L2 IRQ types */
-static struct hw_interrupt_type bigsur_l1irq_type = {
- "BigSur-CPLD-Level1-IRQ",
- startup_bigsur_irq,
- shutdown_bigsur_irq,
- enable_bigsur_l1irq,
- disable_bigsur_l1irq,
- mask_and_ack_bigsur,
- end_bigsur_irq
-};
-
-static struct hw_interrupt_type bigsur_l2irq_type = {
- "BigSur-CPLD-Level2-IRQ",
- startup_bigsur_irq,
- shutdown_bigsur_irq,
- enable_bigsur_l2irq,
- disable_bigsur_l2irq,
- mask_and_ack_bigsur,
- end_bigsur_irq
-};
-
-
-static void make_bigsur_l1isr(unsigned int irq) {
-
- /* sanity check first */
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
- /* save the handler in the main description table */
- irq_desc[irq].handler = &bigsur_l1irq_type;
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = 0;
- irq_desc[irq].depth = 1;
-
- disable_bigsur_l1irq(irq);
- return;
- }
- DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq);
- return;
-}
-
-static void make_bigsur_l2isr(unsigned int irq) {
-
- /* sanity check first */
- if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
- /* save the handler in the main description table */
- irq_desc[irq].handler = &bigsur_l2irq_type;
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = 0;
- irq_desc[irq].depth = 1;
-
- disable_bigsur_l2irq(irq);
- return;
- }
- DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq);
- return;
-}
-
-/* The IRQ's will be decoded as follows:
- * If a level 2 handler exists and there is an unmasked active
- * IRQ, the 2nd level handler will be called.
- * If a level 2 handler does not exist for the active IRQ
- * the 1st level handler will be called.
- */
-
-int bigsur_irq_demux(int irq)
-{
- int dmux_irq = irq;
- u8 mask, actv_irqs;
- u32 reg_num;
-
- DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq);
- /* decode the 1st level IRQ */
- if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
- /* Get corresponding L2 ISR bitmask and ISR number */
- mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW];
- reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW];
- /* find the active IRQ's (XOR with inactive level)*/
- actv_irqs = inb(isr_base-reg_num*isr_offset) ^
- bigsur_l2_inactv_state[reg_num];
- /* decode active IRQ's */
- actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset));
- /* if NEZ then we have an active L2 IRQ */
- if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW;
- /* if no 2nd level IRQ action, but has 1st level, use 1st level handler */
- if(!irq_desc[dmux_irq].action && irq_desc[irq].action)
- dmux_irq = irq;
- DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n",
- irq, dmux_irq, mask, reg_num);
- }
-#ifdef CONFIG_HD64465
- dmux_irq = hd64465_irq_demux(dmux_irq);
-#endif /* CONFIG_HD64465 */
- DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq);
-
- return dmux_irq;
-}
-
-/*===========================================================*/
-// Big Sur Init Routines
-/*===========================================================*/
-void __init init_bigsur_IRQ(void)
-{
- int i;
-
- if (!MACH_BIGSUR) return;
-
- /* Create ISR's for Big Sur CPLD IRQ's */
- /*==============================================================*/
- for(i=BIGSUR_IRQ_LOW;i<BIGSUR_IRQ_HIGH;i++)
- make_bigsur_l1isr(i);
-
- printk(KERN_INFO "Big Sur CPLD L1 interrupts %d to %d.\n",
- BIGSUR_IRQ_LOW,BIGSUR_IRQ_HIGH);
-
- for(i=BIGSUR_2NDLVL_IRQ_LOW;i<BIGSUR_2NDLVL_IRQ_HIGH;i++)
- make_bigsur_l2isr(i);
-
- printk(KERN_INFO "Big Sur CPLD L2 interrupts %d to %d.\n",
- BIGSUR_2NDLVL_IRQ_LOW,BIGSUR_2NDLVL_IRQ_HIGH);
-
-}
-
-int __init setup_bigsur(void)
-{
- static int done = 0; /* run this only once */
-
- if (!MACH_BIGSUR || done) return 0;
- done = 1;
-
- /* Mask all 2nd level IRQ's */
- outb(-1,BIGSUR_IMR0);
- outb(-1,BIGSUR_IMR1);
- outb(-1,BIGSUR_IMR2);
- outb(-1,BIGSUR_IMR3);
-
- /* Mask 1st level interrupts */
- outb(-1,BIGSUR_IRLMR0);
- outb(-1,BIGSUR_IRLMR1);
-
-#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL)
- /* remap IO ports for first ISA serial port to HD64465 UART */
- bigsur_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
-#endif /* CONFIG_HD64465 && CONFIG_SERIAL */
- /* TODO: setup IDE registers */
- bigsur_port_map(BIGSUR_IDECTL_IOPORT, 2, BIGSUR_ICTL, 8);
- /* Setup the Ethernet port to BIGSUR_ETHER_IOPORT */
- bigsur_port_map(BIGSUR_ETHER_IOPORT, 16, BIGSUR_ETHR+BIGSUR_ETHER_IOPORT, 0);
- /* set page to 1 */
- outw(1, BIGSUR_ETHR+0xe);
- /* set the IO port to BIGSUR_ETHER_IOPORT */
- outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
-
- return 0;
-}
-
-module_init(setup_bigsur);
diff --git a/arch/sh/kernel/setup_cqreek.c b/arch/sh/kernel/setup_cqreek.c
deleted file mode 100644
index 2e55b9cd53f4..000000000000
--- a/arch/sh/kernel/setup_cqreek.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/* $Id: setup_cqreek.c,v 1.9 2001/07/30 12:43:28 gniibe Exp $
- *
- * arch/sh/kernel/setup_cqreek.c
- *
- * Copyright (C) 2000 Niibe Yutaka
- *
- * CqREEK IDE/ISA Bridge Support.
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/io_generic.h>
-#include <asm/irq.h>
-#include <asm/machvec.h>
-#include <asm/machvec_init.h>
-#include <asm/rtc.h>
-
-#define BRIDGE_FEATURE 0x0002
-
-#define BRIDGE_IDE_CTRL 0x0018
-#define BRIDGE_IDE_INTR_LVL 0x001A
-#define BRIDGE_IDE_INTR_MASK 0x001C
-#define BRIDGE_IDE_INTR_STAT 0x001E
-
-#define BRIDGE_ISA_CTRL 0x0028
-#define BRIDGE_ISA_INTR_LVL 0x002A
-#define BRIDGE_ISA_INTR_MASK 0x002C
-#define BRIDGE_ISA_INTR_STAT 0x002E
-
-#define IDE_OFFSET 0xA4000000UL
-#define ISA_OFFSET 0xA4A00000UL
-
-static unsigned long cqreek_port2addr(unsigned long port)
-{
- if (0x0000<=port && port<=0x0040)
- return IDE_OFFSET + port;
- if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
- return IDE_OFFSET + port;
-
- return ISA_OFFSET + port;
-}
-
-struct cqreek_irq_data {
- unsigned short mask_port; /* Port of Interrupt Mask Register */
- unsigned short stat_port; /* Port of Interrupt Status Register */
- unsigned short bit; /* Value of the bit */
-};
-static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
-
-static void disable_cqreek_irq(unsigned int irq)
-{
- unsigned long flags;
- unsigned short mask;
- unsigned short mask_port = cqreek_irq_data[irq].mask_port;
- unsigned short bit = cqreek_irq_data[irq].bit;
-
- save_and_cli(flags);
- /* Disable IRQ */
- mask = inw(mask_port) & ~bit;
- outw_p(mask, mask_port);
- restore_flags(flags);
-}
-
-static void enable_cqreek_irq(unsigned int irq)
-{
- unsigned long flags;
- unsigned short mask;
- unsigned short mask_port = cqreek_irq_data[irq].mask_port;
- unsigned short bit = cqreek_irq_data[irq].bit;
-
- save_and_cli(flags);
- /* Enable IRQ */
- mask = inw(mask_port) | bit;
- outw_p(mask, mask_port);
- restore_flags(flags);
-}
-
-static void mask_and_ack_cqreek(unsigned int irq)
-{
- unsigned short stat_port = cqreek_irq_data[irq].stat_port;
- unsigned short bit = cqreek_irq_data[irq].bit;
-
- disable_cqreek_irq(irq);
- /* Clear IRQ (it might be edge IRQ) */
- inw(stat_port);
- outw_p(bit, stat_port);
-}
-
-static void end_cqreek_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_cqreek_irq(irq);
-}
-
-static unsigned int startup_cqreek_irq(unsigned int irq)
-{
- enable_cqreek_irq(irq);
- return 0;
-}
-
-static void shutdown_cqreek_irq(unsigned int irq)
-{
- disable_cqreek_irq(irq);
-}
-
-static struct hw_interrupt_type cqreek_irq_type = {
- "CqREEK-IRQ",
- startup_cqreek_irq,
- shutdown_cqreek_irq,
- enable_cqreek_irq,
- disable_cqreek_irq,
- mask_and_ack_cqreek,
- end_cqreek_irq
-};
-
-static int has_ide, has_isa;
-
-/* XXX: This is just for test for my NE2000 ISA board
- What we really need is virtualized IRQ and demultiplexer like HP600 port */
-void __init init_cqreek_IRQ(void)
-{
- if (has_ide) {
- cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
- cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
- cqreek_irq_data[14].bit = 1;
-
- irq_desc[14].handler = &cqreek_irq_type;
- irq_desc[14].status = IRQ_DISABLED;
- irq_desc[14].action = 0;
- irq_desc[14].depth = 1;
-
- disable_cqreek_irq(14);
- }
-
- if (has_isa) {
- cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
- cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
- cqreek_irq_data[10].bit = (1 << 10);
-
- /* XXX: Err... we may need demultiplexer for ISA irq... */
- irq_desc[10].handler = &cqreek_irq_type;
- irq_desc[10].status = IRQ_DISABLED;
- irq_desc[10].action = 0;
- irq_desc[10].depth = 1;
-
- disable_cqreek_irq(10);
- }
-}
-
-/*
- * Initialize the board
- */
-void __init setup_cqreek(void)
-{
- int i;
-/* udelay is not available at setup time yet... */
-#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
-
- if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
- outw_p(0, BRIDGE_IDE_INTR_LVL);
- outw_p(0, BRIDGE_IDE_INTR_MASK);
-
- outw_p(0, BRIDGE_IDE_CTRL);
- DELAY();
-
- outw_p(0x8000, BRIDGE_IDE_CTRL);
- DELAY();
-
- outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
- outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
- outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
- has_ide=1;
- }
-
- if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
- outw_p(0, BRIDGE_ISA_INTR_LVL);
- outw_p(0, BRIDGE_ISA_INTR_MASK);
-
- outw_p(0, BRIDGE_ISA_CTRL);
- DELAY();
- outw_p(0x8000, BRIDGE_ISA_CTRL);
- DELAY();
-
- outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
- outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
- outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
- has_isa=1;
- }
-
- printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", has_ide, has_isa);
-}
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_cqreek __initmv = {
- .mv_name = "CqREEK",
-
-#if defined(__SH4__)
- .mv_nr_irqs = 48,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
- .mv_nr_irqs = 32,
-#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
- .mv_nr_irqs = 61,
-#endif
-
- .mv_inb = generic_inb,
- .mv_inw = generic_inw,
- .mv_inl = generic_inl,
- .mv_outb = generic_outb,
- .mv_outw = generic_outw,
- .mv_outl = generic_outl,
-
- .mv_inb_p = generic_inb_p,
- .mv_inw_p = generic_inw_p,
- .mv_inl_p = generic_inl_p,
- .mv_outb_p = generic_outb_p,
- .mv_outw_p = generic_outw_p,
- .mv_outl_p = generic_outl_p,
-
- .mv_insb = generic_insb,
- .mv_insw = generic_insw,
- .mv_insl = generic_insl,
- .mv_outsb = generic_outsb,
- .mv_outsw = generic_outsw,
- .mv_outsl = generic_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_init_arch = setup_cqreek,
- .mv_init_irq = init_cqreek_IRQ,
-
- .mv_isa_port2addr = cqreek_port2addr,
-
- .mv_ioremap = generic_ioremap,
- .mv_iounmap = generic_iounmap,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-};
-ALIAS_MV(cqreek)
diff --git a/arch/sh/kernel/setup_dc.c b/arch/sh/kernel/setup_dc.c
deleted file mode 100644
index f18c35e6febe..000000000000
--- a/arch/sh/kernel/setup_dc.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* arch/sh/kernel/setup_dc.c
- *
- * Hardware support for the Sega Dreamcast.
- *
- * Copyright (c) 2001 M. R. Brown <mrbrown@linuxdc.org>
- *
- * This file is part of the LinuxDC project (www.linuxdc.org)
- *
- * Released under the terms of the GNU GPL v2.0.
- *
- * This file originally bore the message (with enclosed-$):
- * Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
- * SEGA Dreamcast support
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/dc_sysasic.h>
-
-int __init gapspci_init(void);
-
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-
-/* Dreamcast System ASIC Hardware Events -
-
- The Dreamcast's System ASIC (located on the PowerVR2 chip) is responsible
- for receiving hardware events from system peripherals and triggering an
- SH7750 IRQ. Hardware events can trigger IRQs 13, 11, or 9 depending on
- which bits are set in the Event Mask Registers (EMRs). When a hardware
- event is triggered, it's corresponding bit in the Event Status Registers
- (ESRs) is set, and that bit should be rewritten to the ESR to acknowledge
- that event.
-
- There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event
- types can be found in include/asm-sh/dc_sysasic.h. There are three groups
- of EMRs that parallel the ESRs. Each EMR group corresponds to an IRQ, so
- 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers
- IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
-
- In the kernel, these events are mapped to virtual IRQs so that drivers can
- respond to them as they would a normal interrupt. In order to keep this
- mapping simple, the events are mapped as:
-
- 6900/6910 - Events 0-31, IRQ 13
- 6904/6924 - Events 32-63, IRQ 11
- 6908/6938 - Events 64-95, IRQ 9
-
-*/
-
-#define ESR_BASE 0x005f6900 /* Base event status register */
-#define EMR_BASE 0x005f6910 /* Base event mask register */
-
-/* Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
- 1 = 0x6920, 2 = 0x6930; also determine the event offset */
-#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
-
-/* Return the hardware event's bit positon within the EMR/ESR */
-#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
-
-/* For each of these *_irq routines, the IRQ passed in is the virtual IRQ
- (logically mapped to the corresponding bit for the hardware event). */
-
-/* Disable the hardware event by masking its bit in its EMR */
-static inline void disable_systemasic_irq(unsigned int irq)
-{
- unsigned long flags;
- __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
- __u32 mask;
-
- save_and_cli(flags);
- mask = inl(emr);
- mask &= ~(1 << EVENT_BIT(irq));
- outl(mask, emr);
- restore_flags(flags);
-}
-
-/* Enable the hardware event by setting its bit in its EMR */
-static inline void enable_systemasic_irq(unsigned int irq)
-{
- unsigned long flags;
- __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
- __u32 mask;
-
- save_and_cli(flags);
- mask = inl(emr);
- mask |= (1 << EVENT_BIT(irq));
- outl(mask, emr);
- restore_flags(flags);
-}
-
-/* Acknowledge a hardware event by writing its bit back to its ESR */
-static void ack_systemasic_irq(unsigned int irq)
-{
- __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
- disable_systemasic_irq(irq);
- outl((1 << EVENT_BIT(irq)), esr);
-}
-
-/* After a IRQ has been ack'd and responded to, it needs to be renabled */
-static void end_systemasic_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_systemasic_irq(irq);
-}
-
-static unsigned int startup_systemasic_irq(unsigned int irq)
-{
- enable_systemasic_irq(irq);
-
- return 0;
-}
-
-static void shutdown_systemasic_irq(unsigned int irq)
-{
- disable_systemasic_irq(irq);
-}
-
-static struct hw_interrupt_type systemasic_int = {
- .typename = "System ASIC",
- .startup = startup_systemasic_irq,
- .shutdown = shutdown_systemasic_irq,
- .enable = enable_systemasic_irq,
- .disable = disable_systemasic_irq,
- .ack = ack_systemasic_irq,
- .end = end_systemasic_irq,
-};
-
-/*
- * Map the hardware event indicated by the processor IRQ to a virtual IRQ.
- */
-int systemasic_irq_demux(int irq)
-{
- __u32 emr, esr, status, level;
- __u32 j, bit;
-
- switch (irq) {
- case 13:
- level = 0;
- break;
- case 11:
- level = 1;
- break;
- case 9:
- level = 2;
- break;
- default:
- return irq;
- }
- emr = EMR_BASE + (level << 4) + (level << 2);
- esr = ESR_BASE + (level << 2);
-
- /* Mask the ESR to filter any spurious, unwanted interrtupts */
- status = inl(esr);
- status &= inl(emr);
-
- /* Now scan and find the first set bit as the event to map */
- for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
- if (status & bit) {
- irq = HW_EVENT_IRQ_BASE + j + (level << 5);
- return irq;
- }
- }
-
- /* Not reached */
- return irq;
-}
-
-int __init setup_dreamcast(void)
-{
- int i;
-
- /* Mask all hardware events */
- /* XXX */
-
- /* Acknowledge any previous events */
- /* XXX */
-
- /* Assign all virtual IRQs to the System ASIC int. handler */
- for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
- irq_desc[i].handler = &systemasic_int;
-
-#ifdef CONFIG_PCI
- gapspci_init();
-#endif
-
- printk(KERN_INFO "SEGA Dreamcast support.\n");
-#if 0
- printk(KERN_INFO "BCR1: 0x%08x\n", ctrl_inl(0xff800000));
- printk(KERN_INFO "BCR2: 0x%08x\n", ctrl_inw(0xff800004));
- printk(KERN_INFO "WCR1: 0x%08x\n", ctrl_inl(0xff800008));
- printk(KERN_INFO "WCR2: 0x%08x\n", ctrl_inl(0xff80000c));
- printk(KERN_INFO "WCR3: 0x%08x\n", ctrl_inl(0xff800010));
- printk(KERN_INFO "MCR: 0x%08x\n", ctrl_inl(0xff800014));
- printk(KERN_INFO "PCR: 0x%08x\n", ctrl_inw(0xff800018));
-/*
- * BCR1: 0xa3020008
- * BCR2: 0x0001
- * WCR1: 0x01110111
- * WCR2: 0x618066d8
- * WCR3: 0x07777777
- * MCR: 0xc00a0e24
- * PCR: 0x0000
- */
-#endif
- return 0;
-}
diff --git a/arch/sh/kernel/setup_ec3104.c b/arch/sh/kernel/setup_ec3104.c
deleted file mode 100644
index c864e34f6b4d..000000000000
--- a/arch/sh/kernel/setup_ec3104.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * linux/arch/sh/kernel/setup_ec3104.c
- * EC3104 companion chip support
- *
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- */
-/* EC3104 note:
- * This code was written without any documentation about the EC3104 chip. While
- * I hope I got most of the basic functionality right, the register names I use
- * are most likely completely different from those in the chip documentation.
- *
- * If you have any further information about the EC3104, please tell me
- * (prumpf@tux.org).
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/types.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/ec3104.h>
-
-/* This is for debugging mostly; here's the table that I intend to keep
- * in here:
- *
- * index function base addr power interrupt bit
- * 0 power b0ec0000 --- 00000001 (unused)
- * 1 irqs b0ec1000 --- 00000002 (unused)
- * 2 ?? b0ec2000 b0ec0008 00000004
- * 3 PS2 (1) b0ec3000 b0ec000c 00000008
- * 4 PS2 (2) b0ec4000 b0ec0010 00000010
- * 5 ?? b0ec5000 b0ec0014 00000020
- * 6 I2C b0ec6000 b0ec0018 00000040
- * 7 serial (1) b0ec7000 b0ec001c 00000080
- * 8 serial (2) b0ec8000 b0ec0020 00000100
- * 9 serial (3) b0ec9000 b0ec0024 00000200
- * 10 serial (4) b0eca000 b0ec0028 00000400
- * 12 GPIO (1) b0ecc000 b0ec0030
- * 13 GPIO (2) b0ecc000 b0ec0030
- * 16 pcmcia (1) b0ed0000 b0ec0040 00010000
- * 17 pcmcia (2) b0ed1000 b0ec0044 00020000
- */
-
-/* I used the register names from another interrupt controller I worked with,
- * since it seems to be identical to the ec3104 except that all bits are
- * inverted:
- *
- * IRR: Interrupt Request Register (pending and enabled interrupts)
- * IMR: Interrupt Mask Register (which interrupts are enabled)
- * IPR: Interrupt Pending Register (pending interrupts, even disabled ones)
- *
- * 0 bits mean pending or enabled, 1 bits mean not pending or disabled. all
- * IRQs seem to be level-triggered.
- */
-
-#define EC3104_IRR (EC3104_BASE + 0x1000)
-#define EC3104_IMR (EC3104_BASE + 0x1004)
-#define EC3104_IPR (EC3104_BASE + 0x1008)
-
-#define ctrl_readl(addr) (*(volatile u32 *)(addr))
-#define ctrl_writel(data,addr) (*(volatile u32 *)(addr) = (data))
-#define ctrl_readb(addr) (*(volatile u8 *)(addr))
-
-static char *ec3104_name(unsigned index)
-{
- switch(index) {
- case 0:
- return "power management";
- case 1:
- return "interrupts";
- case 3:
- return "PS2 (1)";
- case 4:
- return "PS2 (2)";
- case 5:
- return "I2C (1)";
- case 6:
- return "I2C (2)";
- case 7:
- return "serial (1)";
- case 8:
- return "serial (2)";
- case 9:
- return "serial (3)";
- case 10:
- return "serial (4)";
- case 16:
- return "pcmcia (1)";
- case 17:
- return "pcmcia (2)";
- default: {
- static char buf[32];
-
- sprintf(buf, "unknown (%d)", index);
-
- return buf;
- }
- }
-}
-
-int get_pending_interrupts(char *buf)
-{
- u32 ipr;
- u32 bit;
- char *p = buf;
-
- p += sprintf(p, "pending: (");
-
- ipr = ctrl_inl(EC3104_IPR);
-
- for (bit = 1; bit < 32; bit++)
- if (!(ipr & (1<<bit)))
- p += sprintf(p, "%s ", ec3104_name(bit));
-
- p += sprintf(p, ")\n");
-
- return p - buf;
-}
-
-static inline u32 ec3104_irq2mask(unsigned int irq)
-{
- return (1 << (irq - EC3104_IRQBASE));
-}
-
-static inline void mask_ec3104_irq(unsigned int irq)
-{
- u32 mask;
-
- mask = ctrl_readl(EC3104_IMR);
-
- mask |= ec3104_irq2mask(irq);
-
- ctrl_writel(mask, EC3104_IMR);
-}
-
-static inline void unmask_ec3104_irq(unsigned int irq)
-{
- u32 mask;
-
- mask = ctrl_readl(EC3104_IMR);
-
- mask &= ~ec3104_irq2mask(irq);
-
- ctrl_writel(mask, EC3104_IMR);
-}
-
-static void disable_ec3104_irq(unsigned int irq)
-{
- mask_ec3104_irq(irq);
-}
-
-static void enable_ec3104_irq(unsigned int irq)
-{
- unmask_ec3104_irq(irq);
-}
-
-static void mask_and_ack_ec3104_irq(unsigned int irq)
-{
- mask_ec3104_irq(irq);
-}
-
-static void end_ec3104_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- unmask_ec3104_irq(irq);
-}
-
-static unsigned int startup_ec3104_irq(unsigned int irq)
-{
- unmask_ec3104_irq(irq);
-
- return 0;
-}
-
-static void shutdown_ec3104_irq(unsigned int irq)
-{
- mask_ec3104_irq(irq);
-
-}
-
-static struct hw_interrupt_type ec3104_int = {
- .typename = "EC3104",
- .enable = enable_ec3104_irq,
- .disable = disable_ec3104_irq,
- .ack = mask_and_ack_ec3104_irq,
- .end = end_ec3104_irq,
- .startup = startup_ec3104_irq,
- .shutdown = shutdown_ec3104_irq,
-};
-
-/* Yuck. the _demux API is ugly */
-int ec3104_irq_demux(int irq)
-{
- if (irq == EC3104_IRQ) {
- unsigned int mask;
-
- mask = ctrl_readl(EC3104_IRR);
-
- if (mask == 0xffffffff)
- return EC3104_IRQ;
- else
- return EC3104_IRQBASE + ffz(mask);
- }
-
- return irq;
-}
-
-int __init setup_ec3104(void)
-{
- char str[8];
- int i;
-
- if (!MACH_EC3104)
- printk("!MACH_EC3104\n");
-
- if (0)
- return 0;
-
- for (i=0; i<8; i++)
- str[i] = ctrl_readb(EC3104_BASE + i);
-
- for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
- irq_desc[i].handler = &ec3104_int;
-
- printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
- str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
-
-
- /* mask all interrupts. this should have been done by the boot
- * loader for us but we want to be sure ... */
- ctrl_writel(0xffffffff, EC3104_IMR);
-
- return 0;
-}
-
-module_init(setup_ec3104);
diff --git a/arch/sh/kernel/setup_sh2000.c b/arch/sh/kernel/setup_sh2000.c
deleted file mode 100644
index ad8604916446..000000000000
--- a/arch/sh/kernel/setup_sh2000.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * linux/arch/sh/kernel/setup_sh2000.c
- *
- * Copyright (C) 2001 SUGIOKA Tochinobu
- *
- * SH-2000 Support.
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/io_generic.h>
-#include <asm/machvec.h>
-#include <asm/machvec_init.h>
-#include <asm/rtc.h>
-
-#define CF_CIS_BASE 0xb4200000
-
-#define PORT_PECR 0xa4000108
-#define PORT_PHCR 0xa400010E
-#define PORT_ICR1 0xa4000010
-#define PORT_IRR0 0xa4000004
-
-/*
- * Initialize the board
- */
-int __init setup_sh2000(void)
-{
- /* XXX: RTC setting comes here */
-
- /* These should be done by BIOS/IPL ... */
- /* Enable nCE2A, nCE2B output */
- ctrl_outw(ctrl_inw(PORT_PECR) & ~0xf00, PORT_PECR);
- /* Enable the Compact Flash card, and set the level interrupt */
- ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
- /* Enable interrupt */
- ctrl_outw(ctrl_inw(PORT_PHCR) & ~0x03f3, PORT_PHCR);
- ctrl_outw(1, PORT_ICR1);
- ctrl_outw(ctrl_inw(PORT_IRR0) & ~0xff3f, PORT_IRR0);
- printk(KERN_INFO "SH-2000 Setup...done\n");
- return 0;
-}
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_sh2000 __initmv = {
- .mv_name = "sh2000",
-
- .mv_nr_irqs = 80,
-
- .mv_inb = generic_inb,
- .mv_inw = generic_inw,
- .mv_inl = generic_inl,
- .mv_outb = generic_outb,
- .mv_outw = generic_outw,
- .mv_outl = generic_outl,
-
- .mv_inb_p = generic_inb_p,
- .mv_inw_p = generic_inw_p,
- .mv_inl_p = generic_inl_p,
- .mv_outb_p = generic_outb_p,
- .mv_outw_p = generic_outw_p,
- .mv_outl_p = generic_outl_p,
-
- .mv_insb = generic_insb,
- .mv_insw = generic_insw,
- .mv_insl = generic_insl,
- .mv_outsb = generic_outsb,
- .mv_outsw = generic_outsw,
- .mv_outsl = generic_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_init_arch = setup_sh2000,
-
- .mv_isa_port2addr = sh2000_isa_port2addr,
-
- .mv_ioremap = generic_ioremap,
- .mv_iounmap = generic_iounmap,
-
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-
- .mv_hw_sh2000 = 1,
-};
-ALIAS_MV(sh2000)
diff --git a/arch/sh/stboards/Makefile b/arch/sh/stboards/Makefile
deleted file mode 100644
index f80ed133166c..000000000000
--- a/arch/sh/stboards/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for STMicroelectronics board specific parts of the kernel
-#
-
-obj-y := irq.o setup.o mach.o led.o
diff --git a/arch/sh/stboards/harp.h b/arch/sh/stboards/harp.h
deleted file mode 100644
index b2fbcfae9940..000000000000
--- a/arch/sh/stboards/harp.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Defintions applicable to the STMicroelectronics ST40STB1 HARP and
- * compatible boards.
- */
-
-#if defined(CONFIG_SH_STB1_HARP)
-
-#define EPLD_BASE 0xa0800000
-
-#define EPLD_LED (EPLD_BASE+0x000c0000)
-#define EPLD_INTSTAT0 (EPLD_BASE+0x00200000)
-#define EPLD_INTSTAT1 (EPLD_BASE+0x00240000)
-#define EPLD_INTMASK0 (EPLD_BASE+0x00280000)
-#define EPLD_INTMASK1 (EPLD_BASE+0x002c0000)
-#define EPLD_PAGEADDR (EPLD_BASE+0x00300000)
-#define EPLD_REVID1 (EPLD_BASE+0x00380000)
-#define EPLD_REVID2 (EPLD_BASE+0x003c0000)
-
-#define EPLD_LED_ON 1
-#define EPLD_LED_OFF 0
-
-#elif defined(CONFIG_SH_STB1_OVERDRIVE)
-
-#define EPLD_BASE 0xa7000000
-
-#define EPLD_REVID (EPLD_BASE+0x00000000)
-#define EPLD_LED (EPLD_BASE+0x00040000)
-#define EPLD_INTMASK0 (EPLD_BASE+0x001c0000)
-#define EPLD_INTMASK1 (EPLD_BASE+0x00200000)
-#define EPLD_INTSTAT0 (EPLD_BASE+0x00240000)
-#define EPLD_INTSTAT1 (EPLD_BASE+0x00280000)
-
-#define EPLD_LED_ON 0
-#define EPLD_LED_OFF 1
-
-#else
-#error Unknown board
-#endif
diff --git a/arch/sh/stboards/mach.c b/arch/sh/stboards/mach.c
deleted file mode 100644
index 879bfe9e5a73..000000000000
--- a/arch/sh/stboards/mach.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * linux/arch/sh/stboards/mach.c
- *
- * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Machine vector for the STMicroelectronics STB1 HARP and compatible boards
- */
-
-#include <linux/init.h>
-
-#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/machvec_init.h>
-#include <asm/io_hd64465.h>
-#include <asm/hd64465.h>
-
-void setup_harp(void);
-void init_harp_irq(void);
-void heartbeat_harp(void);
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_harp __initmv = {
- .mv_name = "STB1 Harp",
-
- .mv_nr_irqs = 89 + HD64465_IRQ_NUM,
-
- .mv_inb = hd64465_inb,
- .mv_inw = hd64465_inw,
- .mv_inl = hd64465_inl,
- .mv_outb = hd64465_outb,
- .mv_outw = hd64465_outw,
- .mv_outl = hd64465_outl,
-
- .mv_inb_p = hd64465_inb_p,
- .mv_inw_p = hd64465_inw,
- .mv_inl_p = hd64465_inl,
- .mv_outb_p = hd64465_outb_p,
- .mv_outw_p = hd64465_outw,
- .mv_outl_p = hd64465_outl,
-
- .mv_insb = hd64465_insb,
- .mv_insw = hd64465_insw,
- .mv_insl = hd64465_insl,
- .mv_outsb = hd64465_outsb,
- .mv_outsw = hd64465_outsw,
- .mv_outsl = hd64465_outsl,
-
- .mv_readb = generic_readb,
- .mv_readw = generic_readw,
- .mv_readl = generic_readl,
- .mv_writeb = generic_writeb,
- .mv_writew = generic_writew,
- .mv_writel = generic_writel,
-
- .mv_ioremap = generic_ioremap,
- .mv_iounmap = generic_iounmap,
-
- .mv_isa_port2addr = hd64465_isa_port2addr,
-
- .mv_init_arch = setup_harp,
-#ifdef CONFIG_PCI
- .mv_init_irq = init_harp_irq,
-#endif
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_harp,
-#endif
- .mv_rtc_gettimeofday = sh_rtc_gettimeofday,
- .mv_rtc_settimeofday = sh_rtc_settimeofday,
-};
-
-ALIAS_MV(harp)
diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
index f618f3b43900..2cc86534c130 100644
--- a/arch/sh/vmlinux.lds.S
+++ b/arch/sh/vmlinux.lds.S
@@ -1,4 +1,4 @@
-/* $Id: vmlinux.lds.in,v 1.5 2001/07/27 11:45:55 gniibe Exp $
+/* $Id: vmlinux.lds.S,v 1.8 2003/05/16 17:18:14 lethal Exp $
* ld script to make SuperH Linux kernel
* Written by Niibe Yutaka
*/
@@ -7,16 +7,14 @@
#ifdef CONFIG_CPU_LITTLE_ENDIAN
OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
-jiffies = jiffies_64;
#else
OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
-jiffies = jiffies_64 + 4;
#endif
OUTPUT_ARCH(sh)
ENTRY(_start)
SECTIONS
{
- . = 0x80000000 + CONFIG_MEMORY_START + 0x1000;
+ . = 0x80000000 + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
_text = .; /* Text and read-only data */
text = .; /* Text and read-only data */
.empty_zero_page : {
@@ -42,6 +40,15 @@ SECTIONS
CONSTRUCTORS
}
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+ . = ALIGN(32);
+ __per_cpu_start = .;
+ .data.percpu : { *(.data.percpu) }
+ __per_cpu_end = .;
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
_edata = .; /* End of data section */
. = ALIGN(8192); /* init_task */
@@ -51,12 +58,17 @@ SECTIONS
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
- .text.init : { *(.text.init) }
- .data.init : { *(.data.init) }
+ _sinittext = .;
+ .init.text : { *(.init.text) }
+ _einittext = .;
+ .init.data : { *(.init.data) }
. = ALIGN(16);
__setup_start = .;
- .setup.init : { *(.setup.init) }
+ .init.setup : { *(.init.setup) }
__setup_end = .;
+ __start___param = .;
+ __param : { *(__param) }
+ __stop___param = .;
__initcall_start = .;
.initcall.init : {
*(.initcall1.init)
@@ -71,27 +83,20 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
+ __initramfs_start = .;
+ .init.ramfs : { *(.init.ramfs) }
+ __initramfs_end = .;
__machvec_start = .;
- .machvec.init : { *(.machvec.init) }
+ .init.machvec : { *(.init.machvec) }
__machvec_end = .;
. = ALIGN(4096);
__init_end = .;
- . = ALIGN(4096);
- .data.page_aligned : { *(.data.idt) }
-
-#ifdef CONFIG_CPU_SH3
- . = ALIGN(16);
-#else
- . = ALIGN(32);
-#endif
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
. = ALIGN(4);
__bss_start = .; /* BSS */
- .bss : {
- *(.bss)
- }
+ .bss : { *(.bss) }
+
. = ALIGN(4);
_end = . ;
@@ -101,8 +106,8 @@ SECTIONS
* it's a module.
*/
/DISCARD/ : {
- *(.text.exit)
- *(.data.exit)
+ *(.exit.text)
+ *(.exit.data)
*(.exitcall.exit)
}
diff --git a/arch/sparc/vmlinux.lds.S b/arch/sparc/vmlinux.lds.S
index 40fbec8537e2..0862360d865d 100644
--- a/arch/sparc/vmlinux.lds.S
+++ b/arch/sparc/vmlinux.lds.S
@@ -62,6 +62,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff --git a/arch/sparc64/vmlinux.lds.S b/arch/sparc64/vmlinux.lds.S
index 0c8919aa9f87..ad95e88a3cbc 100644
--- a/arch/sparc64/vmlinux.lds.S
+++ b/arch/sparc64/vmlinux.lds.S
@@ -68,6 +68,7 @@ SECTIONS
__con_initcall_start = .;
.con_initcall.init : { *(.con_initcall.init) }
__con_initcall_end = .;
+ SECURITY_INIT
. = ALIGN(8192);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 0bc2d8c94181..10f78014d6e6 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -52,6 +52,18 @@ config EARLY_PRINTK
klogd/syslogd or the X server. You should normally N here, unless
you want to debug such a crash.
+config HPET_TIMER
+ bool
+ default y
+ help
+ Use the IA-PC HPET (High Precision Event Timer) to manage
+ time in preference to the PIT and RTC, if a HPET is
+ present. The HPET provides a stable time base on SMP
+ systems, unlike the RTC, but it is more expensive to access,
+ as it is off-chip. You can find the HPET spec at
+ <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
+
+ If unsure, say Y.
config GENERIC_ISA_DMA
bool
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index a3cb3f13e9a7..4032f0720c2a 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -47,6 +47,7 @@
ENTRY(ia32_cstar_target)
swapgs
movl %esp,%r8d
+ movq %r8,%gs:pda_oldrsp
movq %gs:pda_kernelstack,%rsp
sti
SAVE_ARGS 8,1
diff --git a/arch/x86_64/kernel/acpi/boot.c b/arch/x86_64/kernel/acpi/boot.c
index e88862d9127b..d222d13acd7e 100644
--- a/arch/x86_64/kernel/acpi/boot.c
+++ b/arch/x86_64/kernel/acpi/boot.c
@@ -244,9 +244,11 @@ acpi_parse_hpet (
return -1;
}
- hpet.address = hpet_tbl->addr.addrl | ((long) hpet_tbl->addr.addrh << 32);
+ vxtime.hpet_address = hpet_tbl->addr.addrl |
+ ((long) hpet_tbl->addr.addrh << 32);
- printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet.address);
+ printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n",
+ hpet_tbl->id, vxtime.hpet_address);
return 0;
}
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 98440f87fc84..1addbb749ec2 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -690,7 +690,13 @@ static void setup_APIC_timer(unsigned int clocks)
}
/* wait for irq slice */
- {
+ if (vxtime.hpet_address) {
+ int trigger = hpet_readl(HPET_T0_CMP);
+ while (hpet_readl(HPET_COUNTER) >= trigger)
+ /* do nothing */ ;
+ while (hpet_readl(HPET_COUNTER) < trigger)
+ /* do nothing */ ;
+ } else {
int c1, c2;
outb_p(0x00, 0x43);
c2 = inb_p(0x40);
diff --git a/arch/x86_64/kernel/bluesmoke.c b/arch/x86_64/kernel/bluesmoke.c
index 00f2abe0ba46..392b8bab96ee 100644
--- a/arch/x86_64/kernel/bluesmoke.c
+++ b/arch/x86_64/kernel/bluesmoke.c
@@ -363,22 +363,12 @@ static void __init k8_mcheck_init(struct cpuinfo_x86 *c)
machine_check_vector = k8_machine_check;
for (i = 0; i < banks; i++) {
u64 val = ((1UL<<i) & disabled_banks) ? 0 : ~0UL;
+ if (val && i == 4)
+ val = k8_nb_flags;
wrmsrl(MSR_IA32_MC0_CTL+4*i, val);
wrmsrl(MSR_IA32_MC0_STATUS+4*i,0);
}
- nb = find_k8_nb();
- if (nb != NULL) {
- u32 reg, reg2;
- pci_read_config_dword(nb, 0x40, &reg);
- pci_write_config_dword(nb, 0x40, k8_nb_flags);
- pci_read_config_dword(nb, 0x44, &reg2);
- pci_write_config_dword(nb, 0x44, reg2);
- printk(KERN_INFO "Machine Check for K8 Northbridge %d enabled (%x,%x)\n",
- nb->devfn, reg, reg2);
- ignored_banks |= (1UL<<4);
- }
-
set_in_cr4(X86_CR4_MCE);
if (mcheck_interval && (smp_processor_id() == 0)) {
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 8e69eb12d341..12047fff5230 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -173,12 +173,10 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
if (iommu_page == -1)
goto error;
- /* Fill in the GATT, allocating pages as needed. */
+ /* Fill in the GATT */
for (i = 0; i < size; i++) {
unsigned long phys_mem;
void *mem = memory + i*PAGE_SIZE;
- if (i > 0)
- atomic_inc(&virt_to_page(mem)->count);
phys_mem = virt_to_phys(mem);
BUG_ON(phys_mem & ~PHYSICAL_PAGE_MASK);
iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
@@ -206,16 +204,14 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size,
size = round_up(size, PAGE_SIZE);
if (bus >= iommu_bus_base && bus <= iommu_bus_base + iommu_size) {
unsigned pages = size >> PAGE_SHIFT;
+ int i;
iommu_page = (bus - iommu_bus_base) >> PAGE_SHIFT;
vaddr = __va(GPTE_DECODE(iommu_gatt_base[iommu_page]));
-#ifdef CONFIG_IOMMU_DEBUG
- int i;
for (i = 0; i < pages; i++) {
u64 pte = iommu_gatt_base[iommu_page + i];
BUG_ON((pte & GPTE_VALID) == 0);
iommu_gatt_base[iommu_page + i] = 0;
}
-#endif
free_iommu(iommu_page, pages);
}
free_pages((unsigned long)vaddr, get_order(size));
@@ -319,11 +315,6 @@ dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, int dir)
*/
iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
-#ifdef CONFIG_IOMMU_DEBUG
- /* paranoia check */
- BUG_ON(GPTE_DECODE(iommu_gatt_base[iommu_page+i]) != phys_mem);
-#endif
-
#ifdef CONFIG_IOMMU_LEAK
/* XXX need eventually caller of pci_map_sg */
if (iommu_leak_tab)
@@ -350,7 +341,6 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
return;
iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
-#ifdef CONFIG_IOMMU_DEBUG
int i;
for (i = 0; i < npages; i++) {
iommu_gatt_base[iommu_page + i] = 0;
@@ -359,7 +349,6 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
iommu_leak_tab[iommu_page + i] = 0;
#endif
}
-#endif
free_iommu(iommu_page, npages);
}
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index e2c5421dcb1f..5a5b2fe81e6c 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -150,7 +150,7 @@ __setup("idle=", idle_setup);
/* Prints also some state that isn't saved in the pt_regs */
-void show_regs(struct pt_regs * regs)
+void __show_regs(struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
unsigned int fsindex,gsindex;
@@ -192,7 +192,11 @@ void show_regs(struct pt_regs * regs)
fs,fsindex,gs,gsindex,shadowgs);
printk("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0);
printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
+}
+void show_regs(struct pt_regs *regs)
+{
+ __show_regs(regs);
show_trace(&regs->rsp);
}
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index d554126c5e64..00ee45c7a21b 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -67,6 +67,8 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
/* Set when the idlers are all forked */
int smp_threads_ready;
+extern void time_init_smp(void);
+
/*
* Trampoline 80x86 program as an array.
*/
@@ -760,7 +762,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
if (APIC_init_uniprocessor())
printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n");
- return;
+ goto smp_done;
}
/*
@@ -784,7 +786,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpu_online_map = phys_cpu_present_map = 1;
phys_cpu_present_map = 1;
disable_apic = 1;
- return;
+ goto smp_done;
}
verify_local_APIC();
@@ -799,7 +801,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
cpu_online_map = phys_cpu_present_map = 1;
phys_cpu_present_map = 1;
disable_apic = 1;
- return;
+ goto smp_done;
}
connect_bsp_APIC();
@@ -883,6 +885,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
*/
if (cpu_has_tsc && cpucount)
synchronize_tsc_bp();
+
+ smp_done:
+ time_init_smp();
}
/* These are wrappers to interface to the new boot process. Someone
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 18c60397a8ea..aaa976327a82 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/bcd.h>
+#include <asm/pgtable.h>
#include <asm/vsyscall.h>
#include <asm/timex.h>
#ifdef CONFIG_X86_LOCAL_APIC
@@ -35,41 +36,61 @@ u64 jiffies_64 = INITIAL_JIFFIES;
extern int using_apic_timer;
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
extern int using_apic_timer;
extern void smp_local_timer_interrupt(struct pt_regs * regs);
+#undef HPET_HACK_ENABLE_DANGEROUS
+
unsigned int cpu_khz; /* TSC clocks / usec, not used here */
unsigned long hpet_period; /* fsecs / HPET clock */
unsigned long hpet_tick; /* HPET clocks / interrupt */
-int hpet_report_lost_ticks; /* command line option */
+unsigned long vxtime_hz = 1193182;
+int report_lost_ticks; /* command line option */
-struct hpet_data __hpet __section_hpet; /* address, quotient, trigger, hz */
+struct vxtime_data __vxtime __section_vxtime; /* for vsyscalls */
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES;
struct timespec __xtime __section_xtime;
struct timezone __sys_tz __section_sys_tz;
+static inline void rdtscll_sync(unsigned long *tsc)
+{
+#ifdef CONFIG_SMP
+ sync_core();
+#endif
+ rdtscll(*tsc);
+}
+
/*
* do_gettimeoffset() returns microseconds since last timer interrupt was
* triggered by hardware. A memory read of HPET is slower than a register read
* of TSC, but much more reliable. It's also synchronized to the timer
* interrupt. Note that do_gettimeoffset() may return more than hpet_tick, if a
- * timer interrupt has happened already, but hpet.trigger wasn't updated yet.
+ * timer interrupt has happened already, but vxtime.trigger wasn't updated yet.
* This is not a problem, because jiffies hasn't updated either. They are bound
* together by xtime_lock.
*/
-inline unsigned int do_gettimeoffset(void)
+static inline unsigned int do_gettimeoffset_tsc(void)
{
unsigned long t;
- sync_core();
- rdtscll(t);
- return (t - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset;
+ unsigned long x;
+ rdtscll_sync(&t);
+ x = ((t - vxtime.last_tsc) * vxtime.tsc_quot) >> 32;
+ return x;
+}
+
+static inline unsigned int do_gettimeoffset_hpet(void)
+{
+ return ((hpet_readl(HPET_COUNTER) - vxtime.last) * vxtime.quot) >> 32;
}
+unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc;
+
/*
* This version of gettimeofday() has microsecond resolution and better than
* microsecond precision, as we're using at least a 10 MHz (usually 14.31818
@@ -87,7 +108,8 @@ void do_gettimeofday(struct timeval *tv)
sec = xtime.tv_sec;
usec = xtime.tv_nsec / 1000;
- t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset();
+ t = (jiffies - wall_jiffies) * (1000000L / HZ) +
+ do_gettimeoffset();
usec += t;
} while (read_seqretry(&xtime_lock, seq));
@@ -107,7 +129,7 @@ void do_settimeofday(struct timeval *tv)
write_seqlock_irq(&xtime_lock);
tv->tv_usec -= do_gettimeoffset() +
- (jiffies - wall_jiffies) * tick_usec;
+ (jiffies - wall_jiffies) * (USEC_PER_SEC/HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
@@ -178,8 +200,8 @@ static void set_rtc_mmss(unsigned long nowtime)
CMOS_WRITE(real_seconds, RTC_SECONDS);
CMOS_WRITE(real_minutes, RTC_MINUTES);
} else
- printk(KERN_WARNING "time.c: can't update CMOS clock from %d to %d\n",
- cmos_minutes, real_minutes);
+ printk(KERN_WARNING "time.c: can't update CMOS clock "
+ "from %d to %d\n", cmos_minutes, real_minutes);
/*
* The following flags have to be released exactly in this order, otherwise the
@@ -198,6 +220,8 @@ static void set_rtc_mmss(unsigned long nowtime)
static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
static unsigned long rtc_update = 0;
+ unsigned long tsc, lost = 0;
+ int delay, offset = 0;
/*
* Here we are in the timer irq handler. We have irqs locally disabled (so we
@@ -208,17 +232,53 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
write_seqlock(&xtime_lock);
- {
- unsigned long t;
+ if (vxtime.hpet_address) {
+ offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
+ delay = hpet_readl(HPET_COUNTER) - offset;
+ } else {
+ spin_lock(&i8253_lock);
+ outb_p(0x00, 0x43);
+ delay = inb_p(0x40);
+ delay |= inb(0x40) << 8;
+ spin_unlock(&i8253_lock);
+ delay = LATCH - 1 - delay;
+ }
- sync_core();
- rdtscll(t);
- hpet.offset = (t - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset - 1000000L / HZ;
- if (hpet.offset >= 1000000L / HZ)
- hpet.offset = 0;
- hpet.ticks = min_t(long, max_t(long, (t - hpet.last_tsc) * (1000000L / HZ) / (1000000L / HZ - hpet.offset),
- cpu_khz * 1000/HZ * 15 / 16), cpu_khz * 1000/HZ * 16 / 15);
- hpet.last_tsc = t;
+ rdtscll_sync(&tsc);
+
+ if (vxtime.mode == VXTIME_HPET) {
+ if (offset - vxtime.last > hpet_tick) {
+ lost = (offset - vxtime.last) / hpet_tick - 1;
+ }
+
+ vxtime.last = offset;
+ } else {
+ offset = (((tsc - vxtime.last_tsc) *
+ vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ);
+
+ if (offset < 0)
+ offset = 0;
+
+ if (offset > (USEC_PER_SEC / HZ)) {
+ lost = offset / (USEC_PER_SEC / HZ);
+ offset %= (USEC_PER_SEC / HZ);
+ }
+
+ vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot;
+
+ if ((((tsc - vxtime.last_tsc) *
+ vxtime.tsc_quot) >> 32) < offset)
+ vxtime.last_tsc = tsc -
+ (((long) offset << 32) / vxtime.tsc_quot) - 1;
+ }
+
+ if (lost) {
+ if (report_lost_ticks)
+ printk(KERN_WARNING "time.c: Lost %ld timer "
+ "tick(s)! (rip %016lx)\n",
+ (offset - vxtime.last) / hpet_tick - 1,
+ regs->rip);
+ jiffies += lost;
}
/*
@@ -244,7 +304,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* If we have an externally synchronized Linux clock, then update CMOS clock
* accordingly every ~11 minutes. set_rtc_mmss() will be called in the jiffy
* closest to exactly 500 ms before the next second. If the update fails, we
- * don'tcare, as it'll be updated on the next turn, and the problem (time way
+ * don't care, as it'll be updated on the next turn, and the problem (time way
* off) isn't likely to go away much sooner anyway.
*/
@@ -263,6 +323,7 @@ unsigned long get_cmos_time(void)
{
unsigned int timeout, year, mon, day, hour, min, sec;
unsigned char last, this;
+ unsigned long flags;
/*
* The Linux interpretation of the CMOS clock register contents: When the
@@ -272,7 +333,7 @@ unsigned long get_cmos_time(void)
* standard 8.3 MHz ISA bus.
*/
- spin_lock(&rtc_lock);
+ spin_lock_irqsave(&rtc_lock, flags);
timeout = 1000000;
last = this = 0;
@@ -295,7 +356,7 @@ unsigned long get_cmos_time(void)
mon = CMOS_READ(RTC_MONTH);
year = CMOS_READ(RTC_YEAR);
- spin_unlock(&rtc_lock);
+ spin_unlock_irqrestore(&rtc_lock, flags);
/*
* We know that x86-64 always uses BCD format, no need to check the config
@@ -326,6 +387,32 @@ unsigned long get_cmos_time(void)
#define TICK_COUNT 100000000
+static unsigned int __init hpet_calibrate_tsc(void)
+{
+ int tsc_start, hpet_start;
+ int tsc_now, hpet_now;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ local_irq_disable();
+
+ hpet_start = hpet_readl(HPET_COUNTER);
+ rdtscl(tsc_start);
+
+ do {
+ local_irq_disable();
+ hpet_now = hpet_readl(HPET_COUNTER);
+ sync_core();
+ rdtscl(tsc_now);
+ local_irq_restore(flags);
+ } while ((tsc_now - tsc_start) < TICK_COUNT &&
+ (hpet_now - hpet_start) < TICK_COUNT);
+
+ return (tsc_now - tsc_start) * 1000000000L
+ / ((hpet_now - hpet_start) * hpet_period / 1000);
+}
+
+
/*
* pit_calibrate_tsc() uses the speaker output (channel 2) of
* the PIT. This is better than using the timer interrupt output,
@@ -339,10 +426,9 @@ static unsigned int __init pit_calibrate_tsc(void)
unsigned long start, end;
unsigned long flags;
- outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+ spin_lock_irqsave(&i8253_lock, flags);
- local_irq_save(flags);
- local_irq_disable();
+ outb((inb(0x61) & ~0x02) | 0x01, 0x61);
outb(0xb0, 0x43);
outb((1193182 / (1000 / 50)) & 0xff, 0x42);
@@ -353,42 +439,146 @@ static unsigned int __init pit_calibrate_tsc(void)
sync_core();
rdtscll(end);
-
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&i8253_lock, flags);
return (end - start) / 50;
}
+static int hpet_init(void)
+{
+ unsigned int cfg, id;
+
+ if (!vxtime.hpet_address)
+ return -1;
+ set_fixmap_nocache(FIX_HPET_BASE, vxtime.hpet_address);
+
+/*
+ * Read the period, compute tick and quotient.
+ */
+
+ id = hpet_readl(HPET_ID);
+
+ if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER) ||
+ !(id & HPET_ID_LEGSUP))
+ return -1;
+
+ hpet_period = hpet_readl(HPET_PERIOD);
+ if (hpet_period < 100000 || hpet_period > 100000000)
+ return -1;
+
+ hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) /
+ hpet_period;
+
+/*
+ * Stop the timers and reset the main counter.
+ */
+
+ cfg = hpet_readl(HPET_CFG);
+ cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
+ hpet_writel(cfg, HPET_CFG);
+ hpet_writel(0, HPET_COUNTER);
+ hpet_writel(0, HPET_COUNTER + 4);
+
+/*
+ * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
+ * and period also hpet_tick.
+ */
+
+ hpet_writel(HPET_T0_ENABLE | HPET_T0_PERIODIC | HPET_T0_SETVAL |
+ HPET_T0_32BIT, HPET_T0_CFG);
+ hpet_writel(hpet_tick, HPET_T0_CMP);
+ hpet_writel(hpet_tick, HPET_T0_CMP);
+
+/*
+ * Go!
+ */
+
+ cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY;
+ hpet_writel(cfg, HPET_CFG);
+
+ return 0;
+}
+
void __init pit_init(void)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&i8253_lock, flags);
outb_p(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff, 0x40); /* LSB */
outb_p(LATCH >> 8, 0x40); /* MSB */
+ spin_unlock_irqrestore(&i8253_lock, flags);
}
int __init time_setup(char *str)
{
- hpet_report_lost_ticks = 1;
+ report_lost_ticks = 1;
return 1;
}
-static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
+static struct irqaction irq0 = {
+ timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL
+};
extern void __init config_acpi_tables(void);
void __init time_init(void)
{
+ char *timename;
+
+#ifdef HPET_HACK_ENABLE_DANGEROUS
+ if (!vxtime.hpet_address) {
+ printk(KERN_WARNING "time.c: WARNING: Enabling HPET base "
+ "manually!\n");
+ outl(0x800038a0, 0xcf8);
+ outl(0xff000001, 0xcfc);
+ outl(0x800038a0, 0xcf8);
+ hpet_address = inl(0xcfc) & 0xfffffffe;
+ printk(KERN_WARNING "time.c: WARNING: Enabled HPET "
+ "at %#lx.\n", hpet_address);
+ }
+#endif
+
xtime.tv_sec = get_cmos_time();
xtime.tv_nsec = 0;
+ if (!hpet_init()) {
+ vxtime_hz = (1000000000000000L + hpet_period / 2) /
+ hpet_period;
+ cpu_khz = hpet_calibrate_tsc();
+ timename = "HPET";
+ } else {
pit_init();
- printk(KERN_INFO "time.c: Using 1.1931816 MHz PIT timer.\n");
cpu_khz = pit_calibrate_tsc();
+ timename = "PIT";
+ }
+
+ printk(KERN_INFO "time.c: Using %ld.%06ld MHz %s timer.\n",
+ vxtime_hz / 1000000, vxtime_hz % 1000000, timename);
printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000);
- hpet.ticks = cpu_khz * (1000 / HZ);
- rdtscll(hpet.last_tsc);
+ vxtime.mode = VXTIME_TSC;
+ vxtime.quot = (1000000L << 32) / vxtime_hz;
+ vxtime.tsc_quot = (1000L << 32) / cpu_khz;
+ vxtime.hz = vxtime_hz;
+ rdtscll_sync(&vxtime.last_tsc);
setup_irq(0, &irq0);
}
+void __init time_init_smp(void)
+{
+ char *timetype;
+
+ if (vxtime.hpet_address) {
+ timetype = "HPET";
+ vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
+ vxtime.mode = VXTIME_HPET;
+ do_gettimeoffset = do_gettimeoffset_hpet;
+ } else {
+ timetype = "PIT/TSC";
+ vxtime.mode = VXTIME_TSC;
+ }
+ printk(KERN_INFO "time.c: Using %s based timekeeping.\n", timetype);
+}
+
__setup("report_lost_ticks", time_setup);
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index e1620dc69800..24d5862bdcd7 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -263,7 +263,7 @@ void show_registers(struct pt_regs *regs)
rsp = regs->rsp;
printk("CPU %d ", cpu);
- show_regs(regs);
+ __show_regs(regs);
printk("Process %s (pid: %d, stackpage=%08lx)\n",
cur->comm, cur->pid, 4096+(unsigned long)cur);
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index 4162dd9bf8dc..cb52162ae495 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -78,13 +78,21 @@ static force_inline void do_vgettimeofday(struct timeval * tv)
do {
sequence = read_seqbegin(&__xtime_lock);
- sync_core();
- rdtscll(t);
sec = __xtime.tv_sec;
usec = (__xtime.tv_nsec / 1000) +
- (__jiffies - __wall_jiffies) * (1000000 / HZ) +
- (t - __hpet.last_tsc) * (1000000 / HZ) / __hpet.ticks + __hpet.offset;
-
+ (__jiffies - __wall_jiffies) * (1000000 / HZ);
+
+ if (__vxtime.mode == VXTIME_TSC) {
+ sync_core();
+ rdtscll(t);
+ usec += ((t - __vxtime.last_tsc) *
+ __vxtime.tsc_quot) >> 32;
+ } else {
+#if 0
+ usec += ((readl(fix_to_virt(VSYSCALL_HPET) + 0xf0) -
+ __vxtime.last) * __vxtime.quot) >> 32;
+#endif
+ }
} while (read_seqretry(&__xtime_lock, sequence));
tv->tv_sec = sec + usec / 1000000;
diff --git a/arch/x86_64/lib/clear_page.S b/arch/x86_64/lib/clear_page.S
index b34c34f85fc6..5867f704c0ad 100644
--- a/arch/x86_64/lib/clear_page.S
+++ b/arch/x86_64/lib/clear_page.S
@@ -1,19 +1,18 @@
-/*
- * Copyright 2002 Andi Kleen, SuSE Labs.
- */
- #include <linux/linkage.h>
/*
* Zero a page.
* rdi page
*/
-ENTRY(clear_page)
+ .globl clear_page
+ .p2align 4
+clear_page:
xorl %eax,%eax
- movl $4096/128,%ecx
- movl $128,%edx
-loop:
+ movl $4096/64,%ecx
+ .p2align 4
+.Lloop:
+ decl %ecx
#define PUT(x) movq %rax,x*8(%rdi)
- PUT(0)
+ movq %rax,(%rdi)
PUT(1)
PUT(2)
PUT(3)
@@ -21,17 +20,8 @@ loop:
PUT(5)
PUT(6)
PUT(7)
- PUT(8)
- PUT(9)
- PUT(10)
- PUT(11)
- PUT(12)
- PUT(13)
- PUT(14)
- PUT(15)
- addq %rdx,%rdi
- decl %ecx
- jnz loop
- sfence
+ leaq 64(%rdi),%rdi
+ jnz .Lloop
+ nop
ret
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S
index 71d3c57441fa..72eb9314bd37 100644
--- a/arch/x86_64/lib/copy_page.S
+++ b/arch/x86_64/lib/copy_page.S
@@ -1,74 +1,91 @@
-/*
- * Copyright 2002 Andi Kleen, SuSE Labs.
- */
+/* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */
- #include <linux/linkage.h>
- #include <linux/config.h>
- #ifdef CONFIG_PREEMPT
- #warning "check your fpu context saving!"
- #endif
+/* Don't use streaming store because it's better when the target
+ ends up in cache. */
+
+/* Could vary the prefetch distance based on SMP/UP */
-/*
- * Copy a page.
- *
- * rdi destination page
- * rsi source page
- *
- * src/dst must be aligned to 16 bytes.
- *
- * Warning: in case of super lazy FP save this needs to be preempt_stop
- */
-
.globl copy_page
- .p2align
+ .p2align 4
copy_page:
- prefetchnta (%rsi)
- prefetchnta 64(%rsi)
-
- movq %rsp,%rax
- subq $16*4,%rsp
- andq $~15,%rsp
- movdqa %xmm0,(%rsp)
- movdqa %xmm1,16(%rsp)
- movdqa %xmm2,32(%rsp)
- movdqa %xmm3,48(%rsp)
-
- movl $(4096/128)-2,%ecx
- movl $128,%edx
-loop:
- prefetchnta (%rsi)
- prefetchnta 64(%rsi)
-loop_no_prefetch:
- movdqa (%rsi),%xmm0
- movdqa 16(%rsi),%xmm1
- movdqa 32(%rsi),%xmm2
- movdqa 48(%rsi),%xmm3
- movntdq %xmm0,(%rdi)
- movntdq %xmm1,16(%rdi)
- movntdq %xmm2,32(%rdi)
- movntdq %xmm3,48(%rdi)
-
- movdqa 64(%rsi),%xmm0
- movdqa 80(%rsi),%xmm1
- movdqa 96(%rsi),%xmm2
- movdqa 112(%rsi),%xmm3
- movntdq %xmm0,64(%rdi)
- movntdq %xmm1,80(%rdi)
- movntdq %xmm2,96(%rdi)
- movntdq %xmm3,112(%rdi)
+ prefetch (%rsi)
+ prefetch 1*64(%rsi)
+ prefetch 2*64(%rsi)
+ prefetch 3*64(%rsi)
+ prefetch 4*64(%rsi)
+ prefetchw (%rdi)
+ prefetchw 1*64(%rdi)
+ prefetchw 2*64(%rdi)
+ prefetchw 3*64(%rdi)
+ prefetchw 4*64(%rdi)
+
+ subq $3*8,%rsp
+ movq %rbx,(%rsp)
+ movq %r12,1*8(%rsp)
+ movq %r13,2*8(%rsp)
+
+ movl $(4096/64)-5,%ecx
+ .p2align 4
+.Loop64:
+ dec %rcx
+
+ movq (%rsi), %rax
+ movq 8 (%rsi), %rbx
+ movq 16 (%rsi), %rdx
+ movq 24 (%rsi), %r8
+ movq 32 (%rsi), %r9
+ movq 40 (%rsi), %r10
+ movq 48 (%rsi), %r11
+ movq 56 (%rsi), %r12
+
+ prefetch 5*64(%rsi)
+
+ movq %rax, (%rdi)
+ movq %rbx, 8 (%rdi)
+ movq %rdx, 16 (%rdi)
+ movq %r8, 24 (%rdi)
+ movq %r9, 32 (%rdi)
+ movq %r10, 40 (%rdi)
+ movq %r11, 48 (%rdi)
+ movq %r12, 56 (%rdi)
- addq %rdx,%rdi
- addq %rdx,%rsi
+ prefetchw 5*64(%rdi)
+
+ leaq 64 (%rsi), %rsi
+ leaq 64 (%rdi), %rdi
+
+ jnz .Loop64
+
+ movl $5,%ecx
+ .p2align 4
+.Loop2:
decl %ecx
- jns loop
- cmpl $-1,%ecx
- je loop_no_prefetch
-
- sfence
- movdqa (%rsp),%xmm0
- movdqa 16(%rsp),%xmm1
- movdqa 32(%rsp),%xmm2
- movdqa 48(%rsp),%xmm3
- movq %rax,%rsp
+ movq (%rsi), %rax
+ movq 8 (%rsi), %rbx
+ movq 16 (%rsi), %rdx
+ movq 24 (%rsi), %r8
+ movq 32 (%rsi), %r9
+ movq 40 (%rsi), %r10
+ movq 48 (%rsi), %r11
+ movq 56 (%rsi), %r12
+
+ movq %rax, (%rdi)
+ movq %rbx, 8 (%rdi)
+ movq %rdx, 16 (%rdi)
+ movq %r8, 24 (%rdi)
+ movq %r9, 32 (%rdi)
+ movq %r10, 40 (%rdi)
+ movq %r11, 48 (%rdi)
+ movq %r12, 56 (%rdi)
+
+ leaq 64(%rdi),%rdi
+ leaq 64(%rsi),%rsi
+
+ jnz .Loop2
+
+ movq (%rsp),%rbx
+ movq 1*8(%rsp),%r12
+ movq 2*8(%rsp),%r13
+ addq $3*8,%rsp
ret
diff --git a/arch/x86_64/lib/csum-copy.S b/arch/x86_64/lib/csum-copy.S
index ccd89d25fe85..7aa2cec7ab8f 100644
--- a/arch/x86_64/lib/csum-copy.S
+++ b/arch/x86_64/lib/csum-copy.S
@@ -1,5 +1,5 @@
/*
- * Copyright 2002 Andi Kleen
+ * Copyright 2002,2003 Andi Kleen, SuSE Labs.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
@@ -8,7 +8,6 @@
#include <linux/linkage.h>
#include <asm/errno.h>
-// #define FIX_ALIGNMENT 1
/*
* Checksum copy with exception handling.
* On exceptions src_err_ptr or dst_err_ptr is set to -EFAULT and the
@@ -26,17 +25,14 @@
* eax 64bit sum. undefined in case of exception.
*