aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sh
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/Kconfig793
-rw-r--r--arch/sh/Kconfig.debug124
-rw-r--r--arch/sh/Makefile183
-rw-r--r--arch/sh/boards/adx/Makefile6
-rw-r--r--arch/sh/boards/adx/irq.c31
-rw-r--r--arch/sh/boards/adx/irq_maskreg.c107
-rw-r--r--arch/sh/boards/adx/setup.c56
-rw-r--r--arch/sh/boards/bigsur/Makefile6
-rw-r--r--arch/sh/boards/bigsur/io.c125
-rw-r--r--arch/sh/boards/bigsur/irq.c348
-rw-r--r--arch/sh/boards/bigsur/led.c55
-rw-r--r--arch/sh/boards/bigsur/setup.c96
-rw-r--r--arch/sh/boards/cat68701/Makefile6
-rw-r--r--arch/sh/boards/cat68701/irq.c28
-rw-r--r--arch/sh/boards/cat68701/setup.c86
-rw-r--r--arch/sh/boards/cqreek/Makefile6
-rw-r--r--arch/sh/boards/cqreek/irq.c128
-rw-r--r--arch/sh/boards/cqreek/setup.c101
-rw-r--r--arch/sh/boards/dmida/Makefile7
-rw-r--r--arch/sh/boards/dmida/mach.c59
-rw-r--r--arch/sh/boards/dreamcast/Makefile6
-rw-r--r--arch/sh/boards/dreamcast/irq.c160
-rw-r--r--arch/sh/boards/dreamcast/rtc.c81
-rw-r--r--arch/sh/boards/dreamcast/setup.c83
-rw-r--r--arch/sh/boards/ec3104/Makefile6
-rw-r--r--arch/sh/boards/ec3104/io.c81
-rw-r--r--arch/sh/boards/ec3104/irq.c196
-rw-r--r--arch/sh/boards/ec3104/setup.c78
-rw-r--r--arch/sh/boards/harp/Makefile8
-rw-r--r--arch/sh/boards/harp/irq.c148
-rw-r--r--arch/sh/boards/harp/led.c52
-rw-r--r--arch/sh/boards/harp/mach.c62
-rw-r--r--arch/sh/boards/harp/pcidma.c42
-rw-r--r--arch/sh/boards/harp/setup.c91
-rw-r--r--arch/sh/boards/hp6xx/hp620/Makefile6
-rw-r--r--arch/sh/boards/hp6xx/hp620/mach.c52
-rw-r--r--arch/sh/boards/hp6xx/hp620/setup.c45
-rw-r--r--arch/sh/boards/hp6xx/hp680/Makefile6
-rw-r--r--arch/sh/boards/hp6xx/hp680/mach.c53
-rw-r--r--arch/sh/boards/hp6xx/hp680/setup.c41
-rw-r--r--arch/sh/boards/hp6xx/hp690/Makefile6
-rw-r--r--arch/sh/boards/hp6xx/hp690/mach.c48
-rw-r--r--arch/sh/boards/mpc1211/Makefile8
-rw-r--r--arch/sh/boards/mpc1211/led.c64
-rw-r--r--arch/sh/boards/mpc1211/pci.c296
-rw-r--r--arch/sh/boards/mpc1211/rtc.c152
-rw-r--r--arch/sh/boards/mpc1211/setup.c360
-rw-r--r--arch/sh/boards/overdrive/Makefile8
-rw-r--r--arch/sh/boards/overdrive/fpga.c134
-rw-r--r--arch/sh/boards/overdrive/galileo.c588
-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.c62
-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/renesas/edosk7705/Makefile10
-rw-r--r--arch/sh/boards/renesas/edosk7705/io.c94
-rw-r--r--arch/sh/boards/renesas/edosk7705/setup.c60
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/Makefile12
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/io.c310
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/irq.c122
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/led.c27
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/mach.c55
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/pci.c150
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/setup.c89
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/Makefile10
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/io.c319
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/irq.c135
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/led.c67
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/mach.c70
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/setup.c31
-rw-r--r--arch/sh/boards/renesas/systemh/Makefile13
-rw-r--r--arch/sh/boards/renesas/systemh/io.c283
-rw-r--r--arch/sh/boards/renesas/systemh/irq.c111
-rw-r--r--arch/sh/boards/renesas/systemh/setup.c80
-rw-r--r--arch/sh/boards/saturn/Makefile8
-rw-r--r--arch/sh/boards/saturn/io.c26
-rw-r--r--arch/sh/boards/saturn/irq.c118
-rw-r--r--arch/sh/boards/saturn/setup.c43
-rw-r--r--arch/sh/boards/saturn/smp.c68
-rw-r--r--arch/sh/boards/se/7300/Makefile7
-rw-r--r--arch/sh/boards/se/7300/io.c265
-rw-r--r--arch/sh/boards/se/7300/irq.c37
-rw-r--r--arch/sh/boards/se/7300/led.c69
-rw-r--r--arch/sh/boards/se/7300/setup.c66
-rw-r--r--arch/sh/boards/se/73180/Makefile7
-rw-r--r--arch/sh/boards/se/73180/io.c265
-rw-r--r--arch/sh/boards/se/73180/irq.c137
-rw-r--r--arch/sh/boards/se/73180/led.c67
-rw-r--r--arch/sh/boards/se/73180/setup.c68
-rw-r--r--arch/sh/boards/se/770x/Makefile6
-rw-r--r--arch/sh/boards/se/770x/io.c226
-rw-r--r--arch/sh/boards/se/770x/irq.c80
-rw-r--r--arch/sh/boards/se/770x/led.c68
-rw-r--r--arch/sh/boards/se/770x/mach.c68
-rw-r--r--arch/sh/boards/se/770x/setup.c85
-rw-r--r--arch/sh/boards/se/7751/Makefile8
-rw-r--r--arch/sh/boards/se/7751/io.c244
-rw-r--r--arch/sh/boards/se/7751/irq.c67
-rw-r--r--arch/sh/boards/se/7751/led.c68
-rw-r--r--arch/sh/boards/se/7751/mach.c55
-rw-r--r--arch/sh/boards/se/7751/pci.c148
-rw-r--r--arch/sh/boards/se/7751/setup.c228
-rw-r--r--arch/sh/boards/sh03/Makefile6
-rw-r--r--arch/sh/boards/sh03/led.c49
-rw-r--r--arch/sh/boards/sh03/rtc.c144
-rw-r--r--arch/sh/boards/sh03/setup.c72
-rw-r--r--arch/sh/boards/sh2000/Makefile6
-rw-r--r--arch/sh/boards/sh2000/setup.c71
-rw-r--r--arch/sh/boards/snapgear/Makefile6
-rw-r--r--arch/sh/boards/snapgear/io.c226
-rw-r--r--arch/sh/boards/snapgear/rtc.c333
-rw-r--r--arch/sh/boards/snapgear/setup.c216
-rw-r--r--arch/sh/boards/superh/microdev/Makefile8
-rw-r--r--arch/sh/boards/superh/microdev/io.c370
-rw-r--r--arch/sh/boards/superh/microdev/irq.c200
-rw-r--r--arch/sh/boards/superh/microdev/led.c102
-rw-r--r--arch/sh/boards/superh/microdev/setup.c278
-rw-r--r--arch/sh/boards/unknown/Makefile6
-rw-r--r--arch/sh/boards/unknown/io.c46
-rw-r--r--arch/sh/boards/unknown/mach.c67
-rw-r--r--arch/sh/boards/unknown/setup.c23
-rw-r--r--arch/sh/boot/Makefile20
-rw-r--r--arch/sh/boot/compressed/Makefile41
-rw-r--r--arch/sh/boot/compressed/head.S120
-rw-r--r--arch/sh/boot/compressed/install.sh56
-rw-r--r--arch/sh/boot/compressed/misc.c240
-rw-r--r--arch/sh/boot/compressed/vmlinux.scr9
-rw-r--r--arch/sh/cchips/Kconfig96
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/Makefile6
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/io.c157
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/setup.c171
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/Makefile6
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/gpio.c196
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/io.c216
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/setup.c202
-rw-r--r--arch/sh/cchips/voyagergx/Makefile8
-rw-r--r--arch/sh/cchips/voyagergx/consistent.c126
-rw-r--r--arch/sh/cchips/voyagergx/irq.c194
-rw-r--r--arch/sh/cchips/voyagergx/setup.c37
-rw-r--r--arch/sh/configs/adx_defconfig539
-rw-r--r--arch/sh/configs/cqreek_defconfig533
-rw-r--r--arch/sh/configs/dreamcast_defconfig794
-rw-r--r--arch/sh/configs/hp680_defconfig554
-rw-r--r--arch/sh/configs/microdev_defconfig734
-rw-r--r--arch/sh/configs/rts7751r2d_defconfig847
-rw-r--r--arch/sh/configs/se7300_defconfig531
-rw-r--r--arch/sh/configs/se73180_defconfig496
-rw-r--r--arch/sh/configs/se7705_defconfig714
-rw-r--r--arch/sh/configs/se7750_defconfig713
-rw-r--r--arch/sh/configs/se7751_defconfig777
-rw-r--r--arch/sh/configs/sh03_defconfig924
-rw-r--r--arch/sh/configs/snapgear_defconfig699
-rw-r--r--arch/sh/configs/systemh_defconfig509
-rw-r--r--arch/sh/drivers/Makefile7
-rw-r--r--arch/sh/drivers/dma/Kconfig55
-rw-r--r--arch/sh/drivers/dma/Makefile9
-rw-r--r--arch/sh/drivers/dma/dma-api.c292
-rw-r--r--arch/sh/drivers/dma/dma-g2.c171
-rw-r--r--arch/sh/drivers/dma/dma-isa.c106
-rw-r--r--arch/sh/drivers/dma/dma-pvr2.c109
-rw-r--r--arch/sh/drivers/dma/dma-sh.c267
-rw-r--r--arch/sh/drivers/dma/dma-sh.h52
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c133
-rw-r--r--arch/sh/drivers/pci/Kconfig41
-rw-r--r--arch/sh/drivers/pci/Makefile16
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c71
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c81
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c43
-rw-r--r--arch/sh/drivers/pci/fixups-sh03.c61
-rw-r--r--arch/sh/drivers/pci/ops-bigsur.c88
-rw-r--r--arch/sh/drivers/pci/ops-dreamcast.c169
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c79
-rw-r--r--arch/sh/drivers/pci/ops-sh03.c45
-rw-r--r--arch/sh/drivers/pci/ops-snapgear.c102
-rw-r--r--arch/sh/drivers/pci/pci-auto.c555
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c417
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h303
-rw-r--r--arch/sh/drivers/pci/pci-st40.c509
-rw-r--r--arch/sh/drivers/pci/pci-st40.h136
-rw-r--r--arch/sh/drivers/pci/pci.c155
-rw-r--r--arch/sh/kernel/Makefile22
-rw-r--r--arch/sh/kernel/asm-offsets.c32
-rw-r--r--arch/sh/kernel/cf-enabler.c158
-rw-r--r--arch/sh/kernel/cpu/Makefile16
-rw-r--r--arch/sh/kernel/cpu/adc.c36
-rw-r--r--arch/sh/kernel/cpu/bus.c195
-rw-r--r--arch/sh/kernel/cpu/init.c222
-rw-r--r--arch/sh/kernel/cpu/irq_imask.c116
-rw-r--r--arch/sh/kernel/cpu/irq_ipr.c339
-rw-r--r--arch/sh/kernel/cpu/rtc.c136
-rw-r--r--arch/sh/kernel/cpu/sh2/Makefile6
-rw-r--r--arch/sh/kernel/cpu/sh2/probe.c39
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile6
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S199
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c97
-rw-r--r--arch/sh/kernel/cpu/sh4/Makefile10
-rw-r--r--arch/sh/kernel/cpu/sh4/ex.S384
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c335
-rw-r--r--arch/sh/kernel/cpu/sh4/irq_intc2.c222
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c138
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c453
-rw-r--r--arch/sh/kernel/cpu/ubc.S59
-rw-r--r--arch/sh/kernel/cpufreq.c218
-rw-r--r--arch/sh/kernel/early_printk.c137
-rw-r--r--arch/sh/kernel/entry.S1149
-rw-r--r--arch/sh/kernel/head.S76
-rw-r--r--arch/sh/kernel/init_task.c36
-rw-r--r--arch/sh/kernel/io.c59
-rw-r--r--arch/sh/kernel/io_generic.c243
-rw-r--r--arch/sh/kernel/irq.c106
-rw-r--r--arch/sh/kernel/kgdb_jmp.S33
-rw-r--r--arch/sh/kernel/kgdb_stub.c1491
-rw-r--r--arch/sh/kernel/module.c146
-rw-r--r--arch/sh/kernel/process.c531
-rw-r--r--arch/sh/kernel/ptrace.c320
-rw-r--r--arch/sh/kernel/semaphore.c139
-rw-r--r--arch/sh/kernel/setup.c649
-rw-r--r--arch/sh/kernel/sh_bios.c75
-rw-r--r--arch/sh/kernel/sh_ksyms.c126
-rw-r--r--arch/sh/kernel/signal.c607
-rw-r--r--arch/sh/kernel/smp.c199
-rw-r--r--arch/sh/kernel/sys_sh.c289
-rw-r--r--arch/sh/kernel/time.c657
-rw-r--r--arch/sh/kernel/traps.c712
-rw-r--r--arch/sh/kernel/vmlinux.lds.S155
-rw-r--r--arch/sh/lib/Makefile13
-rw-r--r--arch/sh/lib/checksum.S385
-rw-r--r--arch/sh/lib/delay.c41
-rw-r--r--arch/sh/lib/div64-generic.c19
-rw-r--r--arch/sh/lib/div64.S46
-rw-r--r--arch/sh/lib/memchr.S26
-rw-r--r--arch/sh/lib/memcpy-sh4.S800
-rw-r--r--arch/sh/lib/memcpy.S227
-rw-r--r--arch/sh/lib/memmove.S254
-rw-r--r--arch/sh/lib/memset.S57
-rw-r--r--arch/sh/lib/strcasecmp.c26
-rw-r--r--arch/sh/lib/strlen.S70
-rw-r--r--arch/sh/lib/udivdi3.c16
-rw-r--r--arch/sh/mm/Makefile25
-rw-r--r--arch/sh/mm/cache-sh2.c50
-rw-r--r--arch/sh/mm/cache-sh3.c100
-rw-r--r--arch/sh/mm/cache-sh4.c362
-rw-r--r--arch/sh/mm/cache-sh7705.c206
-rw-r--r--arch/sh/mm/clear_page.S295
-rw-r--r--arch/sh/mm/consistent.c85
-rw-r--r--arch/sh/mm/copy_page.S397
-rw-r--r--arch/sh/mm/extable.c22
-rw-r--r--arch/sh/mm/fault-nommu.c82
-rw-r--r--arch/sh/mm/fault.c374
-rw-r--r--arch/sh/mm/hugetlbpage.c264
-rw-r--r--arch/sh/mm/init.c313
-rw-r--r--arch/sh/mm/ioremap.c163
-rw-r--r--arch/sh/mm/pg-dma.c97
-rw-r--r--arch/sh/mm/pg-nommu.c36
-rw-r--r--arch/sh/mm/pg-sh4.c122
-rw-r--r--arch/sh/mm/pg-sh7705.c137
-rw-r--r--arch/sh/mm/tlb-nommu.c58
-rw-r--r--arch/sh/mm/tlb-sh3.c92
-rw-r--r--arch/sh/mm/tlb-sh4.c96
-rw-r--r--arch/sh/oprofile/Kconfig23
-rw-r--r--arch/sh/oprofile/Makefile13
-rw-r--r--arch/sh/oprofile/op_model_null.c23
-rw-r--r--arch/sh/oprofile/op_model_sh7750.c281
-rw-r--r--arch/sh/ramdisk/Makefile20
-rw-r--r--arch/sh/ramdisk/ld.script9
-rw-r--r--arch/sh/tools/Makefile15
-rw-r--r--arch/sh/tools/gen-mach-types49
-rw-r--r--arch/sh/tools/mach-types31
271 files changed, 45413 insertions, 0 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
new file mode 100644
index 000000000000..722ea1d63c94
--- /dev/null
+++ b/arch/sh/Kconfig
@@ -0,0 +1,793 @@
1#
2# For a description of the syntax of this configuration file,
3# see Documentation/kbuild/kconfig-language.txt.
4#
5
6mainmenu "Linux/SuperH Kernel Configuration"
7
8config SUPERH
9 bool
10 default y
11 help
12 The SuperH is a RISC processor targeted for use in embedded systems
13 and consumer electronics; it was also used in the Sega Dreamcast
14 gaming console. The SuperH port has a home page at
15 <http://www.linux-sh.org/>.
16
17config UID16
18 bool
19 default y
20
21config RWSEM_GENERIC_SPINLOCK
22 bool
23 default y
24
25config RWSEM_XCHGADD_ALGORITHM
26 bool
27
28config GENERIC_HARDIRQS
29 bool
30 default y
31
32config GENERIC_IRQ_PROBE
33 bool
34 default y
35
36config GENERIC_CALIBRATE_DELAY
37 bool
38 default y
39
40source "init/Kconfig"
41
42menu "System type"
43
44choice
45 prompt "SuperH system type"
46 default SH_UNKNOWN
47
48config SH_SOLUTION_ENGINE
49 bool "SolutionEngine"
50 help
51 Select SolutionEngine if configuring for a Hitachi SH7709
52 or SH7750 evaluation board.
53
54config SH_7751_SOLUTION_ENGINE
55 bool "SolutionEngine7751"
56 help
57 Select 7751 SolutionEngine if configuring for a Hitachi SH7751
58 evaluation board.
59
60config SH_7300_SOLUTION_ENGINE
61 bool "SolutionEngine7300"
62 help
63 Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V)
64 evaluation board.
65
66config SH_73180_SOLUTION_ENGINE
67 bool "SolutionEngine73180"
68 help
69 Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3)
70 evaluation board.
71
72config SH_7751_SYSTEMH
73 bool "SystemH7751R"
74 help
75 Select SystemH if you are configuring for a Renesas SystemH
76 7751R evaluation board.
77
78config SH_STB1_HARP
79 bool "STB1_Harp"
80
81config SH_STB1_OVERDRIVE
82 bool "STB1_Overdrive"
83
84config SH_HP620
85 bool "HP620"
86 help
87 Select HP620 if configuring for a HP jornada HP620.
88 More information (hardware only) at
89 <http://www.hp.com/jornada/>.
90
91config SH_HP680
92 bool "HP680"
93 help
94 Select HP680 if configuring for a HP Jornada HP680.
95 More information (hardware only) at
96 <http://www.hp.com/jornada/products/680/>.
97
98config SH_HP690
99 bool "HP690"
100 help
101 Select HP690 if configuring for a HP Jornada HP690.
102 More information (hardware only)
103 at <http://www.hp.com/jornada/products/680/>.
104
105config SH_CQREEK
106 bool "CqREEK"
107 help
108 Select CqREEK if configuring for a CqREEK SH7708 or SH7750.
109 More information at
110 <http://sources.redhat.com/ecos/hardware.html#SuperH>.
111
112config SH_DMIDA
113 bool "DMIDA"
114 help
115 Select DMIDA if configuring for a DataMyte 4000 Industrial
116 Digital Assistant. More information at <http://www.dmida.com/>.
117
118config SH_EC3104
119 bool "EC3104"
120 help
121 Select EC3104 if configuring for a system with an Eclipse
122 International EC3104 chip, e.g. the Harris AD2000.
123
124config SH_SATURN
125 bool "Saturn"
126 help
127 Select Saturn if configuring for a SEGA Saturn.
128
129config SH_DREAMCAST
130 bool "Dreamcast"
131 help
132 Select Dreamcast if configuring for a SEGA Dreamcast.
133 More information at
134 <http://www.m17n.org/linux-sh/dreamcast/>. There is a
135 Dreamcast project is at <http://linuxdc.sourceforge.net/>.
136
137config SH_CAT68701
138 bool "CAT68701"
139
140config SH_BIGSUR
141 bool "BigSur"
142
143config SH_SH2000
144 bool "SH2000"
145 help
146 SH-2000 is a single-board computer based around SH7709A chip
147 intended for embedded applications.
148 It has an Ethernet interface (CS8900A), direct connected
149 Compact Flash socket, three serial ports and PC-104 bus.
150 More information at <http://sh2000.sh-linux.org>.
151
152config SH_ADX
153 bool "ADX"
154
155config SH_MPC1211
156 bool "MPC1211"
157
158config SH_SH03
159 bool "SH03"
160 help
161 CTP/PCI-SH03 is a CPU module computer that produced
162 by Interface Corporation.
163 It is compact and excellent in durability.
164 It will play an active part in your factory or laboratory
165 as a FA computer.
166 More information at <http://www.interface.co.jp>
167
168config SH_SECUREEDGE5410
169 bool "SecureEdge5410"
170 help
171 Select SecureEdge5410 if configuring for a SnapGear SH board.
172 This includes both the OEM SecureEdge products as well as the
173 SME product line.
174
175config SH_HS7751RVOIP
176 bool "HS7751RVOIP"
177 help
178 Select HS7751RVOIP if configuring for a Renesas Technology
179 Sales VoIP board.
180
181config SH_RTS7751R2D
182 bool "RTS7751R2D"
183 help
184 Select RTS7751R2D if configuring for a Renesas Technology
185 Sales SH-Graphics board.
186
187config SH_EDOSK7705
188 bool "EDOSK7705"
189
190config SH_SH4202_MICRODEV
191 bool "SH4-202 MicroDev"
192 help
193 Select SH4-202 MicroDev if configuring for a SuperH MicroDev board
194 with an SH4-202 CPU.
195
196config SH_UNKNOWN
197 bool "BareCPU"
198 help
199 "Bare CPU" aka "unknown" means an SH-based system which is not one
200 of the specific ones mentioned above, which means you need to enter
201 all sorts of stuff like CONFIG_MEMORY_START because the config
202 system doesn't already know what it is. You get a machine vector
203 without any platform-specific code in it, so things like the RTC may
204 not work.
205
206 This option is for the early stages of porting to a new machine.
207
208endchoice
209
210choice
211 prompt "Processor family"
212 default CPU_SH4
213 help
214 This option determines the CPU family to compile for. Supported
215 targets are SH-2, SH-3, and SH-4. These options are independent of
216 CPU functionality. As such, SH-DSP users will still want to select
217 their respective processor family in addition to the DSP support
218 option.
219
220config CPU_SH2
221 bool "SH-2"
222 select SH_WRITETHROUGH
223
224config CPU_SH3
225 bool "SH-3"
226
227config CPU_SH4
228 bool "SH-4"
229
230endchoice
231
232choice
233 prompt "Processor subtype"
234
235config CPU_SUBTYPE_SH7604
236 bool "SH7604"
237 depends on CPU_SH2
238 help
239 Select SH7604 if you have SH7604
240
241config CPU_SUBTYPE_SH7300
242 bool "SH7300"
243 depends on CPU_SH3
244
245config CPU_SUBTYPE_SH7705
246 bool "SH7705"
247 depends on CPU_SH3
248
249config CPU_SUBTYPE_SH7707
250 bool "SH7707"
251 depends on CPU_SH3
252 help
253 Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU.
254
255config CPU_SUBTYPE_SH7708
256 bool "SH7708"
257 depends on CPU_SH3
258 help
259 Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or
260 if you have a 100 Mhz SH-3 HD6417708R CPU.
261
262config CPU_SUBTYPE_SH7709
263 bool "SH7709"
264 depends on CPU_SH3
265 help
266 Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU.
267
268config CPU_SUBTYPE_SH7750
269 bool "SH7750"
270 depends on CPU_SH4
271 help
272 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
273
274config CPU_SUBTYPE_SH7751
275 bool "SH7751/SH7751R"
276 depends on CPU_SH4
277 help
278 Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
279 or if you have a HD6417751R CPU.
280
281config CPU_SUBTYPE_SH7760
282 bool "SH7760"
283 depends on CPU_SH4
284
285config CPU_SUBTYPE_SH73180
286 bool "SH73180"
287 depends on CPU_SH4
288
289config CPU_SUBTYPE_ST40STB1
290 bool "ST40STB1 / ST40RA"
291 depends on CPU_SH4
292 help
293 Select ST40STB1 if you have a ST40RA CPU.
294 This was previously called the ST40STB1, hence the option name.
295
296config CPU_SUBTYPE_ST40GX1
297 bool "ST40GX1"
298 depends on CPU_SH4
299 help
300 Select ST40GX1 if you have a ST40GX1 CPU.
301
302config CPU_SUBTYPE_SH4_202
303 bool "SH4-202"
304 depends on CPU_SH4
305
306endchoice
307
308config SH7705_CACHE_32KB
309 bool "Enable 32KB cache size for SH7705"
310 depends on CPU_SUBTYPE_SH7705
311 default y
312
313config MMU
314 bool "Support for memory management hardware"
315 depends on !CPU_SH2
316 default y
317 help
318 Early SH processors (such as the SH7604) lack an MMU. In order to
319 boot on these systems, this option must not be set.
320
321 On other systems (such as the SH-3 and 4) where an MMU exists,
322 turning this off will boot the kernel on these machines with the
323 MMU implicitly switched off.
324
325choice
326 prompt "HugeTLB page size"
327 depends on HUGETLB_PAGE && CPU_SH4 && MMU
328 default HUGETLB_PAGE_SIZE_64K
329
330config HUGETLB_PAGE_SIZE_64K
331 bool "64K"
332
333config HUGETLB_PAGE_SIZE_1MB
334 bool "1MB"
335
336endchoice
337
338config CMDLINE_BOOL
339 bool "Default bootloader kernel arguments"
340
341config CMDLINE
342 string "Initial kernel command string"
343 depends on CMDLINE_BOOL
344 default "console=ttySC1,115200"
345
346# Platform-specific memory start and size definitions
347config MEMORY_START
348 hex "Physical memory start address" if !MEMORY_SET || MEMORY_OVERRIDE
349 default "0x08000000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || SH_MPC1211 || SH_SH03 || SH_SECUREEDGE5410 || SH_SH4202_MICRODEV
350 default "0x0c000000" if !MEMORY_OVERRIDE && (SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_73180_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D || SH_EDOSK7705)
351 ---help---
352 Computers built with Hitachi SuperH processors always
353 map the ROM starting at address zero. But the processor
354 does not specify the range that RAM takes.
355
356 The physical memory (RAM) start address will be automatically
357 set to 08000000, unless you selected one of the following
358 processor types: SolutionEngine, Overdrive, HP620, HP680, HP690,
359 in which case the start address will be set to 0c000000.
360
361 Tweak this only when porting to a new machine which is not already
362 known by the config system. Changing it from the known correct
363 value on any of the known systems will only lead to disaster.
364
365config MEMORY_SIZE
366 hex "Physical memory size" if !MEMORY_SET || MEMORY_OVERRIDE
367 default "0x00400000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || !MEMORY_OVERRIDE && (SH_HP600 || SH_BIGSUR || SH_SH2000)
368 default "0x01000000" if !MEMORY_OVERRIDE && SH_DREAMCAST || SH_SECUREEDGE5410 || SH_EDOSK7705
369 default "0x02000000" if !MEMORY_OVERRIDE && (SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE)
370 default "0x04000000" if !MEMORY_OVERRIDE && (SH_7300_SOLUTION_ENGINE || SH_7751_SOLUTION_ENGINE || SH_HS7751RVOIP || SH_RTS7751R2D || SH_SH4202_MICRODEV)
371 default "0x08000000" if SH_MPC1211 || SH_SH03
372 help
373 This sets the default memory size assumed by your SH kernel. It can
374 be overridden as normal by the 'mem=' argument on the kernel command
375 line. If unsure, consult your board specifications or just leave it
376 as 0x00400000 which was the default value before this became
377 configurable.
378
379config MEMORY_SET
380 bool
381 depends on !MEMORY_OVERRIDE && (SH_MPC1211 || SH_SH03 || SH_ADX || SH_DREAMCAST || SH_HP600 || SH_BIGSUR || SH_SH2000 || SH_7751_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_SECUREEDGE5410 || SH_HS7751RVOIP || SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_EDOSK7705)
382 default y
383 help
384 This is an option about which you will never be asked a question.
385 Therefore, I conclude that you do not exist - go away.
386
387 There is a grue here.
388
389# If none of the above have set memory start/size, ask the user.
390config MEMORY_OVERRIDE
391 bool "Override default load address and memory size"
392
393# XXX: break these out into the board-specific configs below
394config CF_ENABLER
395 bool "Compact Flash Enabler support"
396 depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03
397 ---help---
398 Compact Flash is a small, removable mass storage device introduced
399 in 1994 originally as a PCMCIA device. If you say `Y' here, you
400 compile in support for Compact Flash devices directly connected to
401 a SuperH processor. A Compact Flash FAQ is available at
402 <http://www.compactflash.org/faqs/faq.htm>.
403
404 If your board has "Directly Connected" CompactFlash at area 5 or 6,
405 you may want to enable this option. Then, you can use CF as
406 primary IDE drive (only tested for SanDisk).
407
408 If in doubt, select 'N'.
409
410choice
411 prompt "Compact Flash Connection Area"
412 depends on CF_ENABLER
413 default CF_AREA6
414
415config CF_AREA5
416 bool "Area5"
417 help
418 If your board has "Directly Connected" CompactFlash, You should
419 select the area where your CF is connected to.
420
421 - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
422 - "Area6" if it is connected to Area 6 (0x18000000)
423
424 "Area6" will work for most boards. For ADX, select "Area5".
425
426config CF_AREA6
427 bool "Area6"
428
429endchoice
430
431config CF_BASE_ADDR
432 hex
433 depends on CF_ENABLER
434 default "0xb8000000" if CF_AREA6
435 default "0xb4000000" if CF_AREA5
436
437# The SH7750 RTC module is disabled in the Dreamcast
438config SH_RTC
439 bool
440 depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && !SH_73180_SOLUTION_ENGINE
441 default y
442 help
443 Selecting this option will allow the Linux kernel to emulate
444 PC's RTC.
445
446 If unsure, say N.
447
448config SH_FPU
449 bool "FPU support"
450 depends on !CPU_SH3
451 default y
452 help
453 Selecting this option will enable support for SH processors that
454 have FPU units (ie, SH77xx).
455
456 This option must be set in order to enable the FPU.
457
458config SH_DSP
459 bool "DSP support"
460 depends on !CPU_SH4
461 default y
462 help
463 Selecting this option will enable support for SH processors that
464 have DSP units (ie, SH2-DSP and SH3-DSP). It is safe to say Y here
465 by default, as the existance of the DSP will be probed at runtime.
466
467 This option must be set in order to enable the DSP.
468
469config SH_ADC
470 bool "ADC support"
471 depends on CPU_SH3
472 default y
473 help
474 Selecting this option will allow the Linux kernel to use SH3 on-chip
475 ADC module.
476
477 If unsure, say N.
478
479config SH_HP600
480 bool
481 depends on SH_HP620 || SH_HP680 || SH_HP690
482 default y
483
484config CPU_SUBTYPE_ST40
485 bool
486 depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
487 default y
488
489config DISCONTIGMEM
490 bool
491 depends on SH_HP690
492 default y
493 help
494 Say Y to upport efficient handling of discontiguous physical memory,
495 for architectures which are either NUMA (Non-Uniform Memory Access)
496 or have huge holes in the physical address space for other reasons.
497 See <file:Documentation/vm/numa> for more.
498
499config ZERO_PAGE_OFFSET
500 hex "Zero page offset"
501 default "0x00001000" if !(SH_MPC1211 || SH_SH03)
502 default "0x00004000" if SH_MPC1211 || SH_SH03
503 help
504 This sets the default offset of zero page.
505
506# XXX: needs to lose subtype for system type
507config ST40_LMI_MEMORY
508 bool "Memory on LMI"
509 depends on CPU_SUBTYPE_ST40STB1
510
511config MEMORY_START
512 hex
513 depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
514 default "0x08000000"
515
516config MEMORY_SIZE
517 hex
518 depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
519 default "0x00400000"
520
521config MEMORY_SET
522 bool
523 depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY
524 default y
525
526config BOOT_LINK_OFFSET
527 hex "Link address offset for booting"
528 default "0x00800000"
529 help
530 This option allows you to set the link address offset of the zImage.
531 This can be useful if you are on a board which has a small amount of
532 memory.
533
534config CPU_LITTLE_ENDIAN
535 bool "Little Endian"
536 help
537 Some SuperH machines can be configured for either little or big
538 endian byte order. These modes require different kernels. Say Y if
539 your machine is little endian, N if it's a big endian machine.
540
541config PREEMPT
542 bool "Preemptible Kernel (EXPERIMENTAL)"
543 depends on EXPERIMENTAL
544
545config UBC_WAKEUP
546 bool "Wakeup UBC on startup"
547 help
548 Selecting this option will wakeup the User Break Controller (UBC) on
549 startup. Although the UBC is left in an awake state when the processor
550 comes up, some boot loaders misbehave by putting the UBC to sleep in a
551 power saving state, which causes issues with things like ptrace().
552
553 If unsure, say N.
554
555config SH_WRITETHROUGH
556 bool "Use write-through caching"
557 default y if CPU_SH2
558 help
559 Selecting this option will configure the caches in write-through
560 mode, as opposed to the default write-back configuration.
561
562 Since there's sill some aliasing issues on SH-4, this option will
563 unfortunately still require the majority of flushing functions to
564 be implemented to deal with aliasing.
565
566 If unsure, say N.
567
568config SH_OCRAM
569 bool "Operand Cache RAM (OCRAM) support"
570 help
571 Selecting this option will automatically tear down the number of
572 sets in the dcache by half, which in turn exposes a memory range.
573
574 The addresses for the OC RAM base will vary according to the
575 processor version. Consult vendor documentation for specifics.
576
577 If unsure, say N.
578
579config SH_STORE_QUEUES
580 bool "Support for Store Queues"
581 depends on CPU_SH4
582 help
583 Selecting this option will enable an in-kernel API for manipulating
584 the store queues integrated in the SH-4 processors.
585
586config SMP
587 bool "Symmetric multi-processing support"
588 ---help---
589 This enables support for systems with more than one CPU. If you have
590 a system with only one CPU, like most personal computers, say N. If
591 you have a system with more than one CPU, say Y.
592
593 If you say N here, the kernel will run on single and multiprocessor
594 machines, but will use only one CPU of a multiprocessor machine. If
595 you say Y here, the kernel will run on many, but not all,
596 singleprocessor machines. On a singleprocessor machine, the kernel
597 will run faster if you say N here.
598
599 People using multiprocessor machines who say Y here should also say
600 Y to "Enhanced Real Time Clock Support", below.
601
602 See also the <file:Documentation/smp.txt>,
603 <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available
604 at <http://www.tldp.org/docs.html#howto>.
605
606 If you don't know what to do here, say N.
607
608config NR_CPUS
609 int "Maximum number of CPUs (2-32)"
610 range 2 32
611 depends on SMP
612 default "2"
613 help
614 This allows you to specify the maximum number of CPUs which this
615 kernel will support. The maximum supported value is 32 and the
616 minimum value which makes sense is 2.
617
618 This is purely to save memory - each supported CPU adds
619 approximately eight kilobytes to the kernel image.
620
621config HS7751RVOIP_CODEC
622 bool "Support VoIP Codec section"
623 depends on SH_HS7751RVOIP
624 help
625 Selecting this option will support CODEC section.
626
627config RTS7751R2D_REV11
628 bool "RTS7751R2D Rev. 1.1 board support"
629 depends on SH_RTS7751R2D
630 help
631 Selecting this option will support version rev. 1.1.
632
633config SH_PCLK_CALC
634 bool
635 default n if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH73180
636 default y
637 help
638 This option will cause the PCLK value to be probed at run-time. It
639 will display a notification if the probed value has greater than a
640 1% variance of the hardcoded CONFIG_SH_PCLK_FREQ.
641
642config SH_PCLK_FREQ
643 int "Peripheral clock frequency (in Hz)"
644 default "50000000" if CPU_SUBTYPE_SH7750
645 default "60000000" if CPU_SUBTYPE_SH7751
646 default "33333333" if CPU_SUBTYPE_SH7300
647 default "27000000" if CPU_SUBTYPE_SH73180
648 default "66000000" if CPU_SUBTYPE_SH4_202
649 default "1193182"
650 help
651 This option is used to specify the peripheral clock frequency. This
652 option must be set for each processor in order for the kernel to
653 function reliably. If no sane default exists, we use a default from
654 the legacy i8254. Any discrepancies will be reported on boot time
655 with an auto-probed frequency which should be considered the proper
656 value for your hardware.
657
658menu "CPU Frequency scaling"
659
660source "drivers/cpufreq/Kconfig"
661
662config SH_CPU_FREQ
663 tristate "SuperH CPU Frequency driver"
664 depends on CPU_FREQ
665 select CPU_FREQ_TABLE
666 help
667 This adds the cpufreq driver for SuperH. At present, only
668 the SH-4 is supported.
669
670 For details, take a look at <file:Documentation/cpu-freq>.
671
672 If unsure, say N.
673
674endmenu
675
676source "arch/sh/drivers/dma/Kconfig"
677
678source "arch/sh/cchips/Kconfig"
679
680config HEARTBEAT
681 bool "Heartbeat LED"
682 depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || SH_RTS7751R2D || SH_SH4202_MICRODEV
683 help
684 Use the power-on LED on your machine as a load meter. The exact
685 behavior is platform-dependent, but normally the flash frequency is
686 a hyperbolic function of the 5-minute load average.
687
688config RTC_9701JE
689 tristate "EPSON RTC-9701JE support"
690 depends on SH_RTS7751R2D
691 help
692 Selecting this option will support EPSON RTC-9701JE.
693
694endmenu
695
696
697menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
698
699# Even on SuperH devices which don't have an ISA bus,
700# this variable helps the PCMCIA modules handle
701# IRQ requesting properly -- Greg Banks.
702#
703# Though we're generally not interested in it when
704# we're not using PCMCIA, so we make it dependent on
705# PCMCIA outright. -- PFM.
706config ISA
707 bool
708 default y if PCMCIA || SMC91X
709 help
710 Find out whether you have ISA slots on your motherboard. ISA is the
711 name of a bus system, i.e. the way the CPU talks to the other stuff
712 inside your box. Other bus systems are PCI, EISA, MicroChannel
713 (MCA) or VESA. ISA is an older system, now being displaced by PCI;
714 newer boards don't support it. If you have ISA, say Y, otherwise N.
715
716config EISA
717 bool
718 ---help---
719 The Extended Industry Standard Architecture (EISA) bus was
720 developed as an open alternative to the IBM MicroChannel bus.
721
722 The EISA bus provided some of the features of the IBM MicroChannel
723 bus while maintaining backward compatibility with cards made for
724 the older ISA bus. The EISA bus saw limited use between 1988 and
725 1995 when it was made obsolete by the PCI bus.
726
727 Say Y here if you are building a kernel for an EISA-based machine.
728
729 Otherwise, say N.
730
731config MCA
732 bool
733 help
734 MicroChannel Architecture is found in some IBM PS/2 machines and
735 laptops. It is a bus system similar to PCI or ISA. See
736 <file:Documentation/mca.txt> (and especially the web page given
737 there) before attempting to build an MCA bus kernel.
738
739config SBUS
740 bool
741
742config MAPLE
743 tristate "Maple Bus support"
744 depends on SH_DREAMCAST
745 default y
746
747source "arch/sh/drivers/pci/Kconfig"
748
749source "drivers/pci/Kconfig"
750
751source "drivers/pcmcia/Kconfig"
752
753source "drivers/pci/hotplug/Kconfig"
754
755endmenu
756
757menu "Executable file formats"
758
759source "fs/Kconfig.binfmt"
760
761endmenu
762
763menu "SH initrd options"
764 depends on BLK_DEV_INITRD
765
766config EMBEDDED_RAMDISK
767 bool "Embed root filesystem ramdisk into the kernel"
768
769config EMBEDDED_RAMDISK_IMAGE
770 string "Filename of gziped ramdisk image"
771 depends on EMBEDDED_RAMDISK
772 default "ramdisk.gz"
773 help
774 This is the filename of the ramdisk image to be built into the
775 kernel. Relative pathnames are relative to arch/sh/ramdisk/.
776 The ramdisk image is not part of the kernel distribution; you must
777 provide one yourself.
778
779endmenu
780
781source "drivers/Kconfig"
782
783source "fs/Kconfig"
784
785source "arch/sh/oprofile/Kconfig"
786
787source "arch/sh/Kconfig.debug"
788
789source "security/Kconfig"
790
791source "crypto/Kconfig"
792
793source "lib/Kconfig"
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
new file mode 100644
index 000000000000..3fab181da364
--- /dev/null
+++ b/arch/sh/Kconfig.debug
@@ -0,0 +1,124 @@
1menu "Kernel hacking"
2
3source "lib/Kconfig.debug"
4
5config SH_STANDARD_BIOS
6 bool "Use LinuxSH standard BIOS"
7 help
8 Say Y here if your target has the gdb-sh-stub
9 package from www.m17n.org (or any conforming standard LinuxSH BIOS)
10 in FLASH or EPROM. The kernel will use standard BIOS calls during
11 boot for various housekeeping tasks (including calls to read and
12 write characters to a system console, get a MAC address from an
13 on-board Ethernet interface, and shut down the hardware). Note this
14 does not work with machines with an existing operating system in
15 mask ROM and no flash (WindowsCE machines fall in this category).
16 If unsure, say N.
17
18config EARLY_SCIF_CONSOLE
19 bool "Use early SCIF console"
20 depends on CPU_SH4
21
22config EARLY_PRINTK
23 bool "Early printk support"
24 depends on SH_STANDARD_BIOS || EARLY_SCIF_CONSOLE
25 help
26 Say Y here to redirect kernel printk messages to the serial port
27 used by the SH-IPL bootloader, starting very early in the boot
28 process and ending when the kernel's serial console is initialised.
29 This option is only useful porting the kernel to a new machine,
30 when the kernel may crash or hang before the serial console is
31 initialised. If unsure, say N.
32
33config KGDB
34 bool "Include KGDB kernel debugger"
35 help
36 Include in-kernel hooks for kgdb, the Linux kernel source level
37 debugger. See <http://kgdb.sourceforge.net/> for more information.
38 Unless you are intending to debug the kernel, say N here.
39
40menu "KGDB configuration options"
41 depends on KGDB
42
43config MORE_COMPILE_OPTIONS
44 bool "Add any additional compile options"
45 help
46 If you want to add additional CFLAGS to the kernel build, enable this
47 option and then enter what you would like to add in the next question.
48 Note however that -g is already appended with the selection of KGDB.
49
50config COMPILE_OPTIONS
51 string "Additional compile arguments"
52 depends on MORE_COMPILE_OPTIONS
53
54config KGDB_NMI
55 bool "Enter KGDB on NMI"
56 default n
57
58config KGDB_THREAD
59 bool "Include KGDB thread support"
60 default y
61
62config SH_KGDB_CONSOLE
63 bool "Console messages through GDB"
64 default n
65
66config KGDB_SYSRQ
67 bool "Allow SysRq 'G' to enter KGDB"
68 default y
69
70config KGDB_KERNEL_ASSERTS
71 bool "Include KGDB kernel assertions"
72 default n
73
74comment "Serial port setup"
75
76config KGDB_DEFPORT
77 int "Port number (ttySCn)"
78 default "1"
79
80config KGDB_DEFBAUD
81 int "Baud rate"
82 default "115200"
83
84choice
85 prompt "Parity"
86 depends on KGDB
87 default KGDB_DEFPARITY_N
88
89config KGDB_DEFPARITY_N
90 bool "None"
91
92config KGDB_DEFPARITY_E
93 bool "Even"
94
95config KGDB_DEFPARITY_O
96 bool "Odd"
97
98endchoice
99
100choice
101 prompt "Data bits"
102 depends on KGDB
103 default KGDB_DEFBITS_8
104
105config KGDB_DEFBITS_8
106 bool "8"
107
108config KGDB_DEFBITS_7
109 bool "7"
110
111endchoice
112
113endmenu
114
115config FRAME_POINTER
116 bool "Compile the kernel with frame pointers"
117 default y if KGDB
118 help
119 If you say Y here the resulting kernel image will be slightly larger
120 and slower, but it will give very useful debugging information.
121 If you don't debug the kernel, you can say N, but we may not be able
122 to solve problems without frame pointers.
123
124endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
new file mode 100644
index 000000000000..b5635635b5ee
--- /dev/null
+++ b/arch/sh/Makefile
@@ -0,0 +1,183 @@
1# $Id: Makefile,v 1.35 2004/04/15 03:39:20 sugioka Exp $
2#
3# This file is subject to the terms and conditions of the GNU General Public
4# License. See the file "COPYING" in the main directory of this archive
5# for more details.
6#
7# Copyright (C) 1999 Kaz Kojima
8# Copyright (C) 2002, 2003, 2004 Paul Mundt
9# Copyright (C) 2002 M. R. Brown
10#
11# This file is included by the global makefile so that you can add your own
12# architecture-specific flags and dependencies. Remember to do have actions
13# for "archclean" and "archdep" for cleaning up and making dependencies for
14# this architecture
15#
16
17cflags-y := -mb
18cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml
19
20cflags-$(CONFIG_CPU_SH2) += -m2
21cflags-$(CONFIG_CPU_SH3) += -m3
22cflags-$(CONFIG_CPU_SH4) += -m4 \
23 $(call cc-option,-mno-implicit-fp,-m4-nofpu)
24
25cflags-$(CONFIG_SH_DSP) += -Wa,-dsp
26cflags-$(CONFIG_SH_KGDB) += -g
27
28cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
29 $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
30
31OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S
32
33#
34# arch/sh/defconfig doesn't reflect any real hardware, and as such should
35# never be used by anyone. Use a board-specific defconfig that has a
36# reasonable chance of being current instead.
37#
38KBUILD_DEFCONFIG := rts7751r2d_defconfig
39
40#
41# Choosing incompatible machines durings configuration will result in
42# error messages during linking.
43#
44LDFLAGS_vmlinux += -e _stext
45
46ifdef CONFIG_CPU_LITTLE_ENDIAN
47LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64'
48LDFLAGS += -EL
49else
50LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4'
51LDFLAGS += -EB
52endif
53
54CFLAGS += -pipe $(cflags-y)
55AFLAGS += $(cflags-y)
56
57head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
58
59LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
60
61core-y += arch/sh/kernel/ arch/sh/mm/
62
63#
64# ramdisk/initrd support
65# You need a compressed ramdisk image, named
66# CONFIG_EMBEDDED_RAMDISK_IMAGE. Relative pathnames
67# are relative to arch/sh/ramdisk/.
68#
69core-$(CONFIG_EMBEDDED_RAMDISK) += arch/sh/ramdisk/
70
71# Boards
72machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
73machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
74machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300
75machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180
76machdir-$(CONFIG_SH_STB1_HARP) := harp
77machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive
78machdir-$(CONFIG_SH_HP620) := hp6xx/hp620
79machdir-$(CONFIG_SH_HP680) := hp6xx/hp680
80machdir-$(CONFIG_SH_HP690) := hp6xx/hp690
81machdir-$(CONFIG_SH_CQREEK) := cqreek
82machdir-$(CONFIG_SH_DMIDA) := dmida
83machdir-$(CONFIG_SH_EC3104) := ec3104
84machdir-$(CONFIG_SH_SATURN) := saturn
85machdir-$(CONFIG_SH_DREAMCAST) := dreamcast
86machdir-$(CONFIG_SH_CAT68701) := cat68701
87machdir-$(CONFIG_SH_BIGSUR) := bigsur
88machdir-$(CONFIG_SH_SH2000) := sh2000
89machdir-$(CONFIG_SH_ADX) := adx
90machdir-$(CONFIG_SH_MPC1211) := mpc1211
91machdir-$(CONFIG_SH_SH03) := sh03
92machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear
93machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip
94machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d
95machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh
96machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705
97machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev
98machdir-$(CONFIG_SH_UNKNOWN) := unknown
99
100incdir-y := $(notdir $(machdir-y))
101
102incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se
103incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751
104incdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se7300
105incdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se73180
106incdir-$(CONFIG_SH_HP600) := hp6xx
107
108ifneq ($(machdir-y),)
109core-y += arch/sh/boards/$(machdir-y)/
110endif
111
112# Companion chips
113core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/
114core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/
115core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/
116
117cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2
118cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3
119cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4
120
121libs-y := arch/sh/lib/ $(libs-y) $(LIBGCC)
122
123drivers-y += arch/sh/drivers/
124drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/
125
126boot := arch/sh/boot
127
128CPPFLAGS_vmlinux.lds := -traditional
129
130# Update machine arch and proc symlinks if something which affects
131# them changed. We use .arch and .mach to indicate when they were
132# updated last, otherwise make uses the target directory mtime.
133
134include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER
135 @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)'
136ifneq ($(KBUILD_SRC),)
137 $(Q)mkdir -p include/asm-sh
138 $(Q)ln -fsn $(srctree)/include/asm-sh/$(cpuincdir-y) include/asm-sh/cpu
139else
140 $(Q)ln -fsn $(cpuincdir-y) include/asm-sh/cpu
141endif
142 @touch $@
143
144include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER
145 @echo ' SYMLINK include/asm-sh/mach -> include/asm-sh/$(incdir-y)'
146ifneq ($(KBUILD_SRC),)
147 $(Q)mkdir -p include/asm-sh
148 $(Q)ln -fsn $(srctree)/include/asm-sh/$(incdir-y) include/asm-sh/mach
149else
150 $(Q)ln -fsn $(incdir-y) include/asm-sh/mach
151endif
152 @touch $@
153
154
155prepare: maketools include/asm-sh/.cpu include/asm-sh/.mach
156
157.PHONY: maketools FORCE
158maketools: include/asm-sh/asm-offsets.h include/linux/version.h FORCE
159 $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
160
161all: zImage
162
163zImage: vmlinux
164 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
165
166compressed: zImage
167
168archclean:
169 $(Q)$(MAKE) $(clean)=$(boot)
170
171CLEAN_FILES += include/asm-sh/machtypes.h include/asm-sh/asm-offsets.h
172
173arch/sh/kernel/asm-offsets.s: include/asm include/linux/version.h \
174 include/asm-sh/.cpu include/asm-sh/.mach
175
176include/asm-sh/asm-offsets.h: arch/sh/kernel/asm-offsets.s
177 $(call filechk,gen-asm-offsets)
178
179
180define archhelp
181 @echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)'
182endef
183
diff --git a/arch/sh/boards/adx/Makefile b/arch/sh/boards/adx/Makefile
new file mode 100644
index 000000000000..5b1c531b3991
--- /dev/null
+++ b/arch/sh/boards/adx/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for ADX boards
3#
4
5obj-y := setup.o irq.o irq_maskreq.o
6
diff --git a/arch/sh/boards/adx/irq.c b/arch/sh/boards/adx/irq.c
new file mode 100644
index 000000000000..c6ca409dff98
--- /dev/null
+++ b/arch/sh/boards/adx/irq.c
@@ -0,0 +1,31 @@
1/*
2 * linux/arch/sh/boards/adx/irq.c
3 *
4 * Copyright (C) 2001 A&D Co., Ltd.
5 *
6 * I/O routine and setup routines for A&D ADX Board
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 *
12 */
13
14#include <asm/irq.h>
15
16void init_adx_IRQ(void)
17{
18 int i;
19
20/* printk("init_adx_IRQ()\n");*/
21 /* setup irq_mask_register */
22 irq_mask_register = (unsigned short *)0xa6000008;
23
24 /* cover all external interrupt area by maskreg_irq_type
25 * (Actually, irq15 doesn't exist)
26 */
27 for (i = 0; i < 16; i++) {
28 make_maskreg_irq(i);
29 disable_irq(i);
30 }
31}
diff --git a/arch/sh/boards/adx/irq_maskreg.c b/arch/sh/boards/adx/irq_maskreg.c
new file mode 100644
index 000000000000..ca91bb0f1f5c
--- /dev/null
+++ b/arch/sh/boards/adx/irq_maskreg.c
@@ -0,0 +1,107 @@
1/*
2 * linux/arch/sh/kernel/irq_maskreg.c
3 *
4 * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp>
5 *
6 * This file may be copied or modified under the terms of the GNU
7 * General Public License. See linux/COPYING for more information.
8 *
9 * Interrupt handling for Simple external interrupt mask register
10 *
11 * This is for the machine which have single 16 bit register
12 * for masking external IRQ individually.
13 * Each bit of the register is for masking each interrupt.
14 */
15
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/irq.h>
20
21#include <asm/system.h>
22#include <asm/io.h>
23#include <asm/machvec.h>
24
25/* address of external interrupt mask register
26 * address must be set prior to use these (maybe in init_XXX_irq())
27 * XXX : is it better to use .config than specifying it in code? */
28unsigned short *irq_mask_register = 0;
29
30/* forward declaration */
31static unsigned int startup_maskreg_irq(unsigned int irq);
32static void shutdown_maskreg_irq(unsigned int irq);
33static void enable_maskreg_irq(unsigned int irq);
34static void disable_maskreg_irq(unsigned int irq);
35static void mask_and_ack_maskreg(unsigned int);
36static void end_maskreg_irq(unsigned int irq);
37
38/* hw_interrupt_type */
39static struct hw_interrupt_type maskreg_irq_type = {
40 " Mask Register",
41 startup_maskreg_irq,
42 shutdown_maskreg_irq,
43 enable_maskreg_irq,
44 disable_maskreg_irq,
45 mask_and_ack_maskreg,
46 end_maskreg_irq
47};
48
49/* actual implementatin */
50static unsigned int startup_maskreg_irq(unsigned int irq)
51{
52 enable_maskreg_irq(irq);
53 return 0; /* never anything pending */
54}
55
56static void shutdown_maskreg_irq(unsigned int irq)
57{
58 disable_maskreg_irq(irq);
59}
60
61static void disable_maskreg_irq(unsigned int irq)
62{
63 if (irq_mask_register) {
64 unsigned long flags;
65 unsigned short val, mask = 0x01 << irq;
66
67 /* Set "irq"th bit */
68 local_irq_save(flags);
69 val = ctrl_inw((unsigned long)irq_mask_register);
70 val |= mask;
71 ctrl_outw(val, (unsigned long)irq_mask_register);
72 local_irq_restore(flags);
73 }
74}
75
76static void enable_maskreg_irq(unsigned int irq)
77{
78 if (irq_mask_register) {
79 unsigned long flags;
80 unsigned short val, mask = ~(0x01 << irq);
81
82 /* Clear "irq"th bit */
83 local_irq_save(flags);
84 val = ctrl_inw((unsigned long)irq_mask_register);
85 val &= mask;
86 ctrl_outw(val, (unsigned long)irq_mask_register);
87 local_irq_restore(flags);
88 }
89}
90
91static void mask_and_ack_maskreg(unsigned int irq)
92{
93 disable_maskreg_irq(irq);
94}
95
96static void end_maskreg_irq(unsigned int irq)
97{
98 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
99 enable_maskreg_irq(irq);
100}
101
102void make_maskreg_irq(unsigned int irq)
103{
104 disable_irq_nosync(irq);
105 irq_desc[irq].handler = &maskreg_irq_type;
106 disable_maskreg_irq(irq);
107}
diff --git a/arch/sh/boards/adx/setup.c b/arch/sh/boards/adx/setup.c
new file mode 100644
index 000000000000..4938d9592343
--- /dev/null
+++ b/arch/sh/boards/adx/setup.c
@@ -0,0 +1,56 @@
1/*
2 * linux/arch/sh/board/adx/setup.c
3 *
4 * Copyright (C) 2001 A&D Co., Ltd.
5 *
6 * I/O routine and setup routines for A&D ADX Board
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 *
12 */
13
14#include <asm/machvec.h>
15#include <linux/module.h>
16
17extern void init_adx_IRQ(void);
18extern void *cf_io_base;
19
20const char *get_system_type(void)
21{
22 return "A&D ADX";
23}
24
25unsigned long adx_isa_port2addr(unsigned long offset)
26{
27 /* CompactFlash (IDE) */
28 if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset == 0x3f6)) {
29 return (unsigned long)cf_io_base + offset;
30 }
31
32 /* eth0 */
33 if ((offset >= 0x300) && (offset <= 0x30f)) {
34 return 0xa5000000 + offset; /* COMM BOARD (AREA1) */
35 }
36
37 return offset + 0xb0000000; /* IOBUS (AREA 4)*/
38}
39
40/*
41 * The Machine Vector
42 */
43
44struct sh_machine_vector mv_adx __initmv = {
45 .mv_nr_irqs = 48,
46 .mv_isa_port2addr = adx_isa_port2addr,
47 .mv_init_irq = init_adx_IRQ,
48};
49ALIAS_MV(adx)
50
51int __init platform_setup(void)
52{
53 /* Nothing to see here .. */
54 return 0;
55}
56
diff --git a/arch/sh/boards/bigsur/Makefile b/arch/sh/boards/bigsur/Makefile
new file mode 100644
index 000000000000..0ff9497ac58e
--- /dev/null
+++ b/arch/sh/boards/bigsur/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the BigSur specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o led.o
6
diff --git a/arch/sh/boards/bigsur/io.c b/arch/sh/boards/bigsur/io.c
new file mode 100644
index 000000000000..697144de7419
--- /dev/null
+++ b/arch/sh/boards/bigsur/io.c
@@ -0,0 +1,125 @@
1/*
2 * include/asm-sh/io_bigsur.c
3 *
4 * By Dustin McIntire (dustin@sensoria.com) (c)2001
5 * Derived from io_hd64465.h, which bore the message:
6 * By Greg Banks <gbanks@pocketpenguins.com>
7 * (c) 2000 PocketPenguins Inc.
8 * and from io_hd64461.h, which bore the message:
9 * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
10 *
11 * May be copied or modified under the terms of the GNU General Public
12 * License. See linux/COPYING for more information.
13 *
14 * IO functions for a Hitachi Big Sur Evaluation Board.
15 */
16
17#include <linux/config.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <asm/machvec.h>
21#include <asm/io.h>
22#include <asm/bigsur/bigsur.h>
23
24/* Low iomap maps port 0-1K to addresses in 8byte chunks */
25#define BIGSUR_IOMAP_LO_THRESH 0x400
26#define BIGSUR_IOMAP_LO_SHIFT 3
27#define BIGSUR_IOMAP_LO_MASK ((1<<BIGSUR_IOMAP_LO_SHIFT)-1)
28#define BIGSUR_IOMAP_LO_NMAP (BIGSUR_IOMAP_LO_THRESH>>BIGSUR_IOMAP_LO_SHIFT)
29static u32 bigsur_iomap_lo[BIGSUR_IOMAP_LO_NMAP];
30static u8 bigsur_iomap_lo_shift[BIGSUR_IOMAP_LO_NMAP];
31
32/* High iomap maps port 1K-64K to addresses in 1K chunks */
33#define BIGSUR_IOMAP_HI_THRESH 0x10000
34#define BIGSUR_IOMAP_HI_SHIFT 10
35#define BIGSUR_IOMAP_HI_MASK ((1<<BIGSUR_IOMAP_HI_SHIFT)-1)
36#define BIGSUR_IOMAP_HI_NMAP (BIGSUR_IOMAP_HI_THRESH>>BIGSUR_IOMAP_HI_SHIFT)
37static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP];
38static u8 bigsur_iomap_hi_shift[BIGSUR_IOMAP_HI_NMAP];
39
40#ifndef MAX
41#define MAX(a,b) ((a)>(b)?(a):(b))
42#endif
43
44void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
45{
46 u32 port, endport = baseport + nports;
47
48 pr_debug("bigsur_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)\n",
49 baseport, nports, addr);
50
51 for (port = baseport ;
52 port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
53 port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
54 pr_debug(" maplo[0x%x] = 0x%08x\n", port, addr);
55 bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = addr;
56 bigsur_iomap_lo_shift[port>>BIGSUR_IOMAP_LO_SHIFT] = shift;
57 addr += (1<<(BIGSUR_IOMAP_LO_SHIFT));
58 }
59
60 for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
61 port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
62 port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
63 pr_debug(" maphi[0x%x] = 0x%08x\n", port, addr);
64 bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = addr;
65 bigsur_iomap_hi_shift[port>>BIGSUR_IOMAP_HI_SHIFT] = shift;
66 addr += (1<<(BIGSUR_IOMAP_HI_SHIFT));
67 }
68}
69EXPORT_SYMBOL(bigsur_port_map);
70
71void bigsur_port_unmap(u32 baseport, u32 nports)
72{
73 u32 port, endport = baseport + nports;
74
75 pr_debug("bigsur_port_unmap(base=0x%0x, n=0x%0x)\n", baseport, nports);
76
77 for (port = baseport ;
78 port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
79 port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
80 bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = 0;
81 }
82
83 for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
84 port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
85 port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
86 bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = 0;
87 }
88}
89EXPORT_SYMBOL(bigsur_port_unmap);
90
91unsigned long bigsur_isa_port2addr(unsigned long port)
92{
93 unsigned long addr = 0;
94 unsigned char shift;
95
96 /* Physical address not in P0, do nothing */
97 if (PXSEG(port)) {
98 addr = port;
99 /* physical address in P0, map to P2 */
100 } else if (port >= 0x30000) {
101 addr = P2SEGADDR(port);
102 /* Big Sur I/O + HD64465 registers 0x10000-0x30000 */
103 } else if (port >= BIGSUR_IOMAP_HI_THRESH) {
104 addr = BIGSUR_INTERNAL_BASE + (port - BIGSUR_IOMAP_HI_THRESH);
105 /* Handle remapping of high IO/PCI IO ports */
106 } else if (port >= BIGSUR_IOMAP_LO_THRESH) {
107 addr = bigsur_iomap_hi[port >> BIGSUR_IOMAP_HI_SHIFT];
108 shift = bigsur_iomap_hi_shift[port >> BIGSUR_IOMAP_HI_SHIFT];
109
110 if (addr != 0)
111 addr += (port & BIGSUR_IOMAP_HI_MASK) << shift;
112 } else {
113 /* Handle remapping of low IO ports */
114 addr = bigsur_iomap_lo[port >> BIGSUR_IOMAP_LO_SHIFT];
115 shift = bigsur_iomap_lo_shift[port >> BIGSUR_IOMAP_LO_SHIFT];
116
117 if (addr != 0)
118 addr += (port & BIGSUR_IOMAP_LO_MASK) << shift;
119 }
120
121 pr_debug("%s(0x%08lx) = 0x%08lx\n", __FUNCTION__, port, addr);
122
123 return addr;
124}
125
diff --git a/arch/sh/boards/bigsur/irq.c b/arch/sh/boards/bigsur/irq.c
new file mode 100644
index 000000000000..c188fc32dc9a
--- /dev/null
+++ b/arch/sh/boards/bigsur/irq.c
@@ -0,0 +1,348 @@
1/*
2 *
3 * By Dustin McIntire (dustin@sensoria.com) (c)2001
4 *
5 * Setup and IRQ handling code for the HD64465 companion chip.
6 * by Greg Banks <gbanks@pocketpenguins.com>
7 * Copyright (c) 2000 PocketPenguins Inc
8 *
9 * Derived from setup_hd64465.c which bore the message:
10 * Greg Banks <gbanks@pocketpenguins.com>
11 * Copyright (c) 2000 PocketPenguins Inc and
12 * Copyright (C) 2000 YAEGASHI Takeshi
13 * and setup_cqreek.c which bore message:
14 * Copyright (C) 2000 Niibe Yutaka
15 *
16 * May be copied or modified under the terms of the GNU General Public
17 * License. See linux/COPYING for more information.
18 *
19 * IRQ functions for a Hitachi Big Sur Evaluation Board.
20 *
21 */
22
23#include <linux/config.h>
24#include <linux/sched.h>
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/param.h>
28#include <linux/ioport.h>
29#include <linux/interrupt.h>
30#include <linux/init.h>
31#include <linux/irq.h>
32#include <linux/bitops.h>
33
34#include <asm/io.h>
35#include <asm/irq.h>
36
37#include <asm/bigsur/io.h>
38#include <asm/hd64465/hd64465.h>
39#include <asm/bigsur/bigsur.h>
40
41//#define BIGSUR_DEBUG 3
42#undef BIGSUR_DEBUG
43
44#ifdef BIGSUR_DEBUG
45#define DPRINTK(args...) printk(args)
46#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
47#else
48#define DPRINTK(args...)
49#define DIPRINTK(n, args...)
50#endif /* BIGSUR_DEBUG */
51
52#ifdef CONFIG_HD64465
53extern int hd64465_irq_demux(int irq);
54#endif /* CONFIG_HD64465 */
55
56
57/*===========================================================*/
58// Big Sur CPLD IRQ Routines
59/*===========================================================*/
60
61/* Level 1 IRQ routines */
62static void disable_bigsur_l1irq(unsigned int irq)
63{
64 unsigned long flags;
65 unsigned char mask;
66 unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
67 unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
68
69 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
70 DPRINTK("Disable L1 IRQ %d\n", irq);
71 DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
72 mask_port, bit);
73 local_irq_save(flags);
74
75 /* Disable IRQ - set mask bit */
76 mask = inb(mask_port) | bit;
77 outb(mask, mask_port);
78 local_irq_restore(flags);
79 return;
80 }
81 DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
82}
83
84static void enable_bigsur_l1irq(unsigned int irq)
85{
86 unsigned long flags;
87 unsigned char mask;
88 unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
89 unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
90
91 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
92 DPRINTK("Enable L1 IRQ %d\n", irq);
93 DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
94 mask_port, bit);
95 local_irq_save(flags);
96 /* Enable L1 IRQ - clear mask bit */
97 mask = inb(mask_port) & ~bit;
98 outb(mask, mask_port);
99 local_irq_restore(flags);
100 return;
101 }
102 DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
103}
104
105
106/* Level 2 irq masks and registers for L2 decoding */
107/* Level2 bitmasks for each level 1 IRQ */
108const u32 bigsur_l2irq_mask[] =
109 {0x40,0x80,0x08,0x01,0x01,0x3C,0x3E,0xFF,0x40,0x80,0x06,0x03};
110/* Level2 to ISR[n] map for each level 1 IRQ */
111const u32 bigsur_l2irq_reg[] =
112 { 2, 2, 3, 3, 1, 2, 1, 0, 1, 1, 3, 2};
113/* Level2 to Level 1 IRQ map */
114const u32 bigsur_l2_l1_map[] =
115 {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};
116/* IRQ inactive level (high or low) */
117const u32 bigsur_l2_inactv_state[] = {0x00, 0xBE, 0xFC, 0xF7};
118
119/* CPLD external status and mask registers base and offsets */
120static const u32 isr_base = BIGSUR_IRQ0;
121static const u32 isr_offset = BIGSUR_IRQ0 - BIGSUR_IRQ1;
122static const u32 imr_base = BIGSUR_IMR0;
123static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;
124
125#define REG_NUM(irq) ((irq-BIGSUR_2NDLVL_IRQ_LOW)/8 )
126
127/* Level 2 IRQ routines */
128static void disable_bigsur_l2irq(unsigned int irq)
129{
130 unsigned long flags;
131 unsigned char mask;
132 unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
133 unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
134
135 if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
136 DPRINTK("Disable L2 IRQ %d\n", irq);
137 DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
138 mask_port, bit);
139 local_irq_save(flags);
140
141 /* Disable L2 IRQ - set mask bit */
142 mask = inb(mask_port) | bit;
143 outb(mask, mask_port);
144 local_irq_restore(flags);
145 return;
146 }
147 DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
148}
149
150static void enable_bigsur_l2irq(unsigned int irq)
151{
152 unsigned long flags;
153 unsigned char mask;
154 unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
155 unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
156
157 if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
158 DPRINTK("Enable L2 IRQ %d\n", irq);
159 DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
160 mask_port, bit);
161 local_irq_save(flags);
162
163 /* Enable L2 IRQ - clear mask bit */
164 mask = inb(mask_port) & ~bit;
165 outb(mask, mask_port);
166 local_irq_restore(flags);
167 return;
168 }
169 DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
170}
171
172static void mask_and_ack_bigsur(unsigned int irq)
173{
174 DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq);
175 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
176 disable_bigsur_l1irq(irq);
177 else
178 disable_bigsur_l2irq(irq);
179}
180
181static void end_bigsur_irq(unsigned int irq)
182{
183 DPRINTK("end_bigsur_irq IRQ %d\n", irq);
184 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
185 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
186 enable_bigsur_l1irq(irq);
187 else
188 enable_bigsur_l2irq(irq);
189 }
190}
191
192static unsigned int startup_bigsur_irq(unsigned int irq)
193{
194 u8 mask;
195 u32 reg;
196
197 DPRINTK("startup_bigsur_irq IRQ %d\n", irq);
198
199 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
200 /* Enable the L1 IRQ */
201 enable_bigsur_l1irq(irq);
202 /* Enable all L2 IRQs in this L1 IRQ */
203 mask = ~(bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW]);
204 reg = imr_base - bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW] * imr_offset;
205 mask &= inb(reg);
206 outb(mask,reg);
207 DIPRINTK(2,"startup_bigsur_irq: IMR=0x%08x mask=0x%x\n",reg,inb(reg));
208 }
209 else {
210 /* Enable the L2 IRQ - clear mask bit */
211 enable_bigsur_l2irq(irq);
212 /* Enable the L1 bit masking this L2 IRQ */
213 enable_bigsur_l1irq(bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW]);
214 DIPRINTK(2,"startup_bigsur_irq: L1=%d L2=%d\n",
215 bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW],irq);
216 }
217 return 0;
218}
219
220static void shutdown_bigsur_irq(unsigned int irq)
221{
222 DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq);
223 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
224 disable_bigsur_l1irq(irq);
225 else
226 disable_bigsur_l2irq(irq);
227}
228
229/* Define the IRQ structures for the L1 and L2 IRQ types */
230static struct hw_interrupt_type bigsur_l1irq_type = {
231 "BigSur-CPLD-Level1-IRQ",
232 startup_bigsur_irq,
233 shutdown_bigsur_irq,
234 enable_bigsur_l1irq,
235 disable_bigsur_l1irq,
236 mask_and_ack_bigsur,
237 end_bigsur_irq
238};
239
240static struct hw_interrupt_type bigsur_l2irq_type = {
241 "BigSur-CPLD-Level2-IRQ",
242 startup_bigsur_irq,
243 shutdown_bigsur_irq,
244 enable_bigsur_l2irq,
245 disable_bigsur_l2irq,
246 mask_and_ack_bigsur,
247 end_bigsur_irq
248};
249
250
251static void make_bigsur_l1isr(unsigned int irq) {
252
253 /* sanity check first */
254 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
255 /* save the handler in the main description table */
256 irq_desc[irq].handler = &bigsur_l1irq_type;
257 irq_desc[irq].status = IRQ_DISABLED;
258 irq_desc[irq].action = 0;
259 irq_desc[irq].depth = 1;
260
261 disable_bigsur_l1irq(irq);
262 return;
263 }
264 DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq);
265 return;
266}
267
268static void make_bigsur_l2isr(unsigned int irq) {
269
270 /* sanity check first */
271 if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
272 /* save the handler in the main description table */
273 irq_desc[irq].handler = &bigsur_l2irq_type;
274 irq_desc[irq].status = IRQ_DISABLED;
275 irq_desc[irq].action = 0;
276 irq_desc[irq].depth = 1;
277
278 disable_bigsur_l2irq(irq);
279 return;
280 }
281 DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq);
282 return;
283}
284
285/* The IRQ's will be decoded as follows:
286 * If a level 2 handler exists and there is an unmasked active
287 * IRQ, the 2nd level handler will be called.
288 * If a level 2 handler does not exist for the active IRQ
289 * the 1st level handler will be called.
290 */
291
292int bigsur_irq_demux(int irq)
293{
294 int dmux_irq = irq;
295 u8 mask, actv_irqs;
296 u32 reg_num;
297
298 DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq);
299 /* decode the 1st level IRQ */
300 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
301 /* Get corresponding L2 ISR bitmask and ISR number */
302 mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW];
303 reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW];
304 /* find the active IRQ's (XOR with inactive level)*/
305 actv_irqs = inb(isr_base-reg_num*isr_offset) ^
306 bigsur_l2_inactv_state[reg_num];
307 /* decode active IRQ's */
308 actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset));
309 /* if NEZ then we have an active L2 IRQ */
310 if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW;
311 /* if no 2nd level IRQ action, but has 1st level, use 1st level handler */
312 if(!irq_desc[dmux_irq].action && irq_desc[irq].action)
313 dmux_irq = irq;
314 DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n",
315 irq, dmux_irq, mask, reg_num);
316 }
317#ifdef CONFIG_HD64465
318 dmux_irq = hd64465_irq_demux(dmux_irq);
319#endif /* CONFIG_HD64465 */
320 DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq);
321
322 return dmux_irq;
323}
324
325/*===========================================================*/
326// Big Sur Init Routines
327/*===========================================================*/
328void __init init_bigsur_IRQ(void)
329{
330 int i;
331
332 if (!MACH_BIGSUR) return;
333
334 /* Create ISR's for Big Sur CPLD IRQ's */
335 /*==============================================================*/
336 for(i=BIGSUR_IRQ_LOW;i<BIGSUR_IRQ_HIGH;i++)
337 make_bigsur_l1isr(i);
338
339 printk(KERN_INFO "Big Sur CPLD L1 interrupts %d to %d.\n",
340 BIGSUR_IRQ_LOW,BIGSUR_IRQ_HIGH);
341
342 for(i=BIGSUR_2NDLVL_IRQ_LOW;i<BIGSUR_2NDLVL_IRQ_HIGH;i++)
343 make_bigsur_l2isr(i);
344
345 printk(KERN_INFO "Big Sur CPLD L2 interrupts %d to %d.\n",
346 BIGSUR_2NDLVL_IRQ_LOW,BIGSUR_2NDLVL_IRQ_HIGH);
347
348}
diff --git a/arch/sh/boards/bigsur/led.c b/arch/sh/boards/bigsur/led.c
new file mode 100644
index 000000000000..0a2339c69440
--- /dev/null
+++ b/arch/sh/boards/bigsur/led.c
@@ -0,0 +1,55 @@
1/*
2 * linux/arch/sh/kernel/led_bigsur.c
3 *
4 * By Dustin McIntire (dustin@sensoria.com) (c)2001
5 * Derived from led_se.c and led.c, which bore the message:
6 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * This file contains Big Sur specific LED code.
12 */
13
14#include <linux/config.h>
15#include <asm/io.h>
16#include <asm/bigsur/bigsur.h>
17
18static void mach_led(int position, int value)
19{
20 int word;
21
22 word = bigsur_inl(BIGSUR_CSLR);
23 if (value) {
24 bigsur_outl(word & ~BIGSUR_LED, BIGSUR_CSLR);
25 } else {
26 bigsur_outl(word | BIGSUR_LED, BIGSUR_CSLR);
27 }
28}
29
30#ifdef CONFIG_HEARTBEAT
31
32#include <linux/sched.h>
33
34/* Cycle the LED on/off */
35void heartbeat_bigsur(void)
36{
37 static unsigned cnt = 0, period = 0, dist = 0;
38
39 if (cnt == 0 || cnt == dist)
40 mach_led( -1, 1);
41 else if (cnt == 7 || cnt == dist+7)
42 mach_led( -1, 0);
43
44 if (++cnt > period) {
45 cnt = 0;
46 /* The hyperbolic function below modifies the heartbeat period
47 * length in dependency of the current (5min) load. It goes
48 * through the points f(0)=126, f(1)=86, f(5)=51,
49 * f(inf)->30. */
50 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
51 dist = period / 4;
52 }
53}
54#endif /* CONFIG_HEARTBEAT */
55
diff --git a/arch/sh/boards/bigsur/setup.c b/arch/sh/boards/bigsur/setup.c
new file mode 100644
index 000000000000..e69be05195f5
--- /dev/null
+++ b/arch/sh/boards/bigsur/setup.c
@@ -0,0 +1,96 @@
1/*
2 *
3 * By Dustin McIntire (dustin@sensoria.com) (c)2001
4 *
5 * Setup and IRQ handling code for the HD64465 companion chip.
6 * by Greg Banks <gbanks@pocketpenguins.com>
7 * Copyright (c) 2000 PocketPenguins Inc
8 *
9 * Derived from setup_hd64465.c which bore the message:
10 * Greg Banks <gbanks@pocketpenguins.com>
11 * Copyright (c) 2000 PocketPenguins Inc and
12 * Copyright (C) 2000 YAEGASHI Takeshi
13 * and setup_cqreek.c which bore message:
14 * Copyright (C) 2000 Niibe Yutaka
15 *
16 * May be copied or modified under the terms of the GNU General Public
17 * License. See linux/COPYING for more information.
18 *
19 * Setup functions for a Hitachi Big Sur Evaluation Board.
20 *
21 */
22
23#include <linux/config.h>
24#include <linux/sched.h>
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/param.h>
28#include <linux/ioport.h>
29#include <linux/interrupt.h>
30#include <linux/init.h>
31#include <linux/irq.h>
32#include <linux/bitops.h>
33
34#include <asm/io.h>
35#include <asm/irq.h>
36#include <asm/machvec.h>
37#include <asm/bigsur/io.h>
38#include <asm/hd64465/hd64465.h>
39#include <asm/bigsur/bigsur.h>
40
41/*===========================================================*/
42// Big Sur Init Routines
43/*===========================================================*/
44
45const char *get_system_type(void)
46{
47 return "Big Sur";
48}
49
50/*
51 * The Machine Vector
52 */
53extern void heartbeat_bigsur(void);
54extern void init_bigsur_IRQ(void);
55
56struct sh_machine_vector mv_bigsur __initmv = {
57 .mv_nr_irqs = NR_IRQS, // Defined in <asm/irq.h>
58
59 .mv_isa_port2addr = bigsur_isa_port2addr,
60 .mv_irq_demux = bigsur_irq_demux,
61
62 .mv_init_irq = init_bigsur_IRQ,
63#ifdef CONFIG_HEARTBEAT
64 .mv_heartbeat = heartbeat_bigsur,
65#endif
66};
67ALIAS_MV(bigsur)
68
69int __init platform_setup(void)
70{
71 /* Mask all 2nd level IRQ's */
72 outb(-1,BIGSUR_IMR0);
73 outb(-1,BIGSUR_IMR1);
74 outb(-1,BIGSUR_IMR2);
75 outb(-1,BIGSUR_IMR3);
76
77 /* Mask 1st level interrupts */
78 outb(-1,BIGSUR_IRLMR0);
79 outb(-1,BIGSUR_IRLMR1);
80
81#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL)
82 /* remap IO ports for first ISA serial port to HD64465 UART */
83 bigsur_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
84#endif /* CONFIG_HD64465 && CONFIG_SERIAL */
85 /* TODO: setup IDE registers */
86 bigsur_port_map(BIGSUR_IDECTL_IOPORT, 2, BIGSUR_ICTL, 8);
87 /* Setup the Ethernet port to BIGSUR_ETHER_IOPORT */
88 bigsur_port_map(BIGSUR_ETHER_IOPORT, 16, BIGSUR_ETHR+BIGSUR_ETHER_IOPORT, 0);
89 /* set page to 1 */
90 outw(1, BIGSUR_ETHR+0xe);
91 /* set the IO port to BIGSUR_ETHER_IOPORT */
92 outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
93
94 return 0;
95}
96
diff --git a/arch/sh/boards/cat68701/Makefile b/arch/sh/boards/cat68701/Makefile
new file mode 100644
index 000000000000..52c1de0a6dfd
--- /dev/null
+++ b/arch/sh/boards/cat68701/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the CAT-68701 specific parts of the kernel
3#
4
5obj-y := setup.o irq.o
6
diff --git a/arch/sh/boards/cat68701/irq.c b/arch/sh/boards/cat68701/irq.c
new file mode 100644
index 000000000000..f9a6d185fb8b
--- /dev/null
+++ b/arch/sh/boards/cat68701/irq.c
@@ -0,0 +1,28 @@
1/*
2 * linux/arch/sh/boards/cat68701/irq.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * 2001 Yutaro Ebihara
6 *
7 * Setup routines for A-ONE Corp CAT-68701 SH7708 Board
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14
15#include <asm/irq.h>
16
17int cat68701_irq_demux(int irq)
18{
19 if(irq==13) return 14;
20 if(irq==7) return 10;
21 return irq;
22}
23
24void init_cat68701_IRQ()
25{
26 make_imask_irq(10);
27 make_imask_irq(14);
28}
diff --git a/arch/sh/boards/cat68701/setup.c b/arch/sh/boards/cat68701/setup.c
new file mode 100644
index 000000000000..ae8a350ade53
--- /dev/null
+++ b/arch/sh/boards/cat68701/setup.c
@@ -0,0 +1,86 @@
1/*
2 * linux/arch/sh/boards/cat68701/setup.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * 2001 Yutaro Ebihara
6 *
7 * Setup routines for A-ONE Corp CAT-68701 SH7708 Board
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14
15#include <asm/io.h>
16#include <asm/machvec.h>
17#include <asm/mach/io.h>
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/sched.h>
22
23const char *get_system_type(void)
24{
25 return "CAT-68701";
26}
27
28#ifdef CONFIG_HEARTBEAT
29void heartbeat_cat68701()
30{
31 static unsigned int cnt = 0, period = 0 , bit = 0;
32 cnt += 1;
33 if (cnt < period) {
34 return;
35 }
36 cnt = 0;
37
38 /* Go through the points (roughly!):
39 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
40 */
41 period = 110 - ( (300<<FSHIFT)/
42 ((avenrun[0]/5) + (3<<FSHIFT)) );
43
44 if(bit){ bit=0; }else{ bit=1; }
45 outw(bit<<15,0x3fe);
46}
47#endif /* CONFIG_HEARTBEAT */
48
49unsigned long cat68701_isa_port2addr(unsigned long offset)
50{
51 /* CompactFlash (IDE) */
52 if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset==0x3f6))
53 return 0xba000000 + offset;
54
55 /* INPUT PORT */
56 if ((offset >= 0x3fc) && (offset <= 0x3fd))
57 return 0xb4007000 + offset;
58
59 /* OUTPUT PORT */
60 if ((offset >= 0x3fe) && (offset <= 0x3ff))
61 return 0xb4007400 + offset;
62
63 return offset + 0xb4000000; /* other I/O (EREA 5)*/
64}
65
66/*
67 * The Machine Vector
68 */
69
70struct sh_machine_vector mv_cat68701 __initmv = {
71 .mv_nr_irqs = 32,
72 .mv_isa_port2addr = cat68701_isa_port2addr,
73 .mv_irq_demux = cat68701_irq_demux,
74
75 .mv_init_irq = init_cat68701_IRQ,
76#ifdef CONFIG_HEARTBEAT
77 .mv_heartbeat = heartbeat_cat68701,
78#endif
79};
80ALIAS_MV(cat68701)
81
82int __init platform_setup(void)
83{
84 /* dummy read erea5 (CS8900A) */
85}
86
diff --git a/arch/sh/boards/cqreek/Makefile b/arch/sh/boards/cqreek/Makefile
new file mode 100644
index 000000000000..1a788a85eba3
--- /dev/null
+++ b/arch/sh/boards/cqreek/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the CqREEK specific parts of the kernel
3#
4
5obj-y := setup.o irq.o
6
diff --git a/arch/sh/boards/cqreek/irq.c b/arch/sh/boards/cqreek/irq.c
new file mode 100644
index 000000000000..fa6cfe5a20a7
--- /dev/null
+++ b/arch/sh/boards/cqreek/irq.c
@@ -0,0 +1,128 @@
1/* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $
2 *
3 * arch/sh/boards/cqreek/irq.c
4 *
5 * Copyright (C) 2000 Niibe Yutaka
6 *
7 * CqREEK IDE/ISA Bridge Support.
8 *
9 */
10
11#include <linux/irq.h>
12#include <linux/init.h>
13
14#include <asm/cqreek/cqreek.h>
15#include <asm/io.h>
16#include <asm/io_generic.h>
17#include <asm/irq.h>
18#include <asm/machvec.h>
19#include <asm/machvec_init.h>
20#include <asm/rtc.h>
21
22struct cqreek_irq_data {
23 unsigned short mask_port; /* Port of Interrupt Mask Register */
24 unsigned short stat_port; /* Port of Interrupt Status Register */
25 unsigned short bit; /* Value of the bit */
26};
27static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
28
29static void disable_cqreek_irq(unsigned int irq)
30{
31 unsigned long flags;
32 unsigned short mask;
33 unsigned short mask_port = cqreek_irq_data[irq].mask_port;
34 unsigned short bit = cqreek_irq_data[irq].bit;
35
36 local_irq_save(flags);
37 /* Disable IRQ */
38 mask = inw(mask_port) & ~bit;
39 outw_p(mask, mask_port);
40 local_irq_restore(flags);
41}
42
43static void enable_cqreek_irq(unsigned int irq)
44{
45 unsigned long flags;
46 unsigned short mask;
47 unsigned short mask_port = cqreek_irq_data[irq].mask_port;
48 unsigned short bit = cqreek_irq_data[irq].bit;
49
50 local_irq_save(flags);
51 /* Enable IRQ */
52 mask = inw(mask_port) | bit;
53 outw_p(mask, mask_port);
54 local_irq_restore(flags);
55}
56
57static void mask_and_ack_cqreek(unsigned int irq)
58{
59 unsigned short stat_port = cqreek_irq_data[irq].stat_port;
60 unsigned short bit = cqreek_irq_data[irq].bit;
61
62 disable_cqreek_irq(irq);
63 /* Clear IRQ (it might be edge IRQ) */
64 inw(stat_port);
65 outw_p(bit, stat_port);
66}
67
68static void end_cqreek_irq(unsigned int irq)
69{
70 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
71 enable_cqreek_irq(irq);
72}
73
74static unsigned int startup_cqreek_irq(unsigned int irq)
75{
76 enable_cqreek_irq(irq);
77 return 0;
78}
79
80static void shutdown_cqreek_irq(unsigned int irq)
81{
82 disable_cqreek_irq(irq);
83}
84
85static struct hw_interrupt_type cqreek_irq_type = {
86 "CqREEK-IRQ",
87 startup_cqreek_irq,
88 shutdown_cqreek_irq,
89 enable_cqreek_irq,
90 disable_cqreek_irq,
91 mask_and_ack_cqreek,
92 end_cqreek_irq
93};
94
95int cqreek_has_ide, cqreek_has_isa;
96
97/* XXX: This is just for test for my NE2000 ISA board
98 What we really need is virtualized IRQ and demultiplexer like HP600 port */
99void __init init_cqreek_IRQ(void)
100{
101 if (cqreek_has_ide) {
102 cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
103 cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
104 cqreek_irq_data[14].bit = 1;
105
106 irq_desc[14].handler = &cqreek_irq_type;
107 irq_desc[14].status = IRQ_DISABLED;
108 irq_desc[14].action = 0;
109 irq_desc[14].depth = 1;
110
111 disable_cqreek_irq(14);
112 }
113
114 if (cqreek_has_isa) {
115 cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
116 cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
117 cqreek_irq_data[10].bit = (1 << 10);
118
119 /* XXX: Err... we may need demultiplexer for ISA irq... */
120 irq_desc[10].handler = &cqreek_irq_type;
121 irq_desc[10].status = IRQ_DISABLED;
122 irq_desc[10].action = 0;
123 irq_desc[10].depth = 1;
124
125 disable_cqreek_irq(10);
126 }
127}
128
diff --git a/arch/sh/boards/cqreek/setup.c b/arch/sh/boards/cqreek/setup.c
new file mode 100644
index 000000000000..29b537cd6546
--- /dev/null
+++ b/arch/sh/boards/cqreek/setup.c
@@ -0,0 +1,101 @@
1/* $Id: setup.c,v 1.5 2003/08/04 01:51:58 lethal Exp $
2 *
3 * arch/sh/kernel/setup_cqreek.c
4 *
5 * Copyright (C) 2000 Niibe Yutaka
6 *
7 * CqREEK IDE/ISA Bridge Support.
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <asm/mach/cqreek.h>
17#include <asm/machvec.h>
18#include <asm/io.h>
19#include <asm/io_generic.h>
20#include <asm/irq.h>
21#include <asm/rtc.h>
22
23#define IDE_OFFSET 0xA4000000UL
24#define ISA_OFFSET 0xA4A00000UL
25
26const char *get_system_type(void)
27{
28 return "CqREEK";
29}
30
31static unsigned long cqreek_port2addr(unsigned long port)
32{
33 if (0x0000<=port && port<=0x0040)
34 return IDE_OFFSET + port;
35 if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
36 return IDE_OFFSET + port;
37
38 return ISA_OFFSET + port;
39}
40
41/*
42 * The Machine Vector
43 */
44struct sh_machine_vector mv_cqreek __initmv = {
45#if defined(CONFIG_CPU_SH4)
46 .mv_nr_irqs = 48,
47#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
48 .mv_nr_irqs = 32,
49#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
50 .mv_nr_irqs = 61,
51#endif
52
53 .mv_init_irq = init_cqreek_IRQ,
54
55 .mv_isa_port2addr = cqreek_port2addr,
56};
57ALIAS_MV(cqreek)
58
59/*
60 * Initialize the board
61 */
62void __init platform_setup(void)
63{
64 int i;
65/* udelay is not available at setup time yet... */
66#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
67
68 if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
69 outw_p(0, BRIDGE_IDE_INTR_LVL);
70 outw_p(0, BRIDGE_IDE_INTR_MASK);
71
72 outw_p(0, BRIDGE_IDE_CTRL);
73 DELAY();
74
75 outw_p(0x8000, BRIDGE_IDE_CTRL);
76 DELAY();
77
78 outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
79 outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
80 outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
81 cqreek_has_ide=1;
82 }
83
84 if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
85 outw_p(0, BRIDGE_ISA_INTR_LVL);
86 outw_p(0, BRIDGE_ISA_INTR_MASK);
87
88 outw_p(0, BRIDGE_ISA_CTRL);
89 DELAY();
90 outw_p(0x8000, BRIDGE_ISA_CTRL);
91 DELAY();
92
93 outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
94 outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
95 outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
96 cqreek_has_isa=1;
97 }
98
99 printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", cqreek_has_ide, cqreek_has_isa);
100}
101
diff --git a/arch/sh/boards/dmida/Makefile b/arch/sh/boards/dmida/Makefile
new file mode 100644
index 000000000000..75999aa0a2d9
--- /dev/null
+++ b/arch/sh/boards/dmida/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts
3# of the kernel
4#
5
6obj-y := mach.o
7
diff --git a/arch/sh/boards/dmida/mach.c b/arch/sh/boards/dmida/mach.c
new file mode 100644
index 000000000000..d03a25f989c2
--- /dev/null
+++ b/arch/sh/boards/dmida/mach.c
@@ -0,0 +1,59 @@
1/*
2 * linux/arch/sh/boards/dmida/mach.c
3 *
4 * by Greg Banks <gbanks@pocketpenguins.com>
5 * (c) 2000 PocketPenguins Inc
6 *
7 * Derived from mach_hp600.c, which bore the message:
8 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 *
13 * Machine vector for the DataMyte Industrial Digital Assistant(tm).
14 * See http://www.dmida.com
15 *
16 */
17
18#include <linux/init.h>
19
20#include <asm/machvec.h>
21#include <asm/rtc.h>
22#include <asm/machvec_init.h>
23
24#include <asm/io.h>
25#include <asm/hd64465/hd64465.h>
26#include <asm/irq.h>
27
28/*
29 * The Machine Vector
30 */
31
32struct sh_machine_vector mv_dmida __initmv = {
33 .mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM,
34
35 .mv_inb = hd64465_inb,
36 .mv_inw = hd64465_inw,
37 .mv_inl = hd64465_inl,
38 .mv_outb = hd64465_outb,
39 .mv_outw = hd64465_outw,
40 .mv_outl = hd64465_outl,
41
42 .mv_inb_p = hd64465_inb_p,
43 .mv_inw_p = hd64465_inw,
44 .mv_inl_p = hd64465_inl,
45 .mv_outb_p = hd64465_outb_p,
46 .mv_outw_p = hd64465_outw,
47 .mv_outl_p = hd64465_outl,
48
49 .mv_insb = hd64465_insb,
50 .mv_insw = hd64465_insw,
51 .mv_insl = hd64465_insl,
52 .mv_outsb = hd64465_outsb,
53 .mv_outsw = hd64465_outsw,
54 .mv_outsl = hd64465_outsl,
55
56 .mv_irq_demux = hd64465_irq_demux,
57};
58ALIAS_MV(dmida)
59
diff --git a/arch/sh/boards/dreamcast/Makefile b/arch/sh/boards/dreamcast/Makefile
new file mode 100644
index 000000000000..7b97546c7e5f
--- /dev/null
+++ b/arch/sh/boards/dreamcast/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the Sega Dreamcast specific parts of the kernel
3#
4
5obj-y := setup.o irq.o rtc.o
6
diff --git a/arch/sh/boards/dreamcast/irq.c b/arch/sh/boards/dreamcast/irq.c
new file mode 100644
index 000000000000..b10a6b11c034
--- /dev/null
+++ b/arch/sh/boards/dreamcast/irq.c
@@ -0,0 +1,160 @@
1/*
2 * arch/sh/boards/dreamcast/irq.c
3 *
4 * Holly IRQ support for the Sega Dreamcast.
5 *
6 * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
7 *
8 * This file is part of the LinuxDC project (www.linuxdc.org)
9 * Released under the terms of the GNU GPL v2.0
10 */
11
12#include <linux/irq.h>
13
14#include <asm/io.h>
15#include <asm/irq.h>
16#include <asm/dreamcast/sysasic.h>
17
18/* Dreamcast System ASIC Hardware Events -
19
20 The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
21 hardware events from system peripherals and triggering an SH7750 IRQ.
22 Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
23 set in the Event Mask Registers (EMRs). When a hardware event is
24 triggered, it's corresponding bit in the Event Status Registers (ESRs)
25 is set, and that bit should be rewritten to the ESR to acknowledge that
26 event.
27
28 There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event
29 types can be found in include/asm-sh/dc_sysasic.h. There are three groups
30 of EMRs that parallel the ESRs. Each EMR group corresponds to an IRQ, so
31 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers
32 IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
33
34 In the kernel, these events are mapped to virtual IRQs so that drivers can
35 respond to them as they would a normal interrupt. In order to keep this
36 mapping simple, the events are mapped as:
37
38 6900/6910 - Events 0-31, IRQ 13
39 6904/6924 - Events 32-63, IRQ 11
40 6908/6938 - Events 64-95, IRQ 9
41
42*/
43
44#define ESR_BASE 0x005f6900 /* Base event status register */
45#define EMR_BASE 0x005f6910 /* Base event mask register */
46
47/* Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
48 1 = 0x6920, 2 = 0x6930; also determine the event offset */
49#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
50
51/* Return the hardware event's bit positon within the EMR/ESR */
52#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
53
54/* For each of these *_irq routines, the IRQ passed in is the virtual IRQ
55 (logically mapped to the corresponding bit for the hardware event). */
56
57/* Disable the hardware event by masking its bit in its EMR */
58static inline void disable_systemasic_irq(unsigned int irq)
59{
60 unsigned long flags;
61 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
62 __u32 mask;
63
64 local_irq_save(flags);
65 mask = inl(emr);
66 mask &= ~(1 << EVENT_BIT(irq));
67 outl(mask, emr);
68 local_irq_restore(flags);
69}
70
71/* Enable the hardware event by setting its bit in its EMR */
72static inline void enable_systemasic_irq(unsigned int irq)
73{
74 unsigned long flags;
75 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
76 __u32 mask;
77
78 local_irq_save(flags);
79 mask = inl(emr);
80 mask |= (1 << EVENT_BIT(irq));
81 outl(mask, emr);
82 local_irq_restore(flags);
83}
84
85/* Acknowledge a hardware event by writing its bit back to its ESR */
86static void ack_systemasic_irq(unsigned int irq)
87{
88 __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
89 disable_systemasic_irq(irq);
90 outl((1 << EVENT_BIT(irq)), esr);
91}
92
93/* After a IRQ has been ack'd and responded to, it needs to be renabled */
94static void end_systemasic_irq(unsigned int irq)
95{
96 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
97 enable_systemasic_irq(irq);
98}
99
100static unsigned int startup_systemasic_irq(unsigned int irq)
101{
102 enable_systemasic_irq(irq);
103
104 return 0;
105}
106
107static void shutdown_systemasic_irq(unsigned int irq)
108{
109 disable_systemasic_irq(irq);
110}
111
112struct hw_interrupt_type systemasic_int = {
113 .typename = "System ASIC",
114 .startup = startup_systemasic_irq,
115 .shutdown = shutdown_systemasic_irq,
116 .enable = enable_systemasic_irq,
117 .disable = disable_systemasic_irq,
118 .ack = ack_systemasic_irq,
119 .end = end_systemasic_irq,
120};
121
122/*
123 * Map the hardware event indicated by the processor IRQ to a virtual IRQ.
124 */
125int systemasic_irq_demux(int irq)
126{
127 __u32 emr, esr, status, level;
128 __u32 j, bit;
129
130 switch (irq) {
131 case 13:
132 level = 0;
133 break;
134 case 11:
135 level = 1;
136 break;
137 case 9:
138 level = 2;
139 break;
140 default:
141 return irq;
142 }
143 emr = EMR_BASE + (level << 4) + (level << 2);
144 esr = ESR_BASE + (level << 2);
145
146 /* Mask the ESR to filter any spurious, unwanted interrtupts */
147 status = inl(esr);
148 status &= inl(emr);
149
150 /* Now scan and find the first set bit as the event to map */
151 for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
152 if (status & bit) {
153 irq = HW_EVENT_IRQ_BASE + j + (level << 5);
154 return irq;
155 }
156 }
157
158 /* Not reached */
159 return irq;
160}
diff --git a/arch/sh/boards/dreamcast/rtc.c b/arch/sh/boards/dreamcast/rtc.c
new file mode 100644
index 000000000000..379de1629134
--- /dev/null
+++ b/arch/sh/boards/dreamcast/rtc.c
@@ -0,0 +1,81 @@
1/* arch/sh/kernel/rtc-aica.c
2 *
3 * Dreamcast AICA RTC routines.
4 *
5 * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@0xd6.org>
6 * Copyright (c) 2002 Paul Mundt <lethal@chaoticdreams.org>
7 *
8 * Released under the terms of the GNU GPL v2.0.
9 *
10 */
11
12#include <linux/time.h>
13
14#include <asm/io.h>
15
16extern void (*rtc_get_time)(struct timespec *);
17extern int (*rtc_set_time)(const time_t);
18
19/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
20 seconds to get the standard Unix Epoch when getting the time, and add 20
21 years when setting the time. */
22#define TWENTY_YEARS ((20 * 365LU + 5) * 86400)
23
24/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit
25 registers.*/
26#define AICA_RTC_SECS_H 0xa0710000
27#define AICA_RTC_SECS_L 0xa0710004
28
29/**
30 * aica_rtc_gettimeofday - Get the time from the AICA RTC
31 * @ts: pointer to resulting timespec
32 *
33 * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
34 */
35void aica_rtc_gettimeofday(struct timespec *ts) {
36 unsigned long val1, val2;
37
38 do {
39 val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
40 (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
41
42 val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
43 (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
44 } while (val1 != val2);
45
46 ts->tv_sec = val1 - TWENTY_YEARS;
47
48 /* Can't get nanoseconds with just a seconds counter. */
49 ts->tv_nsec = 0;
50}
51
52/**
53 * aica_rtc_settimeofday - Set the AICA RTC to the current time
54 * @secs: contains the time_t to set
55 *
56 * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
57 */
58int aica_rtc_settimeofday(const time_t secs) {
59 unsigned long val1, val2;
60 unsigned long adj = secs + TWENTY_YEARS;
61
62 do {
63 ctrl_outl((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
64 ctrl_outl((adj & 0xffff), AICA_RTC_SECS_L);
65
66 val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
67 (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
68
69 val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
70 (ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
71 } while (val1 != val2);
72
73 return 0;
74}
75
76void aica_time_init(void)
77{
78 rtc_get_time = aica_rtc_gettimeofday;
79 rtc_set_time = aica_rtc_settimeofday;
80}
81
diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c
new file mode 100644
index 000000000000..55dece35cde5
--- /dev/null
+++ b/arch/sh/boards/dreamcast/setup.c
@@ -0,0 +1,83 @@
1/*
2 * arch/sh/boards/dreamcast/setup.c
3 *
4 * Hardware support for the Sega Dreamcast.
5 *
6 * Copyright (c) 2001, 2002 M. R. Brown <mrbrown@linuxdc.org>
7 * Copyright (c) 2002, 2003, 2004 Paul Mundt <lethal@linux-sh.org>
8 *
9 * This file is part of the LinuxDC project (www.linuxdc.org)
10 *
11 * Released under the terms of the GNU GPL v2.0.
12 *
13 * This file originally bore the message (with enclosed-$):
14 * Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
15 * SEGA Dreamcast support
16 */
17
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/param.h>
21#include <linux/interrupt.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24#include <linux/device.h>
25
26#include <asm/io.h>
27#include <asm/irq.h>
28#include <asm/machvec.h>
29#include <asm/machvec_init.h>
30#include <asm/mach/sysasic.h>
31
32extern struct hw_interrupt_type systemasic_int;
33/* XXX: Move this into it's proper header. */
34extern void (*board_time_init)(void);
35extern void aica_time_init(void);
36extern int gapspci_init(void);
37extern int systemasic_irq_demux(int);
38
39void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
40int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t);
41
42const char *get_system_type(void)
43{
44 return "Sega Dreamcast";
45}
46
47struct sh_machine_vector mv_dreamcast __initmv = {
48 .mv_nr_irqs = NR_IRQS,
49
50 .mv_irq_demux = systemasic_irq_demux,
51
52#ifdef CONFIG_PCI
53 .mv_consistent_alloc = dreamcast_consistent_alloc,
54 .mv_consistent_free = dreamcast_consistent_free,
55#endif
56};
57ALIAS_MV(dreamcast)
58
59int __init platform_setup(void)
60{
61 int i;
62
63 /* Mask all hardware events */
64 /* XXX */
65
66 /* Acknowledge any previous events */
67 /* XXX */
68
69 __set_io_port_base(0xa0000000);
70
71 /* Assign all virtual IRQs to the System ASIC int. handler */
72 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
73 irq_desc[i].handler = &systemasic_int;
74
75 board_time_init = aica_time_init;
76
77#ifdef CONFIG_PCI
78 if (gapspci_init() < 0)
79 printk(KERN_WARNING "GAPSPCI was not detected.\n");
80#endif
81
82 return 0;
83}
diff --git a/arch/sh/boards/ec3104/Makefile b/arch/sh/boards/ec3104/Makefile
new file mode 100644
index 000000000000..178891534b67
--- /dev/null
+++ b/arch/sh/boards/ec3104/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the EC3104 specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6
diff --git a/arch/sh/boards/ec3104/io.c b/arch/sh/boards/ec3104/io.c
new file mode 100644
index 000000000000..a70928c44753
--- /dev/null
+++ b/arch/sh/boards/ec3104/io.c
@@ -0,0 +1,81 @@
1/*
2 * linux/arch/sh/kernel/io_ec3104.c
3 * EC3104 companion chip support
4 *
5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
6 *
7 */
8/* EC3104 note:
9 * This code was written without any documentation about the EC3104 chip. While
10 * I hope I got most of the basic functionality right, the register names I use
11 * are most likely completely different from those in the chip documentation.
12 *
13 * If you have any further information about the EC3104, please tell me
14 * (prumpf@tux.org).
15 */
16
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <asm/io.h>
20#include <asm/page.h>
21#include <asm/ec3104/ec3104.h>
22
23/*
24 * EC3104 has a real ISA bus which we redirect low port accesses to (the
25 * actual device on mine is a ESS 1868, and I don't want to hack the driver
26 * more than strictly necessary). I am not going to duplicate the
27 * hard coding of PC addresses (for the 16550s aso) here though; it's just
28 * too ugly.
29 */
30
31#define low_port(port) ((port) < 0x10000)
32
33static inline unsigned long port2addr(unsigned long port)
34{
35 switch(port >> 16) {
36 case 0:
37 return EC3104_ISA_BASE + port * 2;
38
39 /* XXX hack. it's unclear what to do about the serial ports */
40 case 1:
41 return EC3104_BASE + (port&0xffff) * 4;
42
43 default:
44 /* XXX PCMCIA */
45 return 0;
46 }
47}
48
49unsigned char ec3104_inb(unsigned long port)
50{
51 u8 ret;
52
53 ret = *(volatile u8 *)port2addr(port);
54
55 return ret;
56}
57
58unsigned short ec3104_inw(unsigned long port)
59{
60 BUG();
61}
62
63unsigned long ec3104_inl(unsigned long port)
64{
65 BUG();
66}
67
68void ec3104_outb(unsigned char data, unsigned long port)
69{
70 *(volatile u8 *)port2addr(port) = data;
71}
72
73void ec3104_outw(unsigned short data, unsigned long port)
74{
75 BUG();
76}
77
78void ec3104_outl(unsigned long data, unsigned long port)
79{
80 BUG();
81}
diff --git a/arch/sh/boards/ec3104/irq.c b/arch/sh/boards/ec3104/irq.c
new file mode 100644
index 000000000000..ffa4ff1f090f
--- /dev/null
+++ b/arch/sh/boards/ec3104/irq.c
@@ -0,0 +1,196 @@
1/*
2 * linux/arch/sh/boards/ec3104/irq.c
3 * EC3104 companion chip support
4 *
5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
6 *
7 */
8
9#include <asm/io.h>
10#include <asm/irq.h>
11#include <asm/ec3104/ec3104.h>
12
13/* This is for debugging mostly; here's the table that I intend to keep
14 * in here:
15 *
16 * index function base addr power interrupt bit
17 * 0 power b0ec0000 --- 00000001 (unused)
18 * 1 irqs b0ec1000 --- 00000002 (unused)
19 * 2 ?? b0ec2000 b0ec0008 00000004
20 * 3 PS2 (1) b0ec3000 b0ec000c 00000008
21 * 4 PS2 (2) b0ec4000 b0ec0010 00000010
22 * 5 ?? b0ec5000 b0ec0014 00000020
23 * 6 I2C b0ec6000 b0ec0018 00000040
24 * 7 serial (1) b0ec7000 b0ec001c 00000080
25 * 8 serial (2) b0ec8000 b0ec0020 00000100
26 * 9 serial (3) b0ec9000 b0ec0024 00000200
27 * 10 serial (4) b0eca000 b0ec0028 00000400
28 * 12 GPIO (1) b0ecc000 b0ec0030
29 * 13 GPIO (2) b0ecc000 b0ec0030
30 * 16 pcmcia (1) b0ed0000 b0ec0040 00010000
31 * 17 pcmcia (2) b0ed1000 b0ec0044 00020000
32 */
33
34/* I used the register names from another interrupt controller I worked with,
35 * since it seems to be identical to the ec3104 except that all bits are
36 * inverted:
37 *
38 * IRR: Interrupt Request Register (pending and enabled interrupts)
39 * IMR: Interrupt Mask Register (which interrupts are enabled)
40 * IPR: Interrupt Pending Register (pending interrupts, even disabled ones)
41 *
42 * 0 bits mean pending or enabled, 1 bits mean not pending or disabled. all
43 * IRQs seem to be level-triggered.
44 */
45
46#define EC3104_IRR (EC3104_BASE + 0x1000)
47#define EC3104_IMR (EC3104_BASE + 0x1004)
48#define EC3104_IPR (EC3104_BASE + 0x1008)
49
50#define ctrl_readl(addr) (*(volatile u32 *)(addr))
51#define ctrl_writel(data,addr) (*(volatile u32 *)(addr) = (data))
52#define ctrl_readb(addr) (*(volatile u8 *)(addr))
53
54static char *ec3104_name(unsigned index)
55{
56 switch(index) {
57 case 0:
58 return "power management";
59 case 1:
60 return "interrupts";
61 case 3:
62 return "PS2 (1)";
63 case 4:
64 return "PS2 (2)";
65 case 5:
66 return "I2C (1)";
67 case 6:
68 return "I2C (2)";
69 case 7:
70 return "serial (1)";
71 case 8:
72 return "serial (2)";
73 case 9:
74 return "serial (3)";
75 case 10:
76 return "serial (4)";
77 case 16:
78 return "pcmcia (1)";
79 case 17:
80 return "pcmcia (2)";
81 default: {
82 static char buf[32];
83
84 sprintf(buf, "unknown (%d)", index);
85
86 return buf;
87 }
88 }
89}
90
91int get_pending_interrupts(char *buf)
92{
93 u32 ipr;
94 u32 bit;
95 char *p = buf;
96
97 p += sprintf(p, "pending: (");
98
99 ipr = ctrl_inl(EC3104_IPR);
100
101 for (bit = 1; bit < 32; bit++)
102 if (!(ipr & (1<<bit)))
103 p += sprintf(p, "%s ", ec3104_name(bit));
104
105 p += sprintf(p, ")\n");
106
107 return p - buf;
108}
109
110static inline u32 ec3104_irq2mask(unsigned int irq)
111{
112 return (1 << (irq - EC3104_IRQBASE));
113}
114
115static inline void mask_ec3104_irq(unsigned int irq)
116{
117 u32 mask;
118
119 mask = ctrl_readl(EC3104_IMR);
120
121 mask |= ec3104_irq2mask(irq);
122
123 ctrl_writel(mask, EC3104_IMR);
124}
125
126static inline void unmask_ec3104_irq(unsigned int irq)
127{
128 u32 mask;
129
130 mask = ctrl_readl(EC3104_IMR);
131
132 mask &= ~ec3104_irq2mask(irq);
133
134 ctrl_writel(mask, EC3104_IMR);
135}
136
137static void disable_ec3104_irq(unsigned int irq)
138{
139 mask_ec3104_irq(irq);
140}
141
142static void enable_ec3104_irq(unsigned int irq)
143{
144 unmask_ec3104_irq(irq);
145}
146
147static void mask_and_ack_ec3104_irq(unsigned int irq)
148{
149 mask_ec3104_irq(irq);
150}
151
152static void end_ec3104_irq(unsigned int irq)
153{
154 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
155 unmask_ec3104_irq(irq);
156}
157
158static unsigned int startup_ec3104_irq(unsigned int irq)
159{
160 unmask_ec3104_irq(irq);
161
162 return 0;
163}
164
165static void shutdown_ec3104_irq(unsigned int irq)
166{
167 mask_ec3104_irq(irq);
168
169}
170
171static struct hw_interrupt_type ec3104_int = {
172 .typename = "EC3104",
173 .enable = enable_ec3104_irq,
174 .disable = disable_ec3104_irq,
175 .ack = mask_and_ack_ec3104_irq,
176 .end = end_ec3104_irq,
177 .startup = startup_ec3104_irq,
178 .shutdown = shutdown_ec3104_irq,
179};
180
181/* Yuck. the _demux API is ugly */
182int ec3104_irq_demux(int irq)
183{
184 if (irq == EC3104_IRQ) {
185 unsigned int mask;
186
187 mask = ctrl_readl(EC3104_IRR);
188
189 if (mask == 0xffffffff)
190 return EC3104_IRQ;
191 else
192 return EC3104_IRQBASE + ffz(mask);
193 }
194
195 return irq;
196}
diff --git a/arch/sh/boards/ec3104/setup.c b/arch/sh/boards/ec3104/setup.c
new file mode 100644
index 000000000000..5130ba2b6ff1
--- /dev/null
+++ b/arch/sh/boards/ec3104/setup.c
@@ -0,0 +1,78 @@
1/*
2 * linux/arch/sh/boards/ec3104/setup.c
3 * EC3104 companion chip support
4 *
5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
6 *
7 */
8/* EC3104 note:
9 * This code was written without any documentation about the EC3104 chip. While
10 * I hope I got most of the basic functionality right, the register names I use
11 * are most likely completely different from those in the chip documentation.
12 *
13 * If you have any further information about the EC3104, please tell me
14 * (prumpf@tux.org).
15 */
16
17#include <linux/sched.h>
18#include <linux/kernel.h>
19#include <linux/param.h>
20#include <linux/interrupt.h>
21#include <linux/init.h>
22#include <linux/irq.h>
23#include <linux/types.h>
24
25#include <asm/io.h>
26#include <asm/irq.h>
27#include <asm/machvec.h>
28#include <asm/mach/ec3104.h>
29
30const char *get_system_type(void)
31{
32 return "EC3104";
33}
34
35/*
36 * The Machine Vector
37 */
38
39struct sh_machine_vector mv_ec3104 __initmv = {
40 .mv_nr_irqs = 96,
41
42 .mv_inb = ec3104_inb,
43 .mv_inw = ec3104_inw,
44 .mv_inl = ec3104_inl,
45 .mv_outb = ec3104_outb,
46 .mv_outw = ec3104_outw,
47 .mv_outl = ec3104_outl,
48
49 .mv_irq_demux = ec3104_irq_demux,
50};
51
52ALIAS_MV(ec3104)
53
54int __init platform_setup(void)
55{
56 char str[8];
57 int i;
58
59 if (0)
60 return 0;
61
62 for (i=0; i<8; i++)
63 str[i] = ctrl_readb(EC3104_BASE + i);
64
65 for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
66 irq_desc[i].handler = &ec3104_int;
67
68 printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
69 str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
70
71
72 /* mask all interrupts. this should have been done by the boot
73 * loader for us but we want to be sure ... */
74 ctrl_writel(0xffffffff, EC3104_IMR);
75
76 return 0;
77}
78
diff --git a/arch/sh/boards/harp/Makefile b/arch/sh/boards/harp/Makefile
new file mode 100644
index 000000000000..eb753d31812e
--- /dev/null
+++ b/arch/sh/boards/harp/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for STMicroelectronics board specific parts of the kernel
3#
4
5obj-y := irq.o setup.o mach.o led.o
6
7obj-$(CONFIG_PCI) += pcidma.o
8
diff --git a/arch/sh/boards/harp/irq.c b/arch/sh/boards/harp/irq.c
new file mode 100644
index 000000000000..acd58489970f
--- /dev/null
+++ b/arch/sh/boards/harp/irq.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Looks after interrupts on the HARP board.
8 *
9 * Bases on the IPR irq system
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <asm/system.h>
17#include <asm/io.h>
18#include <asm/harp/harp.h>
19
20
21#define NUM_EXTERNAL_IRQS 16
22
23// Early versions of the STB1 Overdrive required this nasty frig
24//#define INVERT_INTMASK_WRITES
25
26static void enable_harp_irq(unsigned int irq);
27static void disable_harp_irq(unsigned int irq);
28
29/* shutdown is same as "disable" */
30#define shutdown_harp_irq disable_harp_irq
31
32static void mask_and_ack_harp(unsigned int);
33static void end_harp_irq(unsigned int irq);
34
35static unsigned int startup_harp_irq(unsigned int irq)
36{
37 enable_harp_irq(irq);
38 return 0; /* never anything pending */
39}
40
41static struct hw_interrupt_type harp_irq_type = {
42 "Harp-IRQ",
43 startup_harp_irq,
44 shutdown_harp_irq,
45 enable_harp_irq,
46 disable_harp_irq,
47 mask_and_ack_harp,
48 end_harp_irq
49};
50
51static void disable_harp_irq(unsigned int irq)
52{
53 unsigned val, flags;
54 unsigned maskReg;
55 unsigned mask;
56 int pri;
57
58 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
59 return;
60
61 pri = 15 - irq;
62
63 if (pri < 8) {
64 maskReg = EPLD_INTMASK0;
65 } else {
66 maskReg = EPLD_INTMASK1;
67 pri -= 8;
68 }
69
70 local_irq_save(flags);
71 mask = ctrl_inl(maskReg);
72 mask &= (~(1 << pri));
73#if defined(INVERT_INTMASK_WRITES)
74 mask ^= 0xff;
75#endif
76 ctrl_outl(mask, maskReg);
77 local_irq_restore(flags);
78}
79
80static void enable_harp_irq(unsigned int irq)
81{
82 unsigned flags;
83 unsigned maskReg;
84 unsigned mask;
85 int pri;
86
87 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
88 return;
89
90 pri = 15 - irq;
91
92 if (pri < 8) {
93 maskReg = EPLD_INTMASK0;
94 } else {
95 maskReg = EPLD_INTMASK1;
96 pri -= 8;
97 }
98
99 local_irq_save(flags);
100 mask = ctrl_inl(maskReg);
101
102
103 mask |= (1 << pri);
104
105#if defined(INVERT_INTMASK_WRITES)
106 mask ^= 0xff;
107#endif
108 ctrl_outl(mask, maskReg);
109
110 local_irq_restore(flags);
111}
112
113/* This functions sets the desired irq handler to be an overdrive type */
114static void __init make_harp_irq(unsigned int irq)
115{
116 disable_irq_nosync(irq);
117 irq_desc[irq].handler = &harp_irq_type;
118 disable_harp_irq(irq);
119}
120
121static void mask_and_ack_harp(unsigned int irq)
122{
123 disable_harp_irq(irq);
124}
125
126static void end_harp_irq(unsigned int irq)
127{
128 enable_harp_irq(irq);
129}
130
131void __init init_harp_irq(void)
132{
133 int i;
134
135#if !defined(INVERT_INTMASK_WRITES)
136 // On the harp these are set to enable an interrupt
137 ctrl_outl(0x00, EPLD_INTMASK0);
138 ctrl_outl(0x00, EPLD_INTMASK1);
139#else
140 // On the Overdrive the data is inverted before being stored in the reg
141 ctrl_outl(0xff, EPLD_INTMASK0);
142 ctrl_outl(0xff, EPLD_INTMASK1);
143#endif
144
145 for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
146 make_harp_irq(i);
147 }
148}
diff --git a/arch/sh/boards/harp/led.c b/arch/sh/boards/harp/led.c
new file mode 100644
index 000000000000..76ca4ccac703
--- /dev/null
+++ b/arch/sh/boards/harp/led.c
@@ -0,0 +1,52 @@
1/*
2 * linux/arch/sh/stboards/led.c
3 *
4 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains ST40STB1 HARP and compatible code.
10 */
11
12#include <linux/config.h>
13#include <asm/io.h>
14#include <asm/harp/harp.h>
15
16/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */
17/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */
18/* Works for HARP and overdrive */
19static void mach_led(int position, int value)
20{
21 if (value) {
22 ctrl_outl(EPLD_LED_ON, EPLD_LED);
23 } else {
24 ctrl_outl(EPLD_LED_OFF, EPLD_LED);
25 }
26}
27
28#ifdef CONFIG_HEARTBEAT
29
30#include <linux/sched.h>
31
32/* acts like an actual heart beat -- ie thump-thump-pause... */
33void heartbeat_harp(void)
34{
35 static unsigned cnt = 0, period = 0, dist = 0;
36
37 if (cnt == 0 || cnt == dist)
38 mach_led( -1, 1);
39 else if (cnt == 7 || cnt == dist+7)
40 mach_led( -1, 0);
41
42 if (++cnt > period) {
43 cnt = 0;
44 /* The hyperbolic function below modifies the heartbeat period
45 * length in dependency of the current (5min) load. It goes
46 * through the points f(0)=126, f(1)=86, f(5)=51,
47 * f(inf)->30. */
48 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
49 dist = period / 4;
50 }
51}
52#endif
diff --git a/arch/sh/boards/harp/mach.c b/arch/sh/boards/harp/mach.c
new file mode 100644
index 000000000000..a946dd1674ca
--- /dev/null
+++ b/arch/sh/boards/harp/mach.c
@@ -0,0 +1,62 @@
1/*
2 * linux/arch/sh/boards/harp/mach.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the STMicroelectronics STB1 HARP and compatible boards
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17#include <asm/hd64465/io.h>
18#include <asm/hd64465/hd64465.h>
19
20void setup_harp(void);
21void init_harp_irq(void);
22void heartbeat_harp(void);
23
24/*
25 * The Machine Vector
26 */
27
28struct sh_machine_vector mv_harp __initmv = {
29 .mv_nr_irqs = 89 + HD64465_IRQ_NUM,
30
31 .mv_inb = hd64465_inb,
32 .mv_inw = hd64465_inw,
33 .mv_inl = hd64465_inl,
34 .mv_outb = hd64465_outb,
35 .mv_outw = hd64465_outw,
36 .mv_outl = hd64465_outl,
37
38 .mv_inb_p = hd64465_inb_p,
39 .mv_inw_p = hd64465_inw,
40 .mv_inl_p = hd64465_inl,
41 .mv_outb_p = hd64465_outb_p,
42 .mv_outw_p = hd64465_outw,
43 .mv_outl_p = hd64465_outl,
44
45 .mv_insb = hd64465_insb,
46 .mv_insw = hd64465_insw,
47 .mv_insl = hd64465_insl,
48 .mv_outsb = hd64465_outsb,
49 .mv_outsw = hd64465_outsw,
50 .mv_outsl = hd64465_outsl,
51
52 .mv_isa_port2addr = hd64465_isa_port2addr,
53
54#ifdef CONFIG_PCI
55 .mv_init_irq = init_harp_irq,
56#endif
57#ifdef CONFIG_HEARTBEAT
58 .mv_heartbeat = heartbeat_harp,
59#endif
60};
61
62ALIAS_MV(harp)
diff --git a/arch/sh/boards/harp/pcidma.c b/arch/sh/boards/harp/pcidma.c
new file mode 100644
index 000000000000..475311390fd6
--- /dev/null
+++ b/arch/sh/boards/harp/pcidma.c
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Dynamic DMA mapping support.
8 */
9
10#include <linux/types.h>
11#include <linux/mm.h>
12#include <linux/string.h>
13#include <linux/pci.h>
14#include <asm/io.h>
15#include <asm/addrspace.h>
16
17
18void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
19 dma_addr_t * dma_handle)
20{
21 void *ret;
22 int gfp = GFP_ATOMIC;
23
24 ret = (void *) __get_free_pages(gfp, get_order(size));
25
26 if (ret != NULL) {
27 /* Is it neccessary to do the memset? */
28 memset(ret, 0, size);
29 *dma_handle = virt_to_bus(ret);
30 }
31 /* We must flush the cache before we pass it on to the device */
32 flush_cache_all();
33 return P2SEGADDR(ret);
34}
35
36void pci_free_consistent(struct pci_dev *hwdev, size_t size,
37 void *vaddr, dma_addr_t dma_handle)
38{
39 unsigned long p1addr=P1SEGADDR((unsigned long)vaddr);
40
41 free_pages(p1addr, get_order(size));
42}
diff --git a/arch/sh/boards/harp/setup.c b/arch/sh/boards/harp/setup.c
new file mode 100644
index 000000000000..05b01b8f40aa
--- /dev/null
+++ b/arch/sh/boards/harp/setup.c
@@ -0,0 +1,91 @@
1/*
2 * arch/sh/stboard/setup.c
3 *
4 * Copyright (C) 2001 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * STMicroelectronics ST40STB1 HARP and compatible support.
10 */
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <asm/io.h>
16#include <asm/harp/harp.h>
17
18const char *get_system_type(void)
19{
20 return "STB1 Harp";
21}
22
23/*
24 * Initialize the board
25 */
26int __init platform_setup(void)
27{
28#ifdef CONFIG_SH_STB1_HARP
29 unsigned long ic8_version, ic36_version;
30
31 ic8_version = ctrl_inl(EPLD_REVID2);
32 ic36_version = ctrl_inl(EPLD_REVID1);
33
34 printk("STMicroelectronics STB1 HARP initialisaton\n");
35 printk("EPLD versions: IC8: %d.%02d, IC36: %d.%02d\n",
36 (ic8_version >> 4) & 0xf, ic8_version & 0xf,
37 (ic36_version >> 4) & 0xf, ic36_version & 0xf);
38#elif defined(CONFIG_SH_STB1_OVERDRIVE)
39 unsigned long version;
40
41 version = ctrl_inl(EPLD_REVID);
42
43 printk("STMicroelectronics STB1 Overdrive initialisaton\n");
44 printk("EPLD version: %d.%02d\n",
45 (version >> 4) & 0xf, version & 0xf);
46#else
47#error Undefined machine
48#endif
49
50 /* Currently all STB1 chips have problems with the sleep instruction,
51 * so disable it here.
52 */
53 disable_hlt();
54
55 return 0;
56}
57
58/*
59 * pcibios_map_platform_irq
60 *
61 * This is board specific and returns the IRQ for a given PCI device.
62 * It is used by the PCI code (arch/sh/kernel/st40_pci*)
63 *
64 */
65
66#define HARP_PCI_IRQ 1
67#define HARP_BRIDGE_IRQ 2
68#define OVERDRIVE_SLOT0_IRQ 0
69
70
71int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
72{
73 switch (slot) {
74#ifdef CONFIG_SH_STB1_HARP
75 case 2: /*This is the PCI slot on the */
76 return HARP_PCI_IRQ;
77 case 1: /* this is the bridge */
78 return HARP_BRIDGE_IRQ;
79#elif defined(CONFIG_SH_STB1_OVERDRIVE)
80 case 1:
81 case 2:
82 case 3:
83 return slot - 1;
84#else
85#error Unknown board
86#endif
87 default:
88 return -1;
89 }
90}
91
diff --git a/arch/sh/boards/hp6xx/hp620/Makefile b/arch/sh/boards/hp6xx/hp620/Makefile
new file mode 100644
index 000000000000..20691dbce347
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp620/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the HP620 specific parts of the kernel
3#
4
5obj-y := mach.o setup.o
6
diff --git a/arch/sh/boards/hp6xx/hp620/mach.c b/arch/sh/boards/hp6xx/hp620/mach.c
new file mode 100644
index 000000000000..0392d82b4a7b
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp620/mach.c
@@ -0,0 +1,52 @@
1/*
2 * linux/arch/sh/boards/hp6xx/hp620/mach.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the HP620
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17
18#include <asm/io.h>
19#include <asm/hd64461/hd64461.h>
20#include <asm/irq.h>
21
22/*
23 * The Machine Vector
24 */
25
26struct sh_machine_vector mv_hp620 __initmv = {
27 .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM,
28
29 .mv_inb = hd64461_inb,
30 .mv_inw = hd64461_inw,
31 .mv_inl = hd64461_inl,
32 .mv_outb = hd64461_outb,
33 .mv_outw = hd64461_outw,
34 .mv_outl = hd64461_outl,
35
36 .mv_inb_p = hd64461_inb_p,
37 .mv_inw_p = hd64461_inw,
38 .mv_inl_p = hd64461_inl,
39 .mv_outb_p = hd64461_outb_p,
40 .mv_outw_p = hd64461_outw,
41 .mv_outl_p = hd64461_outl,
42
43 .mv_insb = hd64461_insb,
44 .mv_insw = hd64461_insw,
45 .mv_insl = hd64461_insl,
46 .mv_outsb = hd64461_outsb,
47 .mv_outsw = hd64461_outsw,
48 .mv_outsl = hd64461_outsl,
49
50 .mv_irq_demux = hd64461_irq_demux,
51};
52ALIAS_MV(hp620)
diff --git a/arch/sh/boards/hp6xx/hp620/setup.c b/arch/sh/boards/hp6xx/hp620/setup.c
new file mode 100644
index 000000000000..045fc5da7274
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp620/setup.c
@@ -0,0 +1,45 @@
1/*
2 * linux/arch/sh/boards/hp6xx/hp620/setup.c
3 *
4 * Copyright (C) 2002 Andriy Skulysh, 2005 Kristoffer Ericson
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See Linux/COPYING for more information.
8 *
9 * Setup code for an HP620.
10 * Due to similiarity with hp680/hp690 same inits are done (for now)
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <asm/hd64461/hd64461.h>
16#include <asm/io.h>
17#include <asm/hp6xx/hp6xx.h>
18#include <asm/cpu/dac.h>
19
20const char *get_system_type(void)
21{
22 return "HP620";
23}
24
25int __init platform_setup(void)
26{
27 u16 v;
28
29 v = inw(HD64461_STBCR);
30 v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
31 HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
32 HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST |
33 HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST |
34 HD64461_STBCR_SAFECKE_IST;
35 outw(v, HD64461_STBCR);
36
37 v = inw(HD64461_GPADR);
38 v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
39 outw(v, HD64461_GPADR);
40
41 sh_dac_disable(DAC_SPEAKER_VOLUME);
42
43 return 0;
44}
45
diff --git a/arch/sh/boards/hp6xx/hp680/Makefile b/arch/sh/boards/hp6xx/hp680/Makefile
new file mode 100644
index 000000000000..0beef11d9b11
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp680/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the HP680 specific parts of the kernel
3#
4
5obj-y := mach.o setup.o
6
diff --git a/arch/sh/boards/hp6xx/hp680/mach.c b/arch/sh/boards/hp6xx/hp680/mach.c
new file mode 100644
index 000000000000..d73486136045
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp680/mach.c
@@ -0,0 +1,53 @@
1/*
2 * linux/arch/sh/boards/hp6xx/hp680/mach.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the HP680
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17
18#include <asm/io.h>
19#include <asm/hd64461/hd64461.h>
20#include <asm/hp6xx/io.h>
21#include <asm/irq.h>
22
23struct sh_machine_vector mv_hp680 __initmv = {
24 .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM,
25
26 .mv_inb = hd64461_inb,
27 .mv_inw = hd64461_inw,
28 .mv_inl = hd64461_inl,
29 .mv_outb = hd64461_outb,
30 .mv_outw = hd64461_outw,
31 .mv_outl = hd64461_outl,
32
33 .mv_inb_p = hd64461_inb_p,
34 .mv_inw_p = hd64461_inw,
35 .mv_inl_p = hd64461_inl,
36 .mv_outb_p = hd64461_outb_p,
37 .mv_outw_p = hd64461_outw,
38 .mv_outl_p = hd64461_outl,
39
40 .mv_insb = hd64461_insb,
41 .mv_insw = hd64461_insw,
42 .mv_insl = hd64461_insl,
43 .mv_outsb = hd64461_outsb,
44 .mv_outsw = hd64461_outsw,
45 .mv_outsl = hd64461_outsl,
46
47 .mv_readw = hd64461_readw,
48 .mv_writew = hd64461_writew,
49
50 .mv_irq_demux = hd64461_irq_demux,
51};
52
53ALIAS_MV(hp680)
diff --git a/arch/sh/boards/hp6xx/hp680/setup.c b/arch/sh/boards/hp6xx/hp680/setup.c
new file mode 100644
index 000000000000..4170190f2644
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp680/setup.c
@@ -0,0 +1,41 @@
1/*
2 * linux/arch/sh/boards/hp6xx/hp680/setup.c
3 *
4 * Copyright (C) 2002 Andriy Skulysh
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Setup code for an HP680 (internal peripherials only)
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <asm/hd64461/hd64461.h>
15#include <asm/io.h>
16#include <asm/hp6xx/hp6xx.h>
17#include <asm/cpu/dac.h>
18
19const char *get_system_type(void)
20{
21 return "HP680";
22}
23
24int __init platform_setup(void)
25{
26 u16 v;
27 v = inw(HD64461_STBCR);
28 v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
29 HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
30 HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST |
31 HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST |
32 HD64461_STBCR_SAFECKE_IST;
33 outw(v, HD64461_STBCR);
34 v = inw(HD64461_GPADR);
35 v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0;
36 outw(v, HD64461_GPADR);
37
38 sh_dac_disable(DAC_SPEAKER_VOLUME);
39
40 return 0;
41}
diff --git a/arch/sh/boards/hp6xx/hp690/Makefile b/arch/sh/boards/hp6xx/hp690/Makefile
new file mode 100644
index 000000000000..fbbe95e75f83
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp690/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the HP690 specific parts of the kernel
3#
4
5obj-y := mach.o
6
diff --git a/arch/sh/boards/hp6xx/hp690/mach.c b/arch/sh/boards/hp6xx/hp690/mach.c
new file mode 100644
index 000000000000..2a4c68783cd6
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp690/mach.c
@@ -0,0 +1,48 @@
1/*
2 * linux/arch/sh/boards/hp6xx/hp690/mach.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the HP690
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17
18#include <asm/io.h>
19#include <asm/hd64461/hd64461.h>
20#include <asm/irq.h>
21
22struct sh_machine_vector mv_hp690 __initmv = {
23 .mv_nr_irqs = HD64461_IRQBASE+HD64461_IRQ_NUM,
24
25 .mv_inb = hd64461_inb,
26 .mv_inw = hd64461_inw,
27 .mv_inl = hd64461_inl,
28 .mv_outb = hd64461_outb,
29 .mv_outw = hd64461_outw,
30 .mv_outl = hd64461_outl,
31
32 .mv_inb_p = hd64461_inb_p,
33 .mv_inw_p = hd64461_inw,
34 .mv_inl_p = hd64461_inl,
35 .mv_outb_p = hd64461_outb_p,
36 .mv_outw_p = hd64461_outw,
37 .mv_outl_p = hd64461_outl,
38
39 .mv_insb = hd64461_insb,
40 .mv_insw = hd64461_insw,
41 .mv_insl = hd64461_insl,
42 .mv_outsb = hd64461_outsb,
43 .mv_outsw = hd64461_outsw,
44 .mv_outsl = hd64461_outsl,
45
46 .mv_irq_demux = hd64461_irq_demux,
47};
48ALIAS_MV(hp690)
diff --git a/arch/sh/boards/mpc1211/Makefile b/arch/sh/boards/mpc1211/Makefile
new file mode 100644
index 000000000000..1644ebed78cb
--- /dev/null
+++ b/arch/sh/boards/mpc1211/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the Interface (CTP/PCI/MPC-SH02) specific parts of the kernel
3#
4
5obj-y := setup.o rtc.o led.o
6
7obj-$(CONFIG_PCI) += pci.o
8
diff --git a/arch/sh/boards/mpc1211/led.c b/arch/sh/boards/mpc1211/led.c
new file mode 100644
index 000000000000..0a31beec3465
--- /dev/null
+++ b/arch/sh/boards/mpc1211/led.c
@@ -0,0 +1,64 @@
1/*
2 * linux/arch/sh/kernel/led_mpc1211.c
3 *
4 * Copyright (C) 2001 Saito.K & Jeanne
5 *
6 * This file contains Interface MPC-1211 specific LED code.
7 */
8
9#include <linux/config.h>
10
11static void mach_led(int position, int value)
12{
13 volatile unsigned char* p = (volatile unsigned char*)0xa2000000;
14
15 if (value) {
16 *p |= 1;
17 } else {
18 *p &= ~1;
19 }
20}
21
22#ifdef CONFIG_HEARTBEAT
23
24#include <linux/sched.h>
25
26/* Cycle the LED's in the clasic Knightrider/Sun pattern */
27void heartbeat_mpc1211(void)
28{
29 static unsigned int cnt = 0, period = 0;
30 volatile unsigned char* p = (volatile unsigned char*)0xa2000000;
31 static unsigned bit = 0, up = 1;
32
33 cnt += 1;
34 if (cnt < period) {
35 return;
36 }
37
38 cnt = 0;
39
40 /* Go through the points (roughly!):
41 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
42 */
43 period = 110 - ( (300<<FSHIFT)/
44 ((avenrun[0]/5) + (3<<FSHIFT)) );
45
46 if (up) {
47 if (bit == 7) {
48 bit--;
49 up=0;
50 } else {
51 bit ++;
52 }
53 } else {
54 if (bit == 0) {
55 bit++;
56 up=1;
57 } else {
58 bit--;
59 }
60 }
61 *p = 1<<bit;
62
63}
64#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/mpc1211/pci.c b/arch/sh/boards/mpc1211/pci.c
new file mode 100644
index 000000000000..ba3a65439752
--- /dev/null
+++ b/arch/sh/boards/mpc1211/pci.c
@@ -0,0 +1,296 @@
1/*
2 * Low-Level PCI Support for the MPC-1211(CTP/PCI/MPC-SH02)
3 *
4 * (c) 2002-2003 Saito.K & Jeanne
5 *
6 * Dustin McIntire (dustin@sensoria.com)
7 * Derived from arch/i386/kernel/pci-*.c which bore the message:
8 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 *
13 */
14#include <linux/config.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20#include <linux/sched.h>
21#include <linux/ioport.h>
22#include <linux/errno.h>
23#include <linux/irq.h>
24#include <linux/interrupt.h>
25
26#include <asm/machvec.h>
27#include <asm/io.h>
28#include <asm/mpc1211/pci.h>
29
30static struct resource mpcpci_io_resource = {
31 "MPCPCI IO",
32 0x00000000,
33 0xffffffff,
34 IORESOURCE_IO
35};
36
37static struct resource mpcpci_mem_resource = {
38 "MPCPCI mem",
39 0x00000000,
40 0xffffffff,
41 IORESOURCE_MEM
42};
43
44static struct pci_ops pci_direct_conf1;
45struct pci_channel board_pci_channels[] = {
46 {&pci_direct_conf1, &mpcpci_io_resource, &mpcpci_mem_resource, 0, 256},
47 {NULL, NULL, NULL, 0, 0},
48};
49
50/*
51 * Direct access to PCI hardware...
52 */
53
54
55#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
56
57/*
58 * Functions for accessing PCI configuration space with type 1 accesses
59 */
60static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
61{
62 u32 word;
63 unsigned long flags;
64
65 /*
66 * PCIPDR may only be accessed as 32 bit words,
67 * so we must do byte alignment by hand
68 */
69 local_irq_save(flags);
70 writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
71 word = readl(PCIPDR);
72 local_irq_restore(flags);
73
74 switch (size) {
75 case 1:
76 switch (where & 0x3) {
77 case 3:
78 *value = (u8)(word >> 24);
79 break;
80 case 2:
81 *value = (u8)(word >> 16);
82 break;
83 case 1:
84 *value = (u8)(word >> 8);
85 break;
86 default:
87 *value = (u8)word;
88 break;
89 }
90 break;
91 case 2:
92 switch (where & 0x3) {
93 case 3:
94 *value = (u16)(word >> 24);
95 local_irq_save(flags);
96 writel(CONFIG_CMD(bus,devfn,(where+1)), PCIPAR);
97 word = readl(PCIPDR);
98 local_irq_restore(flags);
99 *value |= ((word & 0xff) << 8);
100 break;
101 case 2:
102 *value = (u16)(word >> 16);
103 break;
104 case 1:
105 *value = (u16)(word >> 8);
106 break;
107 default:
108 *value = (u16)word;
109 break;
110 }
111 break;
112 case 4:
113 *value = word;
114 break;
115 }
116 PCIDBG(4,"pci_conf1_read@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),*value);
117 return PCIBIOS_SUCCESSFUL;
118}
119
120/*
121 * Since MPC-1211 only does 32bit access we'll have to do a read,mask,write operation.
122 * We'll allow an odd byte offset, though it should be illegal.
123 */
124static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
125{
126 u32 word,mask = 0;
127 unsigned long flags;
128 u32 shift = (where & 3) * 8;
129
130 if(size == 1) {
131 mask = ((1 << 8) - 1) << shift; // create the byte mask
132 } else if(size == 2){
133 if(shift == 24)
134 return PCIBIOS_BAD_REGISTER_NUMBER;
135 mask = ((1 << 16) - 1) << shift; // create the word mask
136 }
137 local_irq_save(flags);
138 writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
139 if(size == 4){
140 writel(value, PCIPDR);
141 local_irq_restore(flags);
142 PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),value);
143 return PCIBIOS_SUCCESSFUL;
144 }
145 word = readl(PCIPDR);
146 word &= ~mask;
147 word |= ((value << shift) & mask);
148 writel(word, PCIPDR);
149 local_irq_restore(flags);
150 PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),word);
151 return PCIBIOS_SUCCESSFUL;
152}
153
154#undef CONFIG_CMD
155
156static struct pci_ops pci_direct_conf1 = {
157 .read = pci_conf1_read,
158 .write = pci_conf1_write,
159};
160
161static void __devinit quirk_ali_ide_ports(struct pci_dev *dev)
162{
163 dev->resource[0].start = 0x1f0;
164 dev->resource[0].end = 0x1f7;
165 dev->resource[0].flags = IORESOURCE_IO;
166 dev->resource[1].start = 0x3f6;
167 dev->resource[1].end = 0x3f6;
168 dev->resource[1].flags = IORESOURCE_IO;
169 dev->resource[2].start = 0x170;
170 dev->resource[2].end = 0x177;
171 dev->resource[2].flags = IORESOURCE_IO;
172 dev->resource[3].start = 0x376;
173 dev->resource[3].end = 0x376;
174 dev->resource[3].flags = IORESOURCE_IO;
175 dev->resource[4].start = 0xf000;
176 dev->resource[4].end = 0xf00f;
177 dev->resource[4].flags = IORESOURCE_IO;
178}
179DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_ports);
180
181char * __devinit pcibios_setup(char *str)
182{
183 return str;
184}
185
186/*
187 * Called after each bus is probed, but before its children
188 * are examined.
189 */
190
191void __init pcibios_fixup_bus(struct pci_bus *b)
192{
193 pci_read_bridge_bases(b);
194}
195
196/*
197 * IRQ functions
198 */
199static inline u8 bridge_swizzle(u8 pin, u8 slot)
200{
201 return (((pin-1) + slot) % 4) + 1;
202}
203
204static inline u8 bridge_swizzle_pci_1(u8 pin, u8 slot)
205{
206 return (((pin-1) - slot) & 3) + 1;
207}
208
209static u8 __init mpc1211_swizzle(struct pci_dev *dev, u8 *pinp)
210{
211 unsigned long flags;
212 u8 pin = *pinp;
213 u32 word;
214
215 for ( ; dev->bus->self; dev = dev->bus->self) {
216 if (!pin)
217 continue;
218
219 if (dev->bus->number == 1) {
220 local_irq_save(flags);
221 writel(0x80000000 | 0x2c, PCIPAR);
222 word = readl(PCIPDR);
223 local_irq_restore(flags);
224 word >>= 16;
225
226 if (word == 0x0001)
227 pin = bridge_swizzle_pci_1(pin, PCI_SLOT(dev->devfn));
228 else
229 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
230 } else
231 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
232 }
233
234 *pinp = pin;
235
236 return PCI_SLOT(dev->devfn);
237}
238
239static int __init map_mpc1211_irq(struct pci_dev *dev, u8 slot, u8 pin)
240{
241 int irq = -1;
242
243 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
244 if (dev->bus->number == 0) {
245 switch (slot) {
246 case 13: irq = 9; break; /* USB */
247 case 22: irq = 10; break; /* LAN */
248 default: irq = 0; break;
249 }
250 } else {
251 switch (pin) {
252 case 0: irq = 0; break;
253 case 1: irq = 7; break;
254 case 2: irq = 9; break;
255 case 3: irq = 10; break;
256 case 4: irq = 11; break;
257 }
258 }
259
260 if( irq < 0 ) {
261 PCIDBG(3, "PCI: Error mapping IRQ on device %s\n", pci_name(dev));
262 return irq;
263 }
264
265 PCIDBG(2, "Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
266
267 return irq;
268}
269
270void __init pcibios_fixup_irqs(void)
271{
272 pci_fixup_irqs(mpc1211_swizzle, map_mpc1211_irq);
273}
274
275void pcibios_align_resource(void *data, struct resource *res,
276 unsigned long size, unsigned long align)
277{
278 unsigned long start = res->start;
279
280 if (res->flags & IORESOURCE_IO) {
281 if (start >= 0x10000UL) {
282 if ((start & 0xffffUL) < 0x4000UL) {
283 start = (start & 0xffff0000UL) + 0x4000UL;
284 } else if ((start & 0xffffUL) >= 0xf000UL) {
285 start = (start & 0xffff0000UL) + 0x10000UL;
286 }
287 res->start = start;
288 } else {
289 if (start & 0x300) {
290 start = (start + 0x3ff) & ~0x3ff;
291 res->start = start;
292 }
293 }
294 }
295}
296
diff --git a/arch/sh/boards/mpc1211/rtc.c b/arch/sh/boards/mpc1211/rtc.c
new file mode 100644
index 000000000000..4d100f048072
--- /dev/null
+++ b/arch/sh/boards/mpc1211/rtc.c
@@ -0,0 +1,152 @@
1/*
2 * linux/arch/sh/kernel/rtc-mpc1211.c -- MPC-1211 on-chip RTC support
3 *
4 * Copyright (C) 2002 Saito.K & Jeanne
5 *
6 */
7
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/time.h>
12#include <linux/mc146818rtc.h>
13
14#ifndef BCD_TO_BIN
15#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
16#endif
17
18#ifndef BIN_TO_BCD
19#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
20#endif
21
22/* arc/i386/kernel/time.c */
23unsigned long get_cmos_time(void)
24{
25 unsigned int year, mon, day, hour, min, sec;
26 int i;
27
28 spin_lock(&rtc_lock);
29 /* The Linux interpretation of the CMOS clock register contents:
30 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
31 * RTC registers show the second which has precisely just started.
32 * Let's hope other operating systems interpret the RTC the same way.
33 */
34 /* read RTC exactly on falling edge of update flag */
35 for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
36 if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
37 break;
38 for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
39 if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
40 break;
41 do { /* Isn't this overkill ? UIP above should guarantee consistency */
42 sec = CMOS_READ(RTC_SECONDS);
43 min = CMOS_READ(RTC_MINUTES);
44 hour = CMOS_READ(RTC_HOURS);
45 day = CMOS_READ(RTC_DAY_OF_MONTH);
46 mon = CMOS_READ(RTC_MONTH);
47 year = CMOS_READ(RTC_YEAR);
48 } while (sec != CMOS_READ(RTC_SECONDS));
49 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
50 {
51 BCD_TO_BIN(sec);
52 BCD_TO_BIN(min);
53 BCD_TO_BIN(hour);
54 BCD_TO_BIN(day);
55 BCD_TO_BIN(mon);
56 BCD_TO_BIN(year);
57 }
58 spin_unlock(&rtc_lock);
59 if ((year += 1900) < 1970)
60 year += 100;
61 return mktime(year, mon, day, hour, min, sec);
62}
63
64void mpc1211_rtc_gettimeofday(struct timeval *tv)
65{
66
67 tv->tv_sec = get_cmos_time();
68 tv->tv_usec = 0;
69}
70
71/* arc/i386/kernel/time.c */
72/*
73 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
74 * called 500 ms after the second nowtime has started, because when
75 * nowtime is written into the registers of the CMOS clock, it will
76 * jump to the next second precisely 500 ms later. Check the Motorola
77 * MC146818A or Dallas DS12887 data sheet for details.
78 *
79 * BUG: This routine does not handle hour overflow properly; it just
80 * sets the minutes. Usually you'll only notice that after reboot!
81 */
82static int set_rtc_mmss(unsigned long nowtime)
83{
84 int retval = 0;
85 int real_seconds, real_minutes, cmos_minutes;
86 unsigned char save_control, save_freq_select;
87
88 /* gets recalled with irq locally disabled */
89 spin_lock(&rtc_lock);
90 save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
91 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
92
93 save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
94 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
95
96 cmos_minutes = CMOS_READ(RTC_MINUTES);
97 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
98 BCD_TO_BIN(cmos_minutes);
99
100 /*
101 * since we're only adjusting minutes and seconds,
102 * don't interfere with hour overflow. This avoids
103 * messing with unknown time zones but requires your
104 * RTC not to be off by more than 15 minutes
105 */
106 real_seconds = nowtime % 60;
107 real_minutes = nowtime / 60;
108 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
109 real_minutes += 30; /* correct for half hour time zone */
110 real_minutes %= 60;
111
112 if (abs(real_minutes - cmos_minutes) < 30) {
113 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
114 BIN_TO_BCD(real_seconds);
115 BIN_TO_BCD(real_minutes);
116 }
117 CMOS_WRITE(real_seconds,RTC_SECONDS);
118 CMOS_WRITE(real_minutes,RTC_MINUTES);
119 } else {
120 printk(KERN_WARNING
121 "set_rtc_mmss: can't update from %d to %d\n",
122 cmos_minutes, real_minutes);
123 retval = -1;
124 }
125
126 /* The following flags have to be released exactly in this order,
127 * otherwise the DS12887 (popular MC146818A clone with integrated
128 * battery and quartz) will not reset the oscillator and will not
129 * update precisely 500 ms later. You won't find this mentioned in
130 * the Dallas Semiconductor data sheets, but who believes data
131 * sheets anyway ... -- Markus Kuhn
132 */
133 CMOS_WRITE(save_control, RTC_CONTROL);
134 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
135 spin_unlock(&rtc_lock);
136
137 return retval;
138}
139
140int mpc1211_rtc_settimeofday(const struct timeval *tv)
141{
142 unsigned long nowtime = tv->tv_sec;
143
144 return set_rtc_mmss(nowtime);
145}
146
147void mpc1211_time_init(void)
148{
149 rtc_get_time = mpc1211_rtc_gettimeofday;
150 rtc_set_time = mpc1211_rtc_settimeofday;
151}
152
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c
new file mode 100644
index 000000000000..2bb581b91683
--- /dev/null
+++ b/arch/sh/boards/mpc1211/setup.c
@@ -0,0 +1,360 @@
1/*
2 * linux/arch/sh/board/mpc1211/setup.c
3 *
4 * Copyright (C) 2002 Saito.K & Jeanne, Fujii.Y
5 *
6 */
7
8#include <linux/config.h>
9#include <linux/init.h>
10#include <linux/irq.h>
11#include <linux/hdreg.h>
12#include <linux/ide.h>
13#include <linux/interrupt.h>
14
15#include <asm/io.h>
16#include <asm/machvec.h>
17#include <asm/mpc1211/mpc1211.h>
18#include <asm/mpc1211/pci.h>
19#include <asm/mpc1211/m1543c.h>
20
21
22/* ALI15X3 SMBus address offsets */
23#define SMBHSTSTS (0 + 0x3100)
24#define SMBHSTCNT (1 + 0x3100)
25#define SMBHSTSTART (2 + 0x3100)
26#define SMBHSTCMD (7 + 0x3100)
27#define SMBHSTADD (3 + 0x3100)
28#define SMBHSTDAT0 (4 + 0x3100)
29#define SMBHSTDAT1 (5 + 0x3100)
30#define SMBBLKDAT (6 + 0x3100)
31
32/* Other settings */
33#define MAX_TIMEOUT 500 /* times 1/100 sec */
34
35/* ALI15X3 command constants */
36#define ALI15X3_ABORT 0x04
37#define ALI15X3_T_OUT 0x08
38#define ALI15X3_QUICK 0x00
39#define ALI15X3_BYTE 0x10
40#define ALI15X3_BYTE_DATA 0x20
41#define ALI15X3_WORD_DATA 0x30
42#define ALI15X3_BLOCK_DATA 0x40
43#define ALI15X3_BLOCK_CLR 0x80
44
45/* ALI15X3 status register bits */
46#define ALI15X3_STS_IDLE 0x04
47#define ALI15X3_STS_BUSY 0x08
48#define ALI15X3_STS_DONE 0x10
49#define ALI15X3_STS_DEV 0x20 /* device error */
50#define ALI15X3_STS_COLL 0x40 /* collision or no response */
51#define ALI15X3_STS_TERM 0x80 /* terminated by abort */
52#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */
53
54const char *get_system_type(void)
55{
56 return "Interface MPC-1211(CTP/PCI/MPC-SH02)";
57}
58
59static void __init pci_write_config(unsigned long busNo,
60 unsigned long devNo,
61 unsigned long fncNo,
62 unsigned long cnfAdd,
63 unsigned long cnfData)
64{
65 ctrl_outl((0x80000000
66 + ((busNo & 0xff) << 16)
67 + ((devNo & 0x1f) << 11)
68 + ((fncNo & 0x07) << 8)
69 + (cnfAdd & 0xfc)), PCIPAR);
70
71 ctrl_outl(cnfData, PCIPDR);
72}
73
74/*
75 Initialize IRQ setting
76*/
77
78static unsigned char m_irq_mask = 0xfb;
79static unsigned char s_irq_mask = 0xff;
80volatile unsigned long irq_err_count;
81
82static void disable_mpc1211_irq(unsigned int irq)
83{
84 unsigned long flags;
85
86 save_and_cli(flags);
87 if( irq < 8) {
88 m_irq_mask |= (1 << irq);
89 outb(m_irq_mask,I8259_M_MR);
90 } else {
91 s_irq_mask |= (1 << (irq - 8));
92 outb(s_irq_mask,I8259_S_MR);
93 }
94 restore_flags(flags);
95
96}
97
98static void enable_mpc1211_irq(unsigned int irq)
99{
100 unsigned long flags;
101
102 save_and_cli(flags);
103
104 if( irq < 8) {
105 m_irq_mask &= ~(1 << irq);
106 outb(m_irq_mask,I8259_M_MR);
107 } else {
108 s_irq_mask &= ~(1 << (irq - 8));
109 outb(s_irq_mask,I8259_S_MR);
110 }
111 restore_flags(flags);
112}
113
114static inline int mpc1211_irq_real(unsigned int irq)
115{
116 int value;
117 int irqmask;
118
119 if ( irq < 8) {
120 irqmask = 1<<irq;
121 outb(0x0b,I8259_M_CR); /* ISR register */
122 value = inb(I8259_M_CR) & irqmask;
123 outb(0x0a,I8259_M_CR); /* back ro the IPR reg */
124 return value;
125 }
126 irqmask = 1<<(irq - 8);
127 outb(0x0b,I8259_S_CR); /* ISR register */
128 value = inb(I8259_S_CR) & irqmask;
129 outb(0x0a,I8259_S_CR); /* back ro the IPR reg */
130 return value;
131}
132
133static void mask_and_ack_mpc1211(unsigned int irq)
134{
135 unsigned long flags;
136
137 save_and_cli(flags);
138
139 if(irq < 8) {
140 if(m_irq_mask & (1<<irq)){
141 if(!mpc1211_irq_real(irq)){
142 irq_err_count++;
143 printk("spurious 8259A interrupt: IRQ %x\n",irq);
144 }
145 } else {
146 m_irq_mask |= (1<<irq);
147 }
148 inb(I8259_M_MR); /* DUMMY */
149 outb(m_irq_mask,I8259_M_MR); /* disable */
150 outb(0x60+irq,I8259_M_CR); /* EOI */
151
152 } else {
153 if(s_irq_mask & (1<<(irq - 8))){
154 if(!mpc1211_irq_real(irq)){
155 irq_err_count++;
156 printk("spurious 8259A interrupt: IRQ %x\n",irq);
157 }
158 } else {
159 s_irq_mask |= (1<<(irq - 8));
160 }
161 inb(I8259_S_MR); /* DUMMY */
162 outb(s_irq_mask,I8259_S_MR); /* disable */
163 outb(0x60+(irq-8),I8259_S_CR); /* EOI */
164 outb(0x60+2,I8259_M_CR);
165 }
166 restore_flags(flags);
167}
168
169static void end_mpc1211_irq(unsigned int irq)
170{
171 enable_mpc1211_irq(irq);
172}
173
174static unsigned int startup_mpc1211_irq(unsigned int irq)
175{
176 enable_mpc1211_irq(irq);
177 return 0;
178}
179
180static void shutdown_mpc1211_irq(unsigned int irq)
181{
182 disable_mpc1211_irq(irq);
183}
184
185static struct hw_interrupt_type mpc1211_irq_type = {
186 .typename = "MPC1211-IRQ",
187 .startup = startup_mpc1211_irq,
188 .shutdown = shutdown_mpc1211_irq,
189 .enable = enable_mpc1211_irq,
190 .disable = disable_mpc1211_irq,
191 .ack = mask_and_ack_mpc1211,
192 .end = end_mpc1211_irq
193};
194
195static void make_mpc1211_irq(unsigned int irq)
196{
197 irq_desc[irq].handler = &mpc1211_irq_type;
198 irq_desc[irq].status = IRQ_DISABLED;
199 irq_desc[irq].action = 0;
200 irq_desc[irq].depth = 1;
201 disable_mpc1211_irq(irq);
202}
203
204int mpc1211_irq_demux(int irq)
205{
206 unsigned int poll;
207
208 if( irq == 2 ) {
209 outb(0x0c,I8259_M_CR);
210 poll = inb(I8259_M_CR);
211 if(poll & 0x80) {
212 irq = (poll & 0x07);
213 }
214 if( irq == 2) {
215 outb(0x0c,I8259_S_CR);
216 poll = inb(I8259_S_CR);
217 irq = (poll & 0x07) + 8;
218 }
219 }
220 return irq;
221}
222
223void __init init_mpc1211_IRQ(void)
224{
225 int i;
226 /*
227 * Super I/O (Just mimic PC):
228 * 1: keyboard
229 * 3: serial 1
230 * 4: serial 0
231 * 5: printer
232 * 6: floppy
233 * 8: rtc
234 * 10: lan
235 * 12: mouse
236 * 14: ide0
237 * 15: ide1
238 */
239
240 pci_write_config(0,0,0,0x54, 0xb0b0002d);
241 outb(0x11, I8259_M_CR); /* mater icw1 edge trigger */
242 outb(0x11, I8259_S_CR); /* slave icw1 edge trigger */
243 outb(0x20, I8259_M_MR); /* m icw2 base vec 0x08 */
244 outb(0x28, I8259_S_MR); /* s icw2 base vec 0x70 */
245 outb(0x04, I8259_M_MR); /* m icw3 slave irq2 */
246 outb(0x02, I8259_S_MR); /* s icw3 slave id */
247 outb(0x01, I8259_M_MR); /* m icw4 non buf normal eoi*/
248 outb(0x01, I8259_S_MR); /* s icw4 non buf normal eo1*/
249 outb(0xfb, I8259_M_MR); /* disable irq0--irq7 */
250 outb(0xff, I8259_S_MR); /* disable irq8--irq15 */
251
252 for ( i=0; i < 16; i++) {
253 if(i != 2) {
254 make_mpc1211_irq(i);
255 }
256 }
257}
258
259/*
260 Initialize the board
261*/
262
263
264static void delay (void)
265{
266 volatile unsigned short tmp;
267 tmp = *(volatile unsigned short *) 0xa0000000;
268}
269
270static void delay1000 (void)
271{
272 int i;
273
274 for (i=0; i<1000; i++)
275 delay ();
276}
277
278static int put_smb_blk(unsigned char *p, int address, int command, int no)
279{
280 int temp;
281 int timeout;
282 int i;
283
284 outb(0xff, SMBHSTSTS);
285 temp = inb(SMBHSTSTS);
286 for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++) {
287 delay1000();
288 temp = inb(SMBHSTSTS);
289 }
290 if (timeout >= MAX_TIMEOUT){
291 return -1;
292 }
293
294 outb(((address & 0x7f) << 1), SMBHSTADD);
295 outb(0xc0, SMBHSTCNT);
296 outb(command & 0xff, SMBHSTCMD);
297 outb(no & 0x1f, SMBHSTDAT0);
298
299 for(i = 1; i <= no; i++) {
300 outb(*p++, SMBBLKDAT);
301 }
302 outb(0xff, SMBHSTSTART);
303
304 temp = inb(SMBHSTSTS);
305 for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) {
306 delay1000();
307 temp = inb(SMBHSTSTS);
308 }
309 if (timeout >= MAX_TIMEOUT) {
310 return -2;
311 }
312 if ( temp & ALI15X3_STS_ERR ){
313 return -3;
314 }
315 return 0;
316}
317
318/*
319 * The Machine Vector
320 */
321
322struct sh_machine_vector mv_mpc1211 __initmv = {
323 .mv_nr_irqs = 48,
324 .mv_irq_demux = mpc1211_irq_demux,
325 .mv_init_irq = init_mpc1211_IRQ,
326
327#ifdef CONFIG_HEARTBEAT
328 .mv_heartbeat = heartbeat_mpc1211,
329#endif
330};
331
332ALIAS_MV(mpc1211)
333
334/* arch/sh/boards/mpc1211/rtc.c */
335void mpc1211_time_init(void);
336
337int __init platform_setup(void)
338{
339 unsigned char spd_buf[128];
340
341 __set_io_port_base(PA_PCI_IO);
342
343 pci_write_config(0,0,0,0x54, 0xb0b00000);
344
345 do {
346 outb(ALI15X3_ABORT, SMBHSTCNT);
347 spd_buf[0] = 0x0c;
348 spd_buf[1] = 0x43;
349 spd_buf[2] = 0x7f;
350 spd_buf[3] = 0x03;
351 spd_buf[4] = 0x00;
352 spd_buf[5] = 0x03;
353 spd_buf[6] = 0x00;
354 } while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0);
355
356 board_time_init = mpc1211_time_init;
357
358 return 0;
359}
360
diff --git a/arch/sh/boards/overdrive/Makefile b/arch/sh/boards/overdrive/Makefile
new file mode 100644
index 000000000000..1762b59e9279
--- /dev/null
+++ b/arch/sh/boards/overdrive/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the STMicroelectronics Overdrive specific parts of the kernel
3#
4
5obj-y := mach.o setup.o io.o irq.o led.o time.o
6
7obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o
8
diff --git a/arch/sh/boards/overdrive/fpga.c b/arch/sh/boards/overdrive/fpga.c
new file mode 100644
index 000000000000..3a1ec9403441
--- /dev/null
+++ b/arch/sh/boards/overdrive/fpga.c
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file handles programming up the Altera Flex10K that interfaces to
8 * the Galileo, and does the PS/2 keyboard and mouse
9 *
10 */
11
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/smp.h>
16#include <linux/smp_lock.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/pci.h>
20#include <linux/delay.h>
21
22
23#include <asm/overdriver/gt64111.h>
24#include <asm/overdrive/overdrive.h>
25#include <asm/overdrive/fpga.h>
26
27#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT
28#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK
29
30/* I need to find out what (if any) the real delay factor here is */
31/* The delay is definately not critical */
32#define long_delay() {int i;for(i=0;i<10000;i++);}
33#define short_delay() {int i;for(i=0;i<100;i++);}
34
35static void __init program_overdrive_fpga(const unsigned char *fpgacode,
36 int size)
37{
38 int timeout = 0;
39 int i, j;
40 unsigned char b;
41 static volatile unsigned char *FPGA_ControlReg =
42 (volatile unsigned char *) (OVERDRIVE_CTRL);
43 static volatile unsigned char *FPGA_ProgramReg =
44 (volatile unsigned char *) (FPGA_DCLK_ADDRESS);
45
46 printk("FPGA: Commencing FPGA Programming\n");
47
48 /* The PCI reset but MUST be low when programming the FPGA !!! */
49 b = (*FPGA_ControlReg) & RESET_PCI_MASK;
50
51 (*FPGA_ControlReg) = b;
52
53 /* Prepare FPGA to program */
54
55 FPGA_NotConfigHigh();
56 long_delay();
57
58 FPGA_NotConfigLow();
59 short_delay();
60
61 while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) {
62 printk("FPGA: Waiting for NotStatus to go Low ... \n");
63 }
64
65 FPGA_NotConfigHigh();
66
67 /* Wait for FPGA "ready to be programmed" signal */
68 printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n");
69
70 for (timeout = 0;
71 (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0)
72 && (timeout < FPGA_TIMEOUT)); timeout++);
73
74 /* Check if timeout condition occured - i.e. an error */
75
76 if (timeout == FPGA_TIMEOUT) {
77 printk
78 ("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n");
79 return;
80 }
81
82 printk("FPGA: Copying data to FPGA ... %d bytes\n", size);
83
84 /* Copy array to FPGA - bit at a time */
85
86 for (i = 0; i < size; i++) {
87 volatile unsigned w = 0;
88
89 for (j = 0; j < 8; j++) {
90 *FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01;
91 short_delay();
92 }
93 if ((i & 0x3ff) == 0) {
94 printk(".");
95 }
96 }
97
98 /* Waiting for CONFDONE to go high - means the program is complete */
99
100 for (timeout = 0;
101 (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0)
102 && (timeout < FPGA_TIMEOUT)); timeout++) {
103
104 *FPGA_ProgramReg = 0x0;
105 long_delay();
106 }
107
108 if (timeout == FPGA_TIMEOUT) {
109 printk
110 ("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n");
111 return;
112 } else { /* Clock another 10 times - gets the device into a working state */
113 for (i = 0; i < 10; i++) {
114 *FPGA_ProgramReg = 0x0;
115 short_delay();
116 }
117 }
118
119 printk("FPGA: Programming complete\n");
120}
121
122
123static const unsigned char __init fpgacode[] = {
124#include "./overdrive.ttf" /* Code from maxplus2 compiler */
125 , 0, 0
126};
127
128
129int __init init_overdrive_fpga(void)
130{
131 program_overdrive_fpga(fpgacode, sizeof(fpgacode));
132
133 return 0;
134}
diff --git a/arch/sh/boards/overdrive/galileo.c b/arch/sh/boards/overdrive/galileo.c
new file mode 100644
index 000000000000..276fa11ee4ce
--- /dev/null
+++ b/arch/sh/boards/overdrive/galileo.c
@@ -0,0 +1,588 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file contains the PCI routines required for the Galileo GT6411
8 * PCI bridge as used on the Orion and Overdrive boards.
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20#include <linux/types.h>
21#include <linux/ioport.h>
22
23#include <asm/overdrive/overdrive.h>
24#include <asm/overdrive/gt64111.h>
25
26
27/* After boot, we shift the Galileo registers so that they appear
28 * in BANK6, along with IO space. This means we can have one contingous
29 * lump of PCI address space without these registers appearing in the
30 * middle of them
31 */
32
33#define GT64111_BASE_ADDRESS 0xbb000000
34#define GT64111_IO_BASE_ADDRESS 0x1000
35/* The GT64111 registers appear at this address to the SH4 after reset */
36#define RESET_GT64111_BASE_ADDRESS 0xb4000000
37
38/* Macros used to access the Galileo registers */
39#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x)
40#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x)
41
42#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x))
43
44#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x))
45
46#define GT_WRITE(x,v) writel((v),GT64111_REG(x))
47#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x))
48#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x))
49
50#define GT_READ(x) readl(GT64111_REG(x))
51#define GT_READ_BYTE(x) readb(GT64111_REG(x))
52#define GT_READ_SHORT(x) readw(GT64111_REG(x))
53
54
55/* Where the various SH banks start at */
56#define SH_BANK4_ADR 0xb0000000
57#define SH_BANK5_ADR 0xb4000000
58#define SH_BANK6_ADR 0xb8000000
59
60/* Masks out everything but lines 28,27,26 */
61#define BANK_SELECT_MASK 0x1c000000
62
63#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK)
64
65/*
66 * Masks used for address conversaion. Bank 6 is used for IO and
67 * has all the address bits zeroed by the FPGA. Special case this
68 */
69#define MEMORY_BANK_MASK 0x1fffffff
70#define IO_BANK_MASK 0x03ffffff
71
72/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code
73 * if you want
74 */
75#define IO_BANK_ADR PCI_GTIO_BASE
76
77/* Will select the correct mask to apply depending on the SH$ address */
78#define SELECT_BANK_MASK(x) \
79 ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK)
80
81/* Converts between PCI space and P2 region */
82#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x))
83
84/* Various macros for figuring out what to stick in the Galileo registers.
85 * You *really* don't want to figure this stuff out by hand, you always get
86 * it wrong
87 */
88#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff)
89#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f)
90#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff)
91
92#define PROGRAM_HI_LO(block,a,s) \
93 GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\
94 GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1))
95
96#define PROGRAM_SUB_HI_LO(block,a,s) \
97 GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\
98 GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1))
99
100/* We need to set the size, and the offset register */
101
102#define GT_BAR_MASK(x) ((x)&~0xfff)
103
104/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */
105#define PROGRAM_GT_BAR(block,a,s) \
106 GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\
107 write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\
108 GT_BAR_MASK(a))
109
110#define DISABLE_GT_BAR(block) \
111 GT_WRITE(PCI_##block##_BANK_SIZE,0),\
112 GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\
113 0x80000000)
114
115/* Macros to disable things we are not going to use */
116#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\
117 GT_WRITE(x##_HI_DEC_ADR,0x00)
118
119#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\
120 GT_WRITE(x##_HI_DEC_ADR,0x00)
121
122static void __init reset_pci(void)
123{
124 /* Set RESET_PCI bit high */
125 writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
126 udelay(250);
127
128 /* Set RESET_PCI bit low */
129 writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL);
130 udelay(250);
131
132 writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
133 udelay(250);
134}
135
136static int write_config_to_galileo(int where, u32 val);
137#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val)
138
139#define ENABLE_PCI_DRAM
140
141
142#ifdef TEST_DRAM
143/* Test function to check out if the PCI DRAM is working OK */
144static int /* __init */ test_dram(unsigned *base, unsigned size)
145{
146 unsigned *p = base;
147 unsigned *end = (unsigned *) (((unsigned) base) + size);
148 unsigned w;
149
150 for (p = base; p < end; p++) {
151 *p = 0xffffffff;
152 if (*p != 0xffffffff) {
153 printk("AAARGH -write failed!!! at %p is %x\n", p,
154 *p);
155 return 0;
156 }
157 *p = 0x0;
158 if (*p != 0x0) {
159 printk("AAARGH -write failed!!!\n");
160 return 0;
161 }
162 }
163
164 for (p = base; p < end; p++) {
165 *p = (unsigned) p;
166 if (*p != (unsigned) p) {
167 printk("Failed at 0x%p, actually is 0x%x\n", p,
168 *p);
169 return 0;
170 }
171 }
172
173 for (p = base; p < end; p++) {
174 w = ((unsigned) p & 0xffff0000);
175 *p = w | (w >> 16);
176 }
177
178 for (p = base; p < end; p++) {
179 w = ((unsigned) p & 0xffff0000);
180 w |= (w >> 16);
181 if (*p != w) {
182 printk
183 ("Failed at 0x%p, should be 0x%x actually is 0x%x\n",
184 p, w, *p);
185 return 0;
186 }
187 }
188
189 return 1;
190}
191#endif
192
193
194/* Function to set up and initialise the galileo. This sets up the BARS,
195 * maps the DRAM into the address space etc,etc
196 */
197int __init galileo_init(void)
198{
199 reset_pci();
200
201 /* Now shift the galileo regs into this block */
202 RESET_GT_WRITE(INTERNAL_SPACE_DEC,
203 GT_MEM_LO_ADR(GT64111_BASE_ADDRESS));
204
205 /* Should have a sanity check here, that you can read back at the new
206 * address what you just wrote
207 */
208
209 /* Disable decode for all regions */
210 DISABLE_DECODE(RAS10);
211 DISABLE_DECODE(RAS32);
212 DISABLE_DECODE(CS20);
213 DISABLE_DECODE(CS3);
214 DISABLE_DECODE(PCI_IO);
215 DISABLE_DECODE(PCI_MEM0);
216 DISABLE_DECODE(PCI_MEM1);
217
218 /* Disable all BARS */
219 GT_WRITE(BAR_ENABLE_ADR, 0x1ff);
220 DISABLE_GT_BAR(RAS10);
221 DISABLE_GT_BAR(RAS32);
222 DISABLE_GT_BAR(CS20);
223 DISABLE_GT_BAR(CS3);
224
225 /* Tell the BAR where the IO registers now are */
226 GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK(
227 (GT64111_IO_BASE_ADDRESS &
228 IO_BANK_MASK)));
229 /* set up a 112 Mb decode */
230 PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024);
231
232 /* Set up a 32 MB io space decode */
233 PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024);
234
235#ifdef ENABLE_PCI_DRAM
236 /* Program up the DRAM configuration - there is DRAM only in bank 0 */
237 /* Now set up the DRAM decode */
238 PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE);
239 /* And the sub decode */
240 PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE);
241
242 DISABLE_SUB_DECODE(RAS1);
243
244 /* Set refresh rate */
245 GT_WRITE(DRAM_BANK0_PARMS, 0x3f);
246 GT_WRITE(DRAM_CFG, 0x100);
247
248 /* we have to lob off the top bits rememeber!! */
249 PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE);
250
251#endif
252
253 /* We are only interested in decoding RAS10 and the Galileo's internal
254 * registers (as IO) on the PCI bus
255 */
256#ifdef ENABLE_PCI_DRAM
257 GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff);
258#else
259 GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff);
260#endif
261
262 /* Change the class code to host bridge, it actually powers up
263 * as a memory controller
264 */
265 GT_CONFIG_WRITE(8, 0x06000011);
266
267 /* Allow the galileo to master the PCI bus */
268 GT_CONFIG_WRITE(PCI_COMMAND,
269 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
270 PCI_COMMAND_IO);
271
272
273#if 0
274 printk("Testing PCI DRAM - ");
275 if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
276 printk("Passed\n");
277 }else {
278 printk("FAILED\n");
279 }
280#endif
281 return 0;
282
283}
284
285
286#define SET_CONFIG_BITS(bus,devfn,where)\
287 ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3))
288
289#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
290
291/* This write to the galileo config registers, unlike the functions below, can
292 * be used before the PCI subsystem has started up
293 */
294static int __init write_config_to_galileo(int where, u32 val)
295{
296 GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where));
297
298 GT_WRITE(PCI_CFG_DATA, val);
299 return 0;
300}
301
302/* We exclude the galileo and slot 31, the galileo because I don't know how to stop
303 * the setup code shagging up the setup I have done on it, and 31 because the whole
304 * thing locks up if you try to access that slot (which doesn't exist of course anyway
305 */
306
307#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31)))
308
309static int galileo_read_config_byte(struct pci_dev *dev, int where,
310 u8 * val)
311{
312
313
314 /* I suspect this doesn't work because this drives a special cycle ? */
315 if (EXCLUDED_DEV(dev)) {
316 *val = 0xff;
317 return PCIBIOS_SUCCESSFUL;
318 }
319 /* Start the config cycle */
320 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
321 /* Read back the result */
322 *val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3));
323
324 return PCIBIOS_SUCCESSFUL;
325}
326
327
328static int galileo_read_config_word(struct pci_dev *dev, int where,
329 u16 * val)
330{
331
332 if (EXCLUDED_DEV(dev)) {
333 *val = 0xffff;
334 return PCIBIOS_SUCCESSFUL;
335 }
336
337 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
338 *val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2));
339
340 return PCIBIOS_SUCCESSFUL;
341}
342
343
344static int galileo_read_config_dword(struct pci_dev *dev, int where,
345 u32 * val)
346{
347 if (EXCLUDED_DEV(dev)) {
348 *val = 0xffffffff;
349 return PCIBIOS_SUCCESSFUL;
350 }
351
352 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
353 *val = GT_READ(PCI_CFG_DATA);
354
355 return PCIBIOS_SUCCESSFUL;
356}
357
358static int galileo_write_config_byte(struct pci_dev *dev, int where,
359 u8 val)
360{
361 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
362
363 GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val);
364
365 return PCIBIOS_SUCCESSFUL;
366}
367
368
369static int galileo_write_config_word(struct pci_dev *dev, int where,
370 u16 val)
371{
372 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
373
374 GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val);
375
376 return PCIBIOS_SUCCESSFUL;
377}
378
379static int galileo_write_config_dword(struct pci_dev *dev, int where,
380 u32 val)
381{
382 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
383
384 GT_WRITE(PCI_CFG_DATA, val);
385
386 return PCIBIOS_SUCCESSFUL;
387}
388
389static struct pci_ops pci_config_ops = {
390 galileo_read_config_byte,
391 galileo_read_config_word,
392 galileo_read_config_dword,
393 galileo_write_config_byte,
394 galileo_write_config_word,
395 galileo_write_config_dword
396};
397
398
399/* Everything hangs off this */
400static struct pci_bus *pci_root_bus;
401
402
403static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
404{
405 return PCI_SLOT(dev->devfn);
406}
407
408static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin)
409{
410 /* Slot 1: Galileo
411 * Slot 2: PCI Slot 1
412 * Slot 3: PCI Slot 2
413 * Slot 4: ESS
414 */
415 switch (slot) {
416 case 2:
417 return OVERDRIVE_PCI_IRQ1;
418 case 3:
419 /* Note this assumes you have a hacked card in slot 2 */
420 return OVERDRIVE_PCI_IRQ2;
421 case 4:
422 return OVERDRIVE_ESS_IRQ;
423 default:
424 /* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */
425 return -1;
426 }
427}
428
429
430
431void __init
432pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
433{
434 ranges->io_start -= bus->resource[0]->start;
435 ranges->io_end -= bus->resource[0]->start;
436 ranges->mem_start -= bus->resource[1]->start;
437 ranges->mem_end -= bus->resource[1]->start;
438}
439
440static void __init pci_fixup_ide_bases(struct pci_dev *d)
441{
442 int i;
443
444 /*
445 * PCI IDE controllers use non-standard I/O port decoding, respect it.
446 */
447 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
448 return;
449 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
450 for(i=0; i<4; i++) {
451 struct resource *r = &d->resource[i];
452 if ((r->start & ~0x80) == 0x374) {
453 r->start |= 2;
454 r->end = r->start;
455 }
456 }
457}
458DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
459
460void __init pcibios_init(void)
461{
462 static struct resource galio,galmem;
463
464 /* Allocate the registers used by the Galileo */
465 galio.flags = IORESOURCE_IO;
466 galio.name = "Galileo GT64011";
467 galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH;
468 galmem.name = "Galileo GT64011 DRAM";
469
470 allocate_resource(&ioport_resource, &galio, 256,
471 GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL);
472 allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE,
473 PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE,
474 PCI_DRAM_SIZE, NULL, NULL);
475
476 /* ok, do the scan man */
477 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
478
479 pci_assign_unassigned_resources();
480 pci_fixup_irqs(no_swizzle, map_od_irq);
481
482#ifdef TEST_DRAM
483 printk("Testing PCI DRAM - ");
484 if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
485 printk("Passed\n");
486 }else {
487 printk("FAILED\n");
488 }
489#endif
490
491}
492
493char * __init pcibios_setup(char *str)
494{
495 return str;
496}
497
498
499
500int pcibios_enable_device(struct pci_dev *dev)
501{
502
503 u16 cmd, old_cmd;
504 int idx;
505 struct resource *r;
506
507 pci_read_config_word(dev, PCI_COMMAND, &cmd);
508 old_cmd = cmd;
509 for (idx = 0; idx < 6; idx++) {
510 r = dev->resource + idx;
511 if (!r->start && r->end) {
512 printk(KERN_ERR
513 "PCI: Device %s not available because"
514 " of resource collisions\n",
515 pci_name(dev));
516 return -EINVAL;
517 }
518 if (r->flags & IORESOURCE_IO)
519 cmd |= PCI_COMMAND_IO;
520 if (r->flags & IORESOURCE_MEM)
521 cmd |= PCI_COMMAND_MEMORY;
522 }
523 if (cmd != old_cmd) {
524 printk("PCI: enabling device %s (%04x -> %04x)\n",
525 pci_name(dev), old_cmd, cmd);
526 pci_write_config_word(dev, PCI_COMMAND, cmd);
527 }
528 return 0;
529
530}
531
532/* We should do some optimisation work here I think. Ok for now though */
533void __init pcibios_fixup_bus(struct pci_bus *bus)
534{
535
536}
537
538void pcibios_align_resource(void *data, struct resource *res,
539 unsigned long size)
540{
541}
542
543void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
544 struct resource *res, int resource)
545{
546
547 unsigned long where, size;
548 u32 reg;
549
550
551 printk("PCI: Assigning %3s %08lx to %s\n",
552 res->flags & IORESOURCE_IO ? "IO" : "MEM",
553 res->start, dev->name);
554
555 where = PCI_BASE_ADDRESS_0 + resource * 4;
556 size = res->end - res->start;
557
558 pci_read_config_dword(dev, where, &reg);
559 reg = (reg & size) | (((u32) (res->start - root->start)) & ~size);
560 pci_write_config_dword(dev, where, reg);
561}
562
563
564void __init pcibios_update_irq(struct pci_dev *dev, int irq)
565{
566 printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
567 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
568}
569
570/*
571 * If we set up a device for bus mastering, we need to check the latency
572 * timer as certain crappy BIOSes forget to set it properly.
573 */
574unsigned int pcibios_max_latency = 255;
575
576void pcibios_set_master(struct pci_dev *dev)
577{
578 u8 lat;
579 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
580 if (lat < 16)
581 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
582 else if (lat > pcibios_max_latency)
583 lat = pcibios_max_latency;
584 else
585 return;
586 printk("PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
587 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
588}
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 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file contains the I/O routines for use on the overdrive board
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/types.h>
13#include <linux/delay.h>
14#include <asm/processor.h>
15#include <asm/io.h>
16#include <asm/addrspace.h>
17
18#include <asm/overdrive/overdrive.h>
19
20/*
21 * readX/writeX() are used to access memory mapped devices. On some
22 * architectures the memory mapped IO stuff needs to be accessed
23 * differently. On the SuperH architecture, we just read/write the
24 * memory location directly.
25 */
26
27#define dprintk(x...)
28
29/* Translates an IO address to where it is mapped in memory */
30
31#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE)
32
33unsigned char od_inb(unsigned long port)
34{
35dprintk("od_inb(%x)\n", port);
36 return readb(io_addr(port)) & 0xff;
37}
38
39
40unsigned short od_inw(unsigned long port)
41{
42dprintk("od_inw(%x)\n", port);
43 return readw(io_addr(port)) & 0xffff;
44}
45
46unsigned int od_inl(unsigned long port)
47{
48dprintk("od_inl(%x)\n", port);
49 return readl(io_addr(port));
50}
51
52void od_outb(unsigned char value, unsigned long port)
53{
54dprintk("od_outb(%x, %x)\n", value, port);
55 writeb(value, io_addr(port));
56}
57
58void od_outw(unsigned short value, unsigned long port)
59{
60dprintk("od_outw(%x, %x)\n", value, port);
61 writew(value, io_addr(port));
62}
63
64void od_outl(unsigned int value, unsigned long port)
65{
66dprintk("od_outl(%x, %x)\n", value, port);
67 writel(value, io_addr(port));
68}
69
70/* This is horrible at the moment - needs more work to do something sensible */
71#define IO_DELAY() udelay(10)
72
73#define OUT_DELAY(x,type) \
74void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();}
75
76#define IN_DELAY(x,type) \
77unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;}
78
79
80OUT_DELAY(b,char)
81OUT_DELAY(w,short)
82OUT_DELAY(l,int)
83
84IN_DELAY(b,char)
85IN_DELAY(w,short)
86IN_DELAY(l,int)
87
88
89/* Now for the string version of these functions */
90void od_outsb(unsigned long port, const void *addr, unsigned long count)
91{
92 int i;
93 unsigned char *p = (unsigned char *) addr;
94
95 for (i = 0; i < count; i++, p++) {
96 outb(*p, port);
97 }
98}
99
100
101void od_insb(unsigned long port, void *addr, unsigned long count)
102{
103 int i;
104 unsigned char *p = (unsigned char *) addr;
105
106 for (i = 0; i < count; i++, p++) {
107 *p = inb(port);
108 }
109}
110
111/* For the 16 and 32 bit string functions, we have to worry about alignment.
112 * The SH does not do unaligned accesses, so we have to read as bytes and
113 * then write as a word or dword.
114 * This can be optimised a lot more, especially in the case where the data
115 * is aligned
116 */
117
118void od_outsw(unsigned long port, const void *addr, unsigned long count)
119{
120 int i;
121 unsigned short tmp;
122 unsigned char *p = (unsigned char *) addr;
123
124 for (i = 0; i < count; i++, p += 2) {
125 tmp = (*p) | ((*(p + 1)) << 8);
126 outw(tmp, port);
127 }
128}
129
130
131void od_insw(unsigned long port, void *addr, unsigned long count)
132{
133 int i;
134 unsigned short tmp;
135 unsigned char *p = (unsigned char *) addr;
136
137 for (i = 0; i < count; i++, p += 2) {
138 tmp = inw(port);
139 p[0] = tmp & 0xff;
140 p[1] = (tmp >> 8) & 0xff;
141 }
142}
143
144
145void od_outsl(unsigned long port, const void *addr, unsigned long count)
146{
147 int i;
148 unsigned tmp;
149 unsigned char *p = (unsigned char *) addr;
150
151 for (i = 0; i < count; i++, p += 4) {
152 tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
153 ((*(p + 3)) << 24);
154 outl(tmp, port);
155 }
156}
157
158
159void od_insl(unsigned long port, void *addr, unsigned long count)
160{
161 int i;
162 unsigned tmp;
163 unsigned char *p = (unsigned char *) addr;
164
165 for (i = 0; i < count; i++, p += 4) {
166 tmp = inl(port);
167 p[0] = tmp & 0xff;
168 p[1] = (tmp >> 8) & 0xff;
169 p[2] = (tmp >> 16) & 0xff;
170 p[3] = (tmp >> 24) & 0xff;
171
172 }
173}
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 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Looks after interrupts on the overdrive board.
8 *
9 * Bases on the IPR irq system
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <asm/system.h>
17#include <asm/io.h>
18
19#include <asm/overdrive/overdrive.h>
20
21struct od_data {
22 int overdrive_irq;
23 int irq_mask;
24};
25
26#define NUM_EXTERNAL_IRQS 16
27#define EXTERNAL_IRQ_NOT_IN_USE (-1)
28#define EXTERNAL_IRQ_NOT_ASSIGNED (-1)
29
30/*
31 * This table is used to determine what to program into the FPGA's CT register
32 * for the specified Linux IRQ.
33 *
34 * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0))
35 * but is one greater than that because the because the FPGA treats 0
36 * as disabled, a value of 1 asserts PCI_Int0, and so on.
37 *
38 * The overdrive_irq specifies which of the eight interrupt sources generates
39 * that interrupt, and but is multiplied by four to give the bit offset into
40 * the CT register.
41 *
42 * The seven interrupts levels (SH4 IRL's) we have available here is hardwired
43 * by the EPLD. The assignments here of which PCI interrupt generates each
44 * level is arbitary.
45 */
46static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = {
47 /* overdrive_irq , irq_mask */
48 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */
49 {EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */
50 {EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */
51 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */
52 {EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */
53 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */
54 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */
55 {EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */
56 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */
57 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */
58 {EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */
59 {EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */
60 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */
61 {EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */
62 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */
63 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */
64};
65
66static void set_od_data(int overdrive_irq, int irq)
67{
68 if (irq >= NUM_EXTERNAL_IRQS || irq < 0)
69 return;
70 od_data_table[irq].overdrive_irq = overdrive_irq << 2;
71}
72
73static void enable_od_irq(unsigned int irq);
74void disable_od_irq(unsigned int irq);
75
76/* shutdown is same as "disable" */
77#define shutdown_od_irq disable_od_irq
78
79static void mask_and_ack_od(unsigned int);
80static void end_od_irq(unsigned int irq);
81
82static unsigned int startup_od_irq(unsigned int irq)
83{
84 enable_od_irq(irq);
85 return 0; /* never anything pending */
86}
87
88static struct hw_interrupt_type od_irq_type = {
89 "Overdrive-IRQ",
90 startup_od_irq,
91 shutdown_od_irq,
92 enable_od_irq,
93 disable_od_irq,
94 mask_and_ack_od,
95 end_od_irq
96};
97
98static void disable_od_irq(unsigned int irq)
99{
100 unsigned val, flags;
101 int overdrive_irq;
102 unsigned mask;
103
104 /* Not a valid interrupt */
105 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
106 return;
107
108 /* Is is necessary to use a cli here? Would a spinlock not be
109 * mroe efficient?
110 */
111 local_irq_save(flags);
112 overdrive_irq = od_data_table[irq].overdrive_irq;
113 if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
114 mask = ~(0x7 << overdrive_irq);
115 val = ctrl_inl(OVERDRIVE_INT_CT);
116 val &= mask;
117 ctrl_outl(val, OVERDRIVE_INT_CT);
118 }
119 local_irq_restore(flags);
120}
121
122static void enable_od_irq(unsigned int irq)
123{
124 unsigned val, flags;
125 int overdrive_irq;
126 unsigned mask;
127
128 /* Not a valid interrupt */
129 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
130 return;
131
132 /* Set priority in OD back to original value */
133 local_irq_save(flags);
134 /* This one is not in use currently */
135 overdrive_irq = od_data_table[irq].overdrive_irq;
136 if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
137 val = ctrl_inl(OVERDRIVE_INT_CT);
138 mask = ~(0x7 << overdrive_irq);
139 val &= mask;
140 mask = od_data_table[irq].irq_mask << overdrive_irq;
141 val |= mask;
142 ctrl_outl(val, OVERDRIVE_INT_CT);
143 }
144 local_irq_restore(flags);
145}
146
147
148
149/* this functions sets the desired irq handler to be an overdrive type */
150static void __init make_od_irq(unsigned int irq)
151{
152 disable_irq_nosync(irq);
153 irq_desc[irq].handler = &od_irq_type;
154 disable_od_irq(irq);
155}
156
157
158static void mask_and_ack_od(unsigned int irq)
159{
160 disable_od_irq(irq);
161}
162
163static void end_od_irq(unsigned int irq)
164{
165 enable_od_irq(irq);
166}
167
168void __init init_overdrive_irq(void)
169{
170 int i;
171
172 /* Disable all interrupts */
173 ctrl_outl(0, OVERDRIVE_INT_CT);
174
175 /* Update interrupt pin mode to use encoded interrupts */
176 i = ctrl_inw(INTC_ICR);
177 i &= ~INTC_ICR_IRLM;
178 ctrl_outw(i, INTC_ICR);
179
180 for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
181 if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) {
182 make_od_irq(i);
183 } else if (i != 15) { // Cannot use imask on level 15
184 make_imask_irq(i);
185 }
186 }
187
188 /* Set up the interrupts */
189 set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1);
190 set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2);
191 set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ);
192}
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 @@
1/*
2 * linux/arch/sh/overdrive/led.c
3 *
4 * Copyright (C) 1999 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains an Overdrive specific LED feature.
10 */
11
12#include <linux/config.h>
13#include <asm/system.h>
14#include <asm/io.h>
15#include <asm/overdrive/overdrive.h>
16
17static void mach_led(int position, int value)
18{
19 unsigned long flags;
20 unsigned long reg;
21
22 local_irq_save(flags);
23
24 reg = readl(OVERDRIVE_CTRL);
25 if (value) {
26 reg |= (1<<3);
27 } else {
28 reg &= ~(1<<3);
29 }
30 writel(reg, OVERDRIVE_CTRL);
31
32 local_irq_restore(flags);
33}
34
35#ifdef CONFIG_HEARTBEAT
36
37#include <linux/sched.h>
38
39/* acts like an actual heart beat -- ie thump-thump-pause... */
40void heartbeat_od(void)
41{
42 static unsigned cnt = 0, period = 0, dist = 0;
43
44 if (cnt == 0 || cnt == dist)
45 mach_led( -1, 1);
46 else if (cnt == 7 || cnt == dist+7)
47 mach_led( -1, 0);
48
49 if (++cnt > period) {
50 cnt = 0;
51 /* The hyperbolic function below modifies the heartbeat period
52 * length in dependency of the current (5min) load. It goes
53 * through the points f(0)=126, f(1)=86, f(5)=51,
54 * f(inf)->30. */
55 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
56 dist = period / 4;
57 }
58}
59#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..2834a03ae477
--- /dev/null
+++ b/arch/sh/boards/overdrive/mach.c
@@ -0,0 +1,62 @@
1/*
2 * linux/arch/sh/overdrive/mach.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the STMicroelectronics Overdrive
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17
18#include <asm/io_unknown.h>
19#include <asm/io_generic.h>
20#include <asm/overdrive/io.h>
21
22void heartbeat_od(void);
23void init_overdrive_irq(void);
24void galileo_pcibios_init(void);
25
26/*
27 * The Machine Vector
28 */
29
30struct sh_machine_vector mv_od __initmv = {
31 .mv_nr_irqs = 48,
32
33 .mv_inb = od_inb,
34 .mv_inw = od_inw,
35 .mv_inl = od_inl,
36 .mv_outb = od_outb,
37 .mv_outw = od_outw,
38 .mv_outl = od_outl,
39
40 .mv_inb_p = od_inb_p,
41 .mv_inw_p = od_inw_p,
42 .mv_inl_p = od_inl_p,
43 .mv_outb_p = od_outb_p,
44 .mv_outw_p = od_outw_p,
45 .mv_outl_p = od_outl_p,
46
47 .mv_insb = od_insb,
48 .mv_insw = od_insw,
49 .mv_insl = od_insl,
50 .mv_outsb = od_outsb,
51 .mv_outsw = od_outsw,
52 .mv_outsl = od_outsl,
53
54#ifdef CONFIG_PCI
55 .mv_init_irq = init_overdrive_irq,
56#endif
57#ifdef CONFIG_HEARTBEAT
58 .mv_heartbeat = heartbeat_od,
59#endif
60};
61
62ALIAS_MV(od)
diff --git a/arch/sh/boards/overdrive/pcidma.c b/arch/sh/boards/overdrive/pcidma.c
new file mode 100644
index 000000000000..1c9bfeda00b7
--- /dev/null
+++ b/arch/sh/boards/overdrive/pcidma.c
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Dynamic DMA mapping support.
8 *
9 * On the overdrive, we can only DMA from memory behind the PCI bus!
10 * this means that all DMA'able memory must come from there.
11 * this restriction will not apply to later boards.
12 */
13
14#include <linux/types.h>
15#include <linux/mm.h>
16#include <linux/string.h>
17#include <linux/pci.h>
18#include <asm/io.h>
19
20void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
21 dma_addr_t * dma_handle)
22{
23 void *ret;
24 int gfp = GFP_ATOMIC;
25
26 printk("BUG: pci_alloc_consistent() called - not yet supported\n");
27 /* We ALWAYS need DMA memory on the overdrive hardware,
28 * due to it's extreme weirdness
29 * Need to flush the cache here as well, since the memory
30 * can still be seen through the cache!
31 */
32 gfp |= GFP_DMA;
33 ret = (void *) __get_free_pages(gfp, get_order(size));
34
35 if (ret != NULL) {
36 memset(ret, 0, size);
37 *dma_handle = virt_to_bus(ret);
38 }
39 return ret;
40}
41
42void pci_free_consistent(struct pci_dev *hwdev, size_t size,
43 void *vaddr, dma_addr_t dma_handle)
44{
45 free_pages((unsigned long) vaddr, get_order(size));
46}
diff --git a/arch/sh/boards/overdrive/setup.c b/arch/sh/boards/overdrive/setup.c
new file mode 100644
index 000000000000..a36ce0284ed3
--- /dev/null
+++ b/arch/sh/boards/overdrive/setup.c
@@ -0,0 +1,41 @@
1/*
2 * arch/sh/overdrive/setup.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * STMicroelectronics Overdrive Support.
10 */
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <asm/io.h>
16
17#include <asm/overdrive/overdrive.h>
18#include <asm/overdrive/fpga.h>
19
20extern void od_time_init(void);
21
22const char *get_system_type(void)
23{
24 return "SH7750 Overdrive";
25}
26
27/*
28 * Initialize the board
29 */
30int __init platform_setup(void)
31{
32#ifdef CONFIG_PCI
33 init_overdrive_fpga();
34 galileo_init();
35#endif
36
37 board_time_init = od_time_init;
38
39 /* Enable RS232 receive buffers */
40 writel(0x1e, OVERDRIVE_CTRL);
41}
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 @@
1/*
2 * arch/sh/boards/overdrive/time.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 * Copyright (C) 2002 Paul Mundt (lethal@chaoticdreams.org)
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 * STMicroelectronics Overdrive Support.
11 */
12
13void od_time_init(void)
14{
15 struct frqcr_data {
16 unsigned short frqcr;
17 struct {
18 unsigned char multiplier;
19 unsigned char divisor;
20 } factor[3];
21 };
22
23 static struct frqcr_data st40_frqcr_table[] = {
24 { 0x000, {{1,1}, {1,1}, {1,2}}},
25 { 0x002, {{1,1}, {1,1}, {1,4}}},
26 { 0x004, {{1,1}, {1,1}, {1,8}}},
27 { 0x008, {{1,1}, {1,2}, {1,2}}},
28 { 0x00A, {{1,1}, {1,2}, {1,4}}},
29 { 0x00C, {{1,1}, {1,2}, {1,8}}},
30 { 0x011, {{1,1}, {2,3}, {1,6}}},
31 { 0x013, {{1,1}, {2,3}, {1,3}}},
32 { 0x01A, {{1,1}, {1,2}, {1,4}}},
33 { 0x01C, {{1,1}, {1,2}, {1,8}}},
34 { 0x023, {{1,1}, {2,3}, {1,3}}},
35 { 0x02C, {{1,1}, {1,2}, {1,8}}},
36 { 0x048, {{1,2}, {1,2}, {1,4}}},
37 { 0x04A, {{1,2}, {1,2}, {1,6}}},
38 { 0x04C, {{1,2}, {1,2}, {1,8}}},
39 { 0x05A, {{1,2}, {1,3}, {1,6}}},
40 { 0x05C, {{1,2}, {1,3}, {1,6}}},
41 { 0x063, {{1,2}, {1,4}, {1,4}}},
42 { 0x06C, {{1,2}, {1,4}, {1,8}}},
43 { 0x091, {{1,3}, {1,3}, {1,6}}},
44 { 0x093, {{1,3}, {1,3}, {1,6}}},
45 { 0x0A3, {{1,3}, {1,6}, {1,6}}},
46 { 0x0DA, {{1,4}, {1,4}, {1,8}}},
47 { 0x0DC, {{1,4}, {1,4}, {1,8}}},
48 { 0x0EC, {{1,4}, {1,8}, {1,8}}},
49 { 0x123, {{1,4}, {1,4}, {1,8}}},
50 { 0x16C, {{1,4}, {1,8}, {1,8}}},
51 };
52
53 struct memclk_data {
54 unsigned char multiplier;
55 unsigned char divisor;
56 };
57 static struct memclk_data st40_memclk_table[8] = {
58 {1,1}, // 000
59 {1,2}, // 001
60 {1,3}, // 010
61 {2,3}, // 011
62 {1,4}, // 100
63 {1,6}, // 101
64 {1,8}, // 110
65 {1,8} // 111
66 };
67
68 unsigned long pvr;
69
70 /*
71 * This should probably be moved into the SH3 probing code, and then
72 * use the processor structure to determine which CPU we are running
73 * on.
74 */
75 pvr = ctrl_inl(CCN_PVR);
76 printk("PVR %08x\n", pvr);
77
78 if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) {
79 /*
80 * Unfortunatly the STB1 FRQCR values are different from the
81 * 7750 ones.
82 */
83 struct frqcr_data *d;
84 int a;
85 unsigned long memclkcr;
86 struct memclk_data *e;
87
88 for (a=0; a<ARRAY_SIZE(st40_frqcr_table); a++) {
89 d = &st40_frqcr_table[a];
90 if (d->frqcr == (frqcr & 0x1ff))
91 break;
92 }
93 if (a == ARRAY_SIZE(st40_frqcr_table)) {
94 d = st40_frqcr_table;
95 printk("ERROR: Unrecognised FRQCR value, using default multipliers\n");
96 }
97
98 memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
99 e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
100
101 printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n",
102 d->factor[0].multiplier, d->factor[0].divisor,
103 d->factor[1].multiplier, d->factor[1].divisor,
104 e->multiplier, e->divisor,
105 d->factor[2].multiplier, d->factor[2].divisor);
106
107 current_cpu_data.master_clock = current_cpu_data.module_clock *
108 d->factor[2].divisor /
109 d->factor[2].multiplier;
110 current_cpu_data.bus_clock = current_cpu_data.master_clock *
111 d->factor[1].multiplier /
112 d->factor[1].divisor;
113 current_cpu_data.memory_clock = current_cpu_data.master_clock *
114 e->multiplier / e->divisor;
115 current_cpu_data.cpu_clock = current_cpu_data.master_clock *
116 d->factor[0].multiplier /
117 d->factor[0].divisor;
118}
119
diff --git a/arch/sh/boards/renesas/edosk7705/Makefile b/arch/sh/boards/renesas/edosk7705/Makefile
new file mode 100644
index 000000000000..7fccbf2e4a1d
--- /dev/null
+++ b/arch/sh/boards/renesas/edosk7705/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for the EDOSK7705 specific parts of the kernel
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8
9obj-y := setup.o io.o
10
diff --git a/arch/sh/boards/renesas/edosk7705/io.c b/arch/sh/boards/renesas/edosk7705/io.c
new file mode 100644
index 000000000000..541cea2a652f
--- /dev/null
+++ b/arch/sh/boards/renesas/edosk7705/io.c
@@ -0,0 +1,94 @@
1/*
2 * arch/sh/boards/renesas/edosk7705/io.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routines for Hitachi EDOSK7705 board.
8 *
9 */
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <asm/io.h>
14#include <asm/edosk7705/io.h>
15#include <asm/addrspace.h>
16
17#define SMC_IOADDR 0xA2000000
18
19#define maybebadio(name,port) \
20 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
21 #name, (port), (__u32) __builtin_return_address(0))
22
23/* Map the Ethernet addresses as if it is at 0x300 - 0x320 */
24unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
25{
26 if (port >= 0x300 && port < 0x320) {
27 /* SMC91C96 registers are 4 byte aligned rather than the
28 * usual 2 byte!
29 */
30 return SMC_IOADDR + ( (port - 0x300) * 2);
31 }
32
33 maybebadio(sh_edosk7705_isa_port2addr, port);
34 return port;
35}
36
37/* Trying to read / write bytes on odd-byte boundaries to the Ethernet
38 * registers causes problems. So we bit-shift the value and read / write
39 * in 2 byte chunks. Setting the low byte to 0 does not cause problems
40 * now as odd byte writes are only made on the bit mask / interrupt
41 * register. This may not be the case in future Mar-2003 SJD
42 */
43unsigned char sh_edosk7705_inb(unsigned long port)
44{
45 if (port >= 0x300 && port < 0x320 && port & 0x01) {
46 return (volatile unsigned char)(generic_inw(port -1) >> 8);
47 }
48 return *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port);
49}
50
51unsigned int sh_edosk7705_inl(unsigned long port)
52{
53 return *(volatile unsigned long *)port;
54}
55
56void sh_edosk7705_outb(unsigned char value, unsigned long port)
57{
58 if (port >= 0x300 && port < 0x320 && port & 0x01) {
59 generic_outw(((unsigned short)value << 8), port -1);
60 return;
61 }
62 *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port) = value;
63}
64
65void sh_edosk7705_outl(unsigned int value, unsigned long port)
66{
67 *(volatile unsigned long *)port = value;
68}
69
70void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count)
71{
72 unsigned char *p = addr;
73 while (count--) *p++ = sh_edosk7705_inb(port);
74}
75
76void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count)
77{
78 unsigned long *p = (unsigned long*)addr;
79 while (count--)
80 *p++ = *(volatile unsigned long *)port;
81}
82
83void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count)
84{
85 unsigned char *p = (unsigned char*)addr;
86 while (count--) sh_edosk7705_outb(*p++, port);
87}
88
89void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count)
90{
91 unsigned long *p = (unsigned long*)addr;
92 while (count--) sh_edosk7705_outl(*p++, port);
93}
94
diff --git a/arch/sh/boards/renesas/edosk7705/setup.c b/arch/sh/boards/renesas/edosk7705/setup.c
new file mode 100644
index 000000000000..8b6f0c2af092
--- /dev/null
+++ b/arch/sh/boards/renesas/edosk7705/setup.c
@@ -0,0 +1,60 @@
1/*
2 * arch/sh/boards/renesas/edosk7705/setup.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Hitachi SolutionEngine Support.
7 *
8 * Modified for edosk7705 development
9 * board by S. Dunn, 2003.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <asm/machvec.h>
15#include <asm/machvec_init.h>
16#include <asm/edosk7705/io.h>
17
18static void init_edosk7705(void);
19
20/*
21 * The Machine Vector
22 */
23
24struct sh_machine_vector mv_edosk7705 __initmv = {
25 .mv_nr_irqs = 80,
26
27 .mv_inb = sh_edosk7705_inb,
28 .mv_inl = sh_edosk7705_inl,
29 .mv_outb = sh_edosk7705_outb,
30 .mv_outl = sh_edosk7705_outl,
31
32 .mv_inl_p = sh_edosk7705_inl,
33 .mv_outl_p = sh_edosk7705_outl,
34
35 .mv_insb = sh_edosk7705_insb,
36 .mv_insl = sh_edosk7705_insl,
37 .mv_outsb = sh_edosk7705_outsb,
38 .mv_outsl = sh_edosk7705_outsl,
39
40 .mv_isa_port2addr = sh_edosk7705_isa_port2addr,
41 .mv_init_irq = init_edosk7705,
42};
43ALIAS_MV(edosk7705)
44
45static void __init init_edosk7705(void)
46{
47 /* This is the Ethernet interrupt */
48 make_imask_irq(0x09);
49}
50
51const char *get_system_type(void)
52{
53 return "EDOSK7705";
54}
55
56void __init platform_setup(void)
57{
58 /* Nothing .. */
59}
60
diff --git a/arch/sh/boards/renesas/hs7751rvoip/Makefile b/arch/sh/boards/renesas/hs7751rvoip/Makefile
new file mode 100644
index 000000000000..e8b4109ace11
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for the HS7751RVoIP specific parts of the kernel
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8
9obj-y := mach.o setup.o io.o irq.o led.o
10
11obj-$(CONFIG_PCI) += pci.o
12
diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c
new file mode 100644
index 000000000000..456753d2649c
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/io.c
@@ -0,0 +1,310 @@
1/*
2 * linux/arch/sh/kernel/io_hs7751rvoip.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for Renesas Technology sales HS7751RVoIP
8 *
9 * Initial version only to support LAN access; some
10 * placeholder code from io_hs7751rvoip.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <asm/io.h>
18#include <asm/hs7751rvoip/hs7751rvoip.h>
19#include <asm/addrspace.h>
20
21#include <linux/module.h>
22#include <linux/pci.h>
23#include "../../../drivers/pci/pci-sh7751.h"
24
25extern void *area5_io8_base; /* Area 5 8bit I/O Base address */
26extern void *area6_io8_base; /* Area 6 8bit I/O Base address */
27extern void *area5_io16_base; /* Area 5 16bit I/O Base address */
28extern void *area6_io16_base; /* Area 6 16bit I/O Base address */
29
30/*
31 * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC)
32 * of the 7751R processor, and has a SuperIO accessible via the PCI.
33 * The board also includes a PCMCIA controller on its memory bus,
34 * like the other Solution Engine boards.
35 */
36
37#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
38#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
39#define PCI_IO_AREA SH7751_PCI_IO_BASE
40#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
41
42#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
43
44#if defined(CONFIG_HS7751RVOIP_CODEC)
45#define CODEC_IO_BASE 0x1000
46#endif
47
48#define maybebadio(name,port) \
49 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
50 #name, (port), (__u32) __builtin_return_address(0))
51
52static inline void delay(void)
53{
54 ctrl_inw(0xa0000000);
55}
56
57static inline unsigned long port2adr(unsigned int port)
58{
59 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
60 if (port == 0x3f6)
61 return ((unsigned long)area5_io16_base + 0x0c);
62 else
63 return ((unsigned long)area5_io16_base + 0x800 + ((port-0x1f0) << 1));
64 else
65 maybebadio(port2adr, (unsigned long)port);
66 return port;
67}
68
69/* The 7751R HS7751RVoIP seems to have everything hooked */
70/* up pretty normally (nothing on high-bytes only...) so this */
71/* shouldn't be needed */
72static inline int shifted_port(unsigned long port)
73{
74 /* For IDE registers, value is not shifted */
75 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
76 return 0;
77 else
78 return 1;
79}
80
81#if defined(CONFIG_HS7751RVOIP_CODEC)
82static inline int
83codec_port(unsigned long port)
84{
85 if (CODEC_IO_BASE <= port && port < (CODEC_IO_BASE+0x20))
86 return 1;
87 else
88 return 0;
89}
90#endif
91
92/* In case someone configures the kernel w/o PCI support: in that */
93/* scenario, don't ever bother to check for PCI-window addresses */
94
95/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
96#if defined(CONFIG_PCI)
97#define CHECK_SH7751_PCIIO(port) \
98 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
99#else
100#define CHECK_SH7751_PCIIO(port) (0)
101#endif
102
103/*
104 * General outline: remap really low stuff [eventually] to SuperIO,
105 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
106 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
107 * should be way beyond the window, and is used w/o translation for
108 * compatibility.
109 */
110unsigned char hs7751rvoip_inb(unsigned long port)
111{
112 if (PXSEG(port))
113 return *(volatile unsigned char *)port;
114#if defined(CONFIG_HS7751RVOIP_CODEC)
115 else if (codec_port(port))
116 return *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE));
117#endif
118 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
119 return *(volatile unsigned char *)PCI_IOMAP(port);
120 else
121 return (*(volatile unsigned short *)port2adr(port) & 0xff);
122}
123
124unsigned char hs7751rvoip_inb_p(unsigned long port)
125{
126 unsigned char v;
127
128 if (PXSEG(port))
129 v = *(volatile unsigned char *)port;
130#if defined(CONFIG_HS7751RVOIP_CODEC)
131 else if (codec_port(port))
132 v = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE));
133#endif
134 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
135 v = *(volatile unsigned char *)PCI_IOMAP(port);
136 else
137 v = (*(volatile unsigned short *)port2adr(port) & 0xff);
138 delay();
139 return v;
140}
141
142unsigned short hs7751rvoip_inw(unsigned long port)
143{
144 if (PXSEG(port))
145 return *(volatile unsigned short *)port;
146 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
147 return *(volatile unsigned short *)PCI_IOMAP(port);
148 else
149 maybebadio(inw, port);
150 return 0;
151}
152
153unsigned int hs7751rvoip_inl(unsigned long port)
154{
155 if (PXSEG(port))
156 return *(volatile unsigned long *)port;
157 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
158 return *(volatile unsigned long *)PCI_IOMAP(port);
159 else
160 maybebadio(inl, port);
161 return 0;
162}
163
164void hs7751rvoip_outb(unsigned char value, unsigned long port)
165{
166
167 if (PXSEG(port))
168 *(volatile unsigned char *)port = value;
169#if defined(CONFIG_HS7751RVOIP_CODEC)
170 else if (codec_port(port))
171 *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value;
172#endif
173 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
174 *(unsigned char *)PCI_IOMAP(port) = value;
175 else
176 *(volatile unsigned short *)port2adr(port) = value;
177}
178
179void hs7751rvoip_outb_p(unsigned char value, unsigned long port)
180{
181 if (PXSEG(port))
182 *(volatile unsigned char *)port = value;
183#if defined(CONFIG_HS7751RVOIP_CODEC)
184 else if (codec_port(port))
185 *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value;
186#endif
187 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
188 *(unsigned char *)PCI_IOMAP(port) = value;
189 else
190 *(volatile unsigned short *)port2adr(port) = value;
191 delay();
192}
193
194void hs7751rvoip_outw(unsigned short value, unsigned long port)
195{
196 if (PXSEG(port))
197 *(volatile unsigned short *)port = value;
198 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
199 *(unsigned short *)PCI_IOMAP(port) = value;
200 else
201 maybebadio(outw, port);
202}
203
204void hs7751rvoip_outl(unsigned int value, unsigned long port)
205{
206 if (PXSEG(port))
207 *(volatile unsigned long *)port = value;
208 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
209 *((unsigned long *)PCI_IOMAP(port)) = value;
210 else
211 maybebadio(outl, port);
212}
213
214void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count)
215{
216 if (PXSEG(port))
217 while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port;
218#if defined(CONFIG_HS7751RVOIP_CODEC)
219 else if (codec_port(port))
220 while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE));
221#endif
222 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
223 volatile __u8 *bp = (__u8 *)PCI_IOMAP(port);
224
225 while (count--) *((volatile unsigned char *) addr)++ = *bp;
226 } else {
227 volatile __u16 *p = (volatile unsigned short *)port2adr(port);
228
229 while (count--) *((unsigned char *) addr)++ = *p & 0xff;
230 }
231}
232
233void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count)
234{
235 volatile __u16 *p;
236
237 if (PXSEG(port))
238 p = (volatile unsigned short *)port;
239 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
240 p = (volatile unsigned short *)PCI_IOMAP(port);
241 else
242 p = (volatile unsigned short *)port2adr(port);
243 while (count--) *((__u16 *) addr)++ = *p;
244}
245
246void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count)
247{
248 if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
249 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
250
251 while (count--) *((__u32 *) addr)++ = *p;
252 } else
253 maybebadio(insl, port);
254}
255
256void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count)
257{
258 if (PXSEG(port))
259 while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++;
260#if defined(CONFIG_HS7751RVOIP_CODEC)
261 else if (codec_port(port))
262 while (count--) *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = *((unsigned char *) addr)++;
263#endif
264 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
265 volatile __u8 *bp = (__u8 *)PCI_IOMAP(port);
266
267 while (count--) *bp = *((volatile unsigned char *) addr)++;
268 } else {
269 volatile __u16 *p = (volatile unsigned short *)port2adr(port);
270
271 while (count--) *p = *((unsigned char *) addr)++;
272 }
273}
274
275void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count)
276{
277 volatile __u16 *p;
278
279 if (PXSEG(port))
280 p = (volatile unsigned short *)port;
281 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
282 p = (volatile unsigned short *)PCI_IOMAP(port);
283 else
284 p = (volatile unsigned short *)port2adr(port);
285 while (count--) *p = *((__u16 *) addr)++;
286}
287
288void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count)
289{
290 if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
291 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
292
293 while (count--) *p = *((__u32 *) addr)++;
294 } else
295 maybebadio(outsl, port);
296}
297
298void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size)
299{
300 if (offset >= 0xfd000000)
301 return (void *)offset;
302 else
303 return (void *)P2SEGADDR(offset);
304}
305EXPORT_SYMBOL(hs7751rvoip_ioremap);
306
307unsigned long hs7751rvoip_isa_port2addr(unsigned long offset)
308{
309 return port2adr(offset);
310}
diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c
new file mode 100644
index 000000000000..a7921f67a35f
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c
@@ -0,0 +1,122 @@
1/*
2 * linux/arch/sh/boards/renesas/hs7751rvoip/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales HS7751RVoIP Support.
7 *
8 * Modified for HS7751RVoIP by
9 * Atom Create Engineering Co., Ltd. 2002.
10 * Lineo uSolutions, Inc. 2003.
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/irq.h>
16#include <asm/io.h>
17#include <asm/irq.h>
18#include <asm/hs7751rvoip/hs7751rvoip.h>
19
20static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7};
21
22static void enable_hs7751rvoip_irq(unsigned int irq);
23static void disable_hs7751rvoip_irq(unsigned int irq);
24
25/* shutdown is same as "disable" */
26#define shutdown_hs7751rvoip_irq disable_hs7751rvoip_irq
27
28static void ack_hs7751rvoip_irq(unsigned int irq);
29static void end_hs7751rvoip_irq(unsigned int irq);
30
31static unsigned int startup_hs7751rvoip_irq(unsigned int irq)
32{
33 enable_hs7751rvoip_irq(irq);
34 return 0; /* never anything pending */
35}
36
37static void disable_hs7751rvoip_irq(unsigned int irq)
38{
39 unsigned long flags;
40 unsigned short val;
41 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
42
43 /* Set the priority in IPR to 0 */
44 local_irq_save(flags);
45 val = ctrl_inw(IRLCNTR3);
46 val &= mask;
47 ctrl_outw(val, IRLCNTR3);
48 local_irq_restore(flags);
49}
50
51static void enable_hs7751rvoip_irq(unsigned int irq)
52{
53 unsigned long flags;
54 unsigned short val;
55 unsigned short value = (0x0001 << mask_pos[irq]);
56
57 /* Set priority in IPR back to original value */
58 local_irq_save(flags);
59 val = ctrl_inw(IRLCNTR3);
60 val |= value;
61 ctrl_outw(val, IRLCNTR3);
62 local_irq_restore(flags);
63}
64
65static void ack_hs7751rvoip_irq(unsigned int irq)
66{
67 disable_hs7751rvoip_irq(irq);
68}
69
70static void end_hs7751rvoip_irq(unsigned int irq)
71{
72 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
73 enable_hs7751rvoip_irq(irq);
74}
75
76static struct hw_interrupt_type hs7751rvoip_irq_type = {
77 "HS7751RVoIP IRQ",
78 startup_hs7751rvoip_irq,
79 shutdown_hs7751rvoip_irq,
80 enable_hs7751rvoip_irq,
81 disable_hs7751rvoip_irq,
82 ack_hs7751rvoip_irq,
83 end_hs7751rvoip_irq,
84};
85
86static void make_hs7751rvoip_irq(unsigned int irq)
87{
88 disable_irq_nosync(irq);
89 irq_desc[irq].handler = &hs7751rvoip_irq_type;
90 disable_hs7751rvoip_irq(irq);
91}
92
93/*
94 * Initialize IRQ setting
95 */
96void __init init_hs7751rvoip_IRQ(void)
97{
98 int i;
99
100 /* IRL0=ON HOOK1
101 * IRL1=OFF HOOK1
102 * IRL2=ON HOOK2
103 * IRL3=OFF HOOK2
104 * IRL4=Ringing Detection
105 * IRL5=CODEC
106 * IRL6=Ethernet
107 * IRL7=Ethernet Hub
108 * IRL8=USB Communication
109 * IRL9=USB Connection
110 * IRL10=USB DMA
111 * IRL11=CF Card
112 * IRL12=PCMCIA
113 * IRL13=PCI Slot
114 */
115 ctrl_outw(0x9876, IRLCNTR1);
116 ctrl_outw(0xdcba, IRLCNTR2);
117 ctrl_outw(0x0050, IRLCNTR4);
118 ctrl_outw(0x4321, IRLCNTR5);
119
120 for (i=0; i<14; i++)
121 make_hs7751rvoip_irq(i);
122}
diff --git a/arch/sh/boards/renesas/hs7751rvoip/led.c b/arch/sh/boards/renesas/hs7751rvoip/led.c
new file mode 100644
index 000000000000..18a13c8da8a4
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/led.c
@@ -0,0 +1,27 @@
1/*
2 * linux/arch/sh/kernel/setup_hs7751rvoip.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales HS7751RVoIP Support.
7 *
8 * Modified for HS7751RVoIP by
9 * Atom Create Engineering Co., Ltd. 2002.
10 * Lineo uSolutions, Inc. 2003.
11 */
12
13#include <linux/config.h>
14#include <asm/io.h>
15#include <asm/hs7751rvoip/hs7751rvoip.h>
16
17extern unsigned int debug_counter;
18
19void debug_led_disp(void)
20{
21 unsigned short value;
22
23 value = (unsigned char)debug_counter++;
24 ctrl_outb((0xf0|value), PA_OUTPORTR);
25 if (value == 0x0f)
26 debug_counter = 0;
27}
diff --git a/arch/sh/boards/renesas/hs7751rvoip/mach.c b/arch/sh/boards/renesas/hs7751rvoip/mach.c
new file mode 100644
index 000000000000..8bbed60220ca
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/mach.c
@@ -0,0 +1,55 @@
1/*
2 * linux/arch/sh/kernel/mach_hs7751rvoip.c
3 *
4 * Minor tweak of mach_se.c file to reference hs7751rvoip-specific items.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Renesas Technology sales HS7751RVoIP
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14
15#include <asm/machvec.h>
16#include <asm/rtc.h>
17#include <asm/irq.h>
18#include <asm/hs7751rvoip/io.h>
19
20extern void init_hs7751rvoip_IRQ(void);
21extern void *hs7751rvoip_ioremap(unsigned long, unsigned long);
22
23/*
24 * The Machine Vector
25 */
26
27struct sh_machine_vector mv_hs7751rvoip __initmv = {
28 .mv_nr_irqs = 72,
29
30 .mv_inb = hs7751rvoip_inb,
31 .mv_inw = hs7751rvoip_inw,
32 .mv_inl = hs7751rvoip_inl,
33 .mv_outb = hs7751rvoip_outb,
34 .mv_outw = hs7751rvoip_outw,
35 .mv_outl = hs7751rvoip_outl,
36
37 .mv_inb_p = hs7751rvoip_inb_p,
38 .mv_inw_p = hs7751rvoip_inw,
39 .mv_inl_p = hs7751rvoip_inl,
40 .mv_outb_p = hs7751rvoip_outb_p,
41 .mv_outw_p = hs7751rvoip_outw,
42 .mv_outl_p = hs7751rvoip_outl,
43
44 .mv_insb = hs7751rvoip_insb,
45 .mv_insw = hs7751rvoip_insw,
46 .mv_insl = hs7751rvoip_insl,
47 .mv_outsb = hs7751rvoip_outsb,
48 .mv_outsw = hs7751rvoip_outsw,
49 .mv_outsl = hs7751rvoip_outsl,
50
51 .mv_ioremap = hs7751rvoip_ioremap,
52 .mv_isa_port2addr = hs7751rvoip_isa_port2addr,
53 .mv_init_irq = init_hs7751rvoip_IRQ,
54};
55ALIAS_MV(hs7751rvoip)
diff --git a/arch/sh/boards/renesas/hs7751rvoip/pci.c b/arch/sh/boards/renesas/hs7751rvoip/pci.c
new file mode 100644
index 000000000000..7a442d1eca46
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/pci.c
@@ -0,0 +1,150 @@
1/*
2 * linux/arch/sh/kernel/pci-hs7751rvoip.c
3 *
4 * Author: Ian DaSilva (idasilva@mvista.com)
5 *
6 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * PCI initialization for the Renesas SH7751R HS7751RVoIP board
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20#include <linux/module.h>
21
22#include <asm/io.h>
23#include "../../../drivers/pci/pci-sh7751.h"
24#include <asm/hs7751rvoip/hs7751rvoip.h>
25
26#define PCIMCR_MRSET_OFF 0xBFFFFFFF
27#define PCIMCR_RFSH_OFF 0xFFFFFFFB
28
29/*
30 * Only long word accesses of the PCIC's internal local registers and the
31 * configuration registers from the CPU is supported.
32 */
33#define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
34#define PCIC_READ(x) readl(PCI_REG(x))
35
36/*
37 * Description: This function sets up and initializes the pcic, sets
38 * up the BARS, maps the DRAM into the address space etc, etc.
39 */
40int __init pcibios_init_platform(void)
41{
42 unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
43 unsigned short bcr2, bcr3;
44
45 /*
46 * Initialize the slave bus controller on the pcic. The values used
47 * here should not be hardcoded, but they should be taken from the bsc
48 * on the processor, to make this function as generic as possible.
49 * (i.e. Another sbc may usr different SDRAM timing settings -- in order
50 * for the pcic to work, its settings need to be exactly the same.)
51 */
52 bcr1 = (*(volatile unsigned long *)(SH7751_BCR1));
53 bcr2 = (*(volatile unsigned short *)(SH7751_BCR2));
54 bcr3 = (*(volatile unsigned short *)(SH7751_BCR3));
55 wcr1 = (*(volatile unsigned long *)(SH7751_WCR1));
56 wcr2 = (*(volatile unsigned long *)(SH7751_WCR2));
57 wcr3 = (*(volatile unsigned long *)(SH7751_WCR3));
58 mcr = (*(volatile unsigned long *)(SH7751_MCR));
59
60 bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */
61 (*(volatile unsigned long *)(SH7751_BCR1)) = bcr1;
62
63 bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
64 PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */
65 PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */
66 PCIC_WRITE(SH7751_PCIBCR3, bcr3); /* PCIC BCR3 */
67 PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */
68 PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */
69 PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */
70 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
71 PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */
72
73 /* Enable all interrupts, so we know what to fix */
74 PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
75 PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
76
77 /* Set up standard PCI config registers */
78 PCIC_WRITE(SH7751_PCICONF1, 0xFB900047); /* Bus Master, Mem & I/O access */
79 PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */
80 PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */
81 PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */
82 PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */
83 PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
84 PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */
85 PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */
86 PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */
87 PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */
88
89 /* Now turn it on... */
90 PCIC_WRITE(SH7751_PCICR, 0xa5000001);
91
92 /*
93 * Set PCIMBR and PCIIOBR here, assuming a single window
94 * (16M MEM, 256K IO) is enough. If a larger space is
95 * needed, the readx/writex and inx/outx functions will
96 * have to do more (e.g. setting registers for each call).
97 */
98
99 /*
100 * Set the MBR so PCI address is one-to-one with window,
101 * meaning all calls go straight through... use ifdef to
102 * catch erroneous assumption.
103 */
104 BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE);
105
106 PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM);
107
108 /* Set IOBR for window containing area specified in pci.h */
109 PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK));
110
111 /* All done, may as well say so... */
112 printk("SH7751R PCI: Finished initialization of the PCI controller\n");
113
114 return 1;
115}
116
117int __init pcibios_map_platform_irq(u8 slot, u8 pin)
118{
119 switch (slot) {
120 case 0: return IRQ_PCISLOT; /* PCI Extend slot */
121 case 1: return IRQ_PCMCIA; /* PCI Cardbus Bridge */
122 case 2: return IRQ_PCIETH; /* Realtek Ethernet controller */
123 case 3: return IRQ_PCIHUB; /* Realtek Ethernet Hub controller */
124 default:
125 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
126 return -1;
127 }
128}
129
130static struct resource sh7751_io_resource = {
131 .name = "SH7751_IO",
132 .start = 0x4000,
133 .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
134 .flags = IORESOURCE_IO
135};
136
137static struct resource sh7751_mem_resource = {
138 .name = "SH7751_mem",
139 .start = SH7751_PCI_MEMORY_BASE,
140 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
141 .flags = IORESOURCE_MEM
142};
143
144extern struct pci_ops sh7751_pci_ops;
145
146struct pci_channel board_pci_channels[] = {
147 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
148 { NULL, NULL, NULL, 0, 0 },
149};
150EXPORT_SYMBOL(board_pci_channels);
diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c
new file mode 100644
index 000000000000..f1a78b6c714c
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c
@@ -0,0 +1,89 @@
1/*
2 * linux/arch/sh/kernel/setup_hs7751rvoip.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales HS7751RVoIP Support.
7 *
8 * Modified for HS7751RVoIP by
9 * Atom Create Engineering Co., Ltd. 2002.
10 * Lineo uSolutions, Inc. 2003.
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/irq.h>
16
17#include <linux/hdreg.h>
18#include <linux/ide.h>
19#include <asm/io.h>
20#include <asm/hs7751rvoip/hs7751rvoip.h>
21
22#include <linux/mm.h>
23#include <linux/vmalloc.h>
24
25/* defined in mm/ioremap.c */
26extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
27
28unsigned int debug_counter;
29
30const char *get_system_type(void)
31{
32 return "HS7751RVoIP";
33}
34
35/*
36 * Initialize the board
37 */
38void __init platform_setup(void)
39{
40 printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n");
41 ctrl_outb(0xf0, PA_OUTPORTR);
42 debug_counter = 0;
43}
44
45void *area5_io8_base;
46void *area6_io8_base;
47void *area5_io16_base;
48void *area6_io16_base;
49
50int __init cf_init(void)
51{
52 pgprot_t prot;
53 unsigned long paddrbase, psize;
54
55 /* open I/O area window */
56 paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800));
57 psize = PAGE_SIZE;
58 prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16);
59 area5_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot);
60 if (!area5_io16_base) {
61 printk("allocate_cf_area : can't open CF I/O window!\n");
62 return -ENOMEM;
63 }
64
65 /* XXX : do we need attribute and common-memory area also? */
66
67 paddrbase = virt_to_phys((void *)PA_AREA6_IO);
68 psize = PAGE_SIZE;
69#if defined(CONFIG_HS7751RVOIP_CODEC)
70 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8);
71#else
72 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8);
73#endif
74 area6_io8_base = p3_ioremap(paddrbase, psize, prot.pgprot);
75 if (!area6_io8_base) {
76 printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n");
77 return -ENOMEM;
78 }
79 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
80 area6_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot);
81 if (!area6_io16_base) {
82 printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n");
83 return -ENOMEM;
84 }
85
86 return 0;
87}
88
89__initcall (cf_init);
diff --git a/arch/sh/boards/renesas/rts7751r2d/Makefile b/arch/sh/boards/renesas/rts7751r2d/Makefile
new file mode 100644
index 000000000000..daa53334bdc3
--- /dev/null
+++ b/arch/sh/boards/renesas/rts7751r2d/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for the RTS7751R2D specific parts of the kernel
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8
9obj-y := mach.o setup.o io.o irq.o led.o
10
diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c
new file mode 100644
index 000000000000..c46f9154cfd5
--- /dev/null
+++ b/arch/sh/boards/renesas/rts7751r2d/io.c
@@ -0,0 +1,319 @@
1/*
2 * linux/arch/sh/kernel/io_rts7751r2d.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for Renesas Technology sales RTS7751R2D.
8 *
9 * Initial version only to support LAN access; some
10 * placeholder code from io_rts7751r2d.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
12 */
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <asm/io.h>
17#include <asm/rts7751r2d/rts7751r2d.h>
18#include <asm/addrspace.h>
19
20#include <linux/module.h>
21#include <linux/pci.h>
22#include "../../../drivers/pci/pci-sh7751.h"
23
24/*
25 * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC)
26 * of the 7751R processor, and has a SuperIO accessible via the PCI.
27 * The board also includes a PCMCIA controller on its memory bus,
28 * like the other Solution Engine boards.
29 */
30
31#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
32#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
33#define PCI_IO_AREA SH7751_PCI_IO_BASE
34#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
35
36#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
37
38#define maybebadio(name,port) \
39 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
40 #name, (port), (__u32) __builtin_return_address(0))
41
42static inline void delay(void)
43{
44 ctrl_inw(0xa0000000);
45}
46
47static inline unsigned long port2adr(unsigned int port)
48{
49 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
50 if (port == 0x3f6)
51 return (PA_AREA5_IO + 0x80c);
52 else
53 return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
54 else
55 maybebadio(port2adr, (unsigned long)port);
56
57 return port;
58}
59
60static inline unsigned long port88796l(unsigned int port, int flag)
61{
62 unsigned long addr;
63
64 if (flag)
65 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
66 else
67 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
68
69 return addr;
70}
71
72/* The 7751R RTS7751R2D seems to have everything hooked */
73/* up pretty normally (nothing on high-bytes only...) so this */
74/* shouldn't be needed */
75static inline int shifted_port(unsigned long port)
76{
77 /* For IDE registers, value is not shifted */
78 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
79 return 0;
80 else
81 return 1;
82}
83
84/* In case someone configures the kernel w/o PCI support: in that */
85/* scenario, don't ever bother to check for PCI-window addresses */
86
87/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
88#if defined(CONFIG_PCI)
89#define CHECK_SH7751_PCIIO(port) \
90 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
91#else
92#define CHECK_SH7751_PCIIO(port) (0)
93#endif
94
95#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
96#define CHECK_AX88796L_PORT(port) \
97 ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
98#else
99#define CHECK_AX88796L_PORT(port) (0)
100#endif
101
102/*
103 * General outline: remap really low stuff [eventually] to SuperIO,
104 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
105 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
106 * should be way beyond the window, and is used w/o translation for
107 * compatibility.
108 */
109unsigned char rts7751r2d_inb(unsigned long port)
110{
111 if (CHECK_AX88796L_PORT(port))
112 return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
113 else if (PXSEG(port))
114 return *(volatile unsigned char *)port;
115 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
116 return *(volatile unsigned char *)PCI_IOMAP(port);
117 else
118 return (*(volatile unsigned short *)port2adr(port) & 0xff);
119}
120
121unsigned char rts7751r2d_inb_p(unsigned long port)
122{
123 unsigned char v;
124
125 if (CHECK_AX88796L_PORT(port))
126 v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
127 else if (PXSEG(port))
128 v = *(volatile unsigned char *)port;
129 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
130 v = *(volatile unsigned char *)PCI_IOMAP(port);
131 else
132 v = (*(volatile unsigned short *)port2adr(port) & 0xff);
133 delay();
134
135 return v;
136}
137
138unsigned short rts7751r2d_inw(unsigned long port)
139{
140 if (CHECK_AX88796L_PORT(port))
141 maybebadio(inw, port);
142 else if (PXSEG(port))
143 return *(volatile unsigned short *)port;
144 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
145 return *(volatile unsigned short *)PCI_IOMAP(port);
146 else
147 maybebadio(inw, port);
148
149 return 0;
150}
151
152unsigned int rts7751r2d_inl(unsigned long port)
153{
154 if (CHECK_AX88796L_PORT(port))
155 maybebadio(inl, port);
156 else if (PXSEG(port))
157 return *(volatile unsigned long *)port;
158 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
159 return *(volatile unsigned long *)PCI_IOMAP(port);
160 else
161 maybebadio(inl, port);
162
163 return 0;
164}
165
166void rts7751r2d_outb(unsigned char value, unsigned long port)
167{
168 if (CHECK_AX88796L_PORT(port))
169 *((volatile unsigned short *)port88796l(port, 0)) = value;
170 else if (PXSEG(port))
171 *(volatile unsigned char *)port = value;
172 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
173 *(volatile unsigned char *)PCI_IOMAP(port) = value;
174 else
175 *(volatile unsigned short *)port2adr(port) = value;
176}
177
178void rts7751r2d_outb_p(unsigned char value, unsigned long port)
179{
180 if (CHECK_AX88796L_PORT(port))
181 *((volatile unsigned short *)port88796l(port, 0)) = value;
182 else if (PXSEG(port))
183 *(volatile unsigned char *)port = value;
184 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
185 *(volatile unsigned char *)PCI_IOMAP(port) = value;
186 else
187 *(volatile unsigned short *)port2adr(port) = value;
188 delay();
189}
190
191void rts7751r2d_outw(unsigned short value, unsigned long port)
192{
193 if (CHECK_AX88796L_PORT(port))
194 maybebadio(outw, port);
195 else if (PXSEG(port))
196 *(volatile unsigned short *)port = value;
197 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
198 *(volatile unsigned short *)PCI_IOMAP(port) = value;
199 else
200 maybebadio(outw, port);
201}
202
203void rts7751r2d_outl(unsigned int value, unsigned long port)
204{
205 if (CHECK_AX88796L_PORT(port))
206 maybebadio(outl, port);
207 else if (PXSEG(port))
208 *(volatile unsigned long *)port = value;
209 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
210 *(volatile unsigned long *)PCI_IOMAP(port) = value;
211 else
212 maybebadio(outl, port);
213}
214
215void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count)
216{
217 volatile __u8 *bp;
218 volatile __u16 *p;
219
220 if (CHECK_AX88796L_PORT(port)) {
221 p = (volatile unsigned short *)port88796l(port, 0);
222 while (count--) *((unsigned char *) addr)++ = *p & 0xff;
223 } else if (PXSEG(port))
224 while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port;
225 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
226 bp = (__u8 *)PCI_IOMAP(port);
227 while (count--) *((volatile unsigned char *) addr)++ = *bp;
228 } else {
229 p = (volatile unsigned short *)port2adr(port);
230 while (count--) *((unsigned char *) addr)++ = *p & 0xff;
231 }
232}
233
234void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
235{
236 volatile __u16 *p;
237
238 if (CHECK_AX88796L_PORT(port))
239 p = (volatile unsigned short *)port88796l(port, 1);
240 else if (PXSEG(port))
241 p = (volatile unsigned short *)port;
242 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
243 p = (volatile unsigned short *)PCI_IOMAP(port);
244 else
245 p = (volatile unsigned short *)port2adr(port);
246 while (count--) *((__u16 *) addr)++ = *p;
247}
248
249void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
250{
251 if (CHECK_AX88796L_PORT(port))
252 maybebadio(insl, port);
253 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
254 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
255
256 while (count--) *((__u32 *) addr)++ = *p;
257 } else
258 maybebadio(insl, port);
259}
260
261void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
262{
263 volatile __u8 *bp;
264 volatile __u16 *p;
265
266 if (CHECK_AX88796L_PORT(port)) {
267 p = (volatile unsigned short *)port88796l(port, 0);
268 while (count--) *p = *((unsigned char *) addr)++;
269 } else if (PXSEG(port))
270 while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++;
271 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
272 bp = (__u8 *)PCI_IOMAP(port);
273 while (count--) *bp = *((volatile unsigned char *) addr)++;
274 } else {
275 p = (volatile unsigned short *)port2adr(port);
276 while (count--) *p = *((unsigned char *) addr)++;
277 }
278}
279
280void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
281{
282 volatile __u16 *p;
283
284 if (CHECK_AX88796L_PORT(port))
285 p = (volatile unsigned short *)port88796l(port, 1);
286 else if (PXSEG(port))
287 p = (volatile unsigned short *)port;
288 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
289 p = (volatile unsigned short *)PCI_IOMAP(port);
290 else
291 p = (volatile unsigned short *)port2adr(port);
292 while (count--) *p = *((__u16 *) addr)++;
293}
294
295void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
296{
297 if (CHECK_AX88796L_PORT(port))
298 maybebadio(outsl, port);
299 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
300 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
301
302 while (count--) *p = *((__u32 *) addr)++;
303 } else
304 maybebadio(outsl, port);
305}
306
307void *rts7751r2d_ioremap(unsigned long offset, unsigned long size)
308{
309 if (offset >= 0xfd000000)
310 return (void *)offset;
311 else
312 return (void *)P2SEGADDR(offset);
313}
314EXPORT_SYMBOL(rts7751r2d_ioremap);
315
316unsigned long rts7751r2d_isa_port2addr(unsigned long offset)
317{
318 return port2adr(offset);
319}
diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c
new file mode 100644
index 000000000000..95717f4f1e2d
--- /dev/null
+++ b/arch/sh/boards/renesas/rts7751r2d/irq.c
@@ -0,0 +1,135 @@
1/*
2 * linux/arch/sh/boards/renesas/rts7751r2d/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales RTS7751R2D Support.
7 *
8 * Modified for RTS7751R2D by
9 * Atom Create Engineering Co., Ltd. 2002.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15#include <asm/io.h>
16#include <asm/irq.h>
17#include <asm/rts7751r2d/rts7751r2d.h>
18
19#if defined(CONFIG_RTS7751R2D_REV11)
20static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0};
21#else
22static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0};
23#endif
24
25extern int voyagergx_irq_demux(int irq);
26extern void setup_voyagergx_irq(void);
27
28static void enable_rts7751r2d_irq(unsigned int irq);
29static void disable_rts7751r2d_irq(unsigned int irq);
30
31/* shutdown is same as "disable" */
32#define shutdown_rts7751r2d_irq disable_rts7751r2d_irq
33
34static void ack_rts7751r2d_irq(unsigned int irq);
35static void end_rts7751r2d_irq(unsigned int irq);
36
37static unsigned int startup_rts7751r2d_irq(unsigned int irq)
38{
39 enable_rts7751r2d_irq(irq);
40 return 0; /* never anything pending */
41}
42
43static void disable_rts7751r2d_irq(unsigned int irq)
44{
45 unsigned long flags;
46 unsigned short val;
47 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
48
49 /* Set the priority in IPR to 0 */
50 local_irq_save(flags);
51 val = ctrl_inw(IRLCNTR1);
52 val &= mask;
53 ctrl_outw(val, IRLCNTR1);
54 local_irq_restore(flags);
55}
56
57static void enable_rts7751r2d_irq(unsigned int irq)
58{
59 unsigned long flags;
60 unsigned short val;
61 unsigned short value = (0x0001 << mask_pos[irq]);
62
63 /* Set priority in IPR back to original value */
64 local_irq_save(flags);
65 val = ctrl_inw(IRLCNTR1);
66 val |= value;
67 ctrl_outw(val, IRLCNTR1);
68 local_irq_restore(flags);
69}
70
71int rts7751r2d_irq_demux(int irq)
72{
73 int demux_irq;
74
75 demux_irq = voyagergx_irq_demux(irq);
76 return demux_irq;
77}
78
79static void ack_rts7751r2d_irq(unsigned int irq)
80{
81 disable_rts7751r2d_irq(irq);
82}
83
84static void end_rts7751r2d_irq(unsigned int irq)
85{
86 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
87 enable_rts7751r2d_irq(irq);
88}
89
90static struct hw_interrupt_type rts7751r2d_irq_type = {
91 "RTS7751R2D IRQ",
92 startup_rts7751r2d_irq,
93 shutdown_rts7751r2d_irq,
94 enable_rts7751r2d_irq,
95 disable_rts7751r2d_irq,
96 ack_rts7751r2d_irq,
97 end_rts7751r2d_irq,
98};
99
100static void make_rts7751r2d_irq(unsigned int irq)
101{
102 disable_irq_nosync(irq);
103 irq_desc[irq].handler = &rts7751r2d_irq_type;
104 disable_rts7751r2d_irq(irq);
105}
106
107/*
108 * Initialize IRQ setting
109 */
110void __init init_rts7751r2d_IRQ(void)
111{
112 int i;
113
114 /* IRL0=KEY Input
115 * IRL1=Ethernet
116 * IRL2=CF Card
117 * IRL3=CF Card Insert
118 * IRL4=PCMCIA
119 * IRL5=VOYAGER
120 * IRL6=RTC Alarm
121 * IRL7=RTC Timer
122 * IRL8=SD Card
123 * IRL9=PCI Slot #1
124 * IRL10=PCI Slot #2
125 * IRL11=Extention #0
126 * IRL12=Extention #1
127 * IRL13=Extention #2
128 * IRL14=Extention #3
129 */
130
131 for (i=0; i<15; i++)
132 make_rts7751r2d_irq(i);
133
134 setup_voyagergx_irq();
135}
diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c
new file mode 100644
index 000000000000..9993259a894f
--- /dev/null
+++ b/arch/sh/boards/renesas/rts7751r2d/led.c
@@ -0,0 +1,67 @@
1/*
2 * linux/arch/sh/kernel/led_rts7751r2d.c
3 *
4 * Copyright (C) Atom Create Engineering Co., Ltd.
5 *
6 * May be copied or modified under the terms of GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains Renesas Technology Sales RTS7751R2D specific LED code.
10 */
11
12#include <linux/config.h>
13#include <asm/io.h>
14#include <asm/rts7751r2d/rts7751r2d.h>
15
16extern unsigned int debug_counter;
17
18#ifdef CONFIG_HEARTBEAT
19
20#include <linux/sched.h>
21
22/* Cycle the LED's in the clasic Knightriger/Sun pattern */
23void heartbeat_rts7751r2d(void)
24{
25 static unsigned int cnt = 0, period = 0;
26 volatile unsigned short *p = (volatile unsigned short *)PA_OUTPORT;
27 static unsigned bit = 0, up = 1;
28
29 cnt += 1;
30 if (cnt < period)
31 return;
32
33 cnt = 0;
34
35 /* Go through the points (roughly!):
36 * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110
37 */
38 period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT)));
39
40 *p = 1 << bit;
41 if (up)
42 if (bit == 7) {
43 bit--;
44 up = 0;
45 } else
46 bit++;
47 else if (bit == 0)
48 up = 1;
49 else
50 bit--;
51}
52#endif /* CONFIG_HEARTBEAT */
53
54void rts7751r2d_led(unsigned short value)
55{
56 ctrl_outw(value, PA_OUTPORT);
57}
58
59void debug_led_disp(void)
60{
61 unsigned short value;
62
63 value = (unsigned short)debug_counter++;
64 rts7751r2d_led(value);
65 if (value == 0xff)
66 debug_counter = 0;
67}
diff --git a/arch/sh/boards/renesas/rts7751r2d/mach.c b/arch/sh/boards/renesas/rts7751r2d/mach.c
new file mode 100644
index 000000000000..1efc18e786d5
--- /dev/null
+++ b/arch/sh/boards/renesas/rts7751r2d/mach.c
@@ -0,0 +1,70 @@
1/*
2 * linux/arch/sh/kernel/mach_rts7751r2d.c
3 *
4 * Minor tweak of mach_se.c file to reference rts7751r2d-specific items.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Renesas Technology sales RTS7751R2D
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/types.h>
15
16#include <asm/machvec.h>
17#include <asm/rtc.h>
18#include <asm/irq.h>
19#include <asm/rts7751r2d/io.h>
20
21extern void heartbeat_rts7751r2d(void);
22extern void init_rts7751r2d_IRQ(void);
23extern void *rts7751r2d_ioremap(unsigned long, unsigned long);
24extern int rts7751r2d_irq_demux(int irq);
25
26extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
27extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
28
29/*
30 * The Machine Vector
31 */
32
33struct sh_machine_vector mv_rts7751r2d __initmv = {
34 .mv_nr_irqs = 72,
35
36 .mv_inb = rts7751r2d_inb,
37 .mv_inw = rts7751r2d_inw,
38 .mv_inl = rts7751r2d_inl,
39 .mv_outb = rts7751r2d_outb,
40 .mv_outw = rts7751r2d_outw,
41 .mv_outl = rts7751r2d_outl,
42
43 .mv_inb_p = rts7751r2d_inb_p,
44 .mv_inw_p = rts7751r2d_inw,
45 .mv_inl_p = rts7751r2d_inl,
46 .mv_outb_p = rts7751r2d_outb_p,
47 .mv_outw_p = rts7751r2d_outw,
48 .mv_outl_p = rts7751r2d_outl,
49
50 .mv_insb = rts7751r2d_insb,
51 .mv_insw = rts7751r2d_insw,
52 .mv_insl = rts7751r2d_insl,
53 .mv_outsb = rts7751r2d_outsb,
54 .mv_outsw = rts7751r2d_outsw,
55 .mv_outsl = rts7751r2d_outsl,
56
57 .mv_ioremap = rts7751r2d_ioremap,
58 .mv_isa_port2addr = rts7751r2d_isa_port2addr,
59 .mv_init_irq = init_rts7751r2d_IRQ,
60#ifdef CONFIG_HEARTBEAT
61 .mv_heartbeat = heartbeat_rts7751r2d,
62#endif
63 .mv_irq_demux = rts7751r2d_irq_demux,
64
65#ifdef CONFIG_USB_OHCI_HCD
66 .mv_consistent_alloc = voyagergx_consistent_alloc,
67 .mv_consistent_free = voyagergx_consistent_free,
68#endif
69};
70ALIAS_MV(rts7751r2d)
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
new file mode 100644
index 000000000000..2587fd1a0240
--- /dev/null
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -0,0 +1,31 @@
1/*
2 * linux/arch/sh/kernel/setup_rts7751r2d.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales RTS7751R2D Support.
7 *
8 * Modified for RTS7751R2D by
9 * Atom Create Engineering Co., Ltd. 2002.
10 */
11
12#include <linux/init.h>
13#include <asm/io.h>
14#include <asm/rts7751r2d/rts7751r2d.h>
15
16unsigned int debug_counter;
17
18const char *get_system_type(void)
19{
20 return "RTS7751R2D";
21}
22
23/*
24 * Initialize the board
25 */
26void __init platform_setup(void)
27{
28 printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
29 ctrl_outw(0x0000, PA_OUTPORT);
30 debug_counter = 0;
31}
diff --git a/arch/sh/boards/renesas/systemh/Makefile b/arch/sh/boards/renesas/systemh/Makefile
new file mode 100644
index 000000000000..2cc6a23d9d39
--- /dev/null
+++ b/arch/sh/boards/renesas/systemh/Makefile
@@ -0,0 +1,13 @@
1#
2# Makefile for the SystemH specific parts of the kernel
3#
4
5obj-y := setup.o irq.o io.o
6
7# XXX: This wants to be consolidated in arch/sh/drivers/pci, and more
8# importantly, with the generic sh7751_pcic_init() code. For now, we'll
9# just abuse the hell out of kbuild, because we can..
10
11obj-$(CONFIG_PCI) += pci.o
12pci-y := ../../se/7751/pci.o
13
diff --git a/arch/sh/boards/renesas/systemh/io.c b/arch/sh/boards/renesas/systemh/io.c
new file mode 100644
index 000000000000..cf979011aa94
--- /dev/null
+++ b/arch/sh/boards/renesas/systemh/io.c
@@ -0,0 +1,283 @@
1/*
2 * linux/arch/sh/boards/systemh/io.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for Hitachi 7751 Systemh.
8 *
9 */
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <asm/systemh/7751systemh.h>
14#include <asm/addrspace.h>
15#include <asm/io.h>
16
17#include <linux/pci.h>
18#include "../../drivers/pci/pci-sh7751.h"
19
20/*
21 * The 7751 SystemH Engine uses the built-in PCI controller (PCIC)
22 * of the 7751 processor, and has a SuperIO accessible on its memory
23 * bus.
24 */
25
26#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
27#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
28#define PCI_IO_AREA SH7751_PCI_IO_BASE
29#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
30
31#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
32#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area
33 of smc lan chip*/
34
35#define maybebadio(name,port) \
36 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
37 #name, (port), (__u32) __builtin_return_address(0))
38
39static inline void delay(void)
40{
41 ctrl_inw(0xa0000000);
42}
43
44static inline volatile __u16 *
45port2adr(unsigned int port)
46{
47 if (port >= 0x2000)
48 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
49#if 0
50 else
51 return (volatile __u16 *) (PA_SUPERIO + (port << 1));
52#endif
53 maybebadio(name,(unsigned long)port);
54 return (volatile __u16*)port;
55}
56
57/* In case someone configures the kernel w/o PCI support: in that */
58/* scenario, don't ever bother to check for PCI-window addresses */
59
60/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
61#if defined(CONFIG_PCI)
62#define CHECK_SH7751_PCIIO(port) \
63 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
64#else
65#define CHECK_SH7751_PCIIO(port) (0)
66#endif
67
68/*
69 * General outline: remap really low stuff [eventually] to SuperIO,
70 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
71 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
72 * should be way beyond the window, and is used w/o translation for
73 * compatibility.
74 */
75unsigned char sh7751systemh_inb(unsigned long port)
76{
77 if (PXSEG(port))
78 return *(volatile unsigned char *)port;
79 else if (CHECK_SH7751_PCIIO(port))
80 return *(volatile unsigned char *)PCI_IOMAP(port);
81 else if (port <= 0x3F1)
82 return *(volatile unsigned char *)ETHER_IOMAP(port);
83 else
84 return (*port2adr(port))&0xff;
85}
86
87unsigned char sh7751systemh_inb_p(unsigned long port)
88{
89 unsigned char v;
90
91 if (PXSEG(port))
92 v = *(volatile unsigned char *)port;
93 else if (CHECK_SH7751_PCIIO(port))
94 v = *(volatile unsigned char *)PCI_IOMAP(port);
95 else if (port <= 0x3F1)
96 v = *(volatile unsigned char *)ETHER_IOMAP(port);
97 else
98 v = (*port2adr(port))&0xff;
99 delay();
100 return v;
101}
102
103unsigned short sh7751systemh_inw(unsigned long port)
104{
105 if (PXSEG(port))
106 return *(volatile unsigned short *)port;
107 else if (CHECK_SH7751_PCIIO(port))
108 return *(volatile unsigned short *)PCI_IOMAP(port);
109 else if (port >= 0x2000)
110 return *port2adr(port);
111 else if (port <= 0x3F1)
112 return *(volatile unsigned int *)ETHER_IOMAP(port);
113 else
114 maybebadio(inw, port);
115 return 0;
116}
117
118unsigned int sh7751systemh_inl(unsigned long port)
119{
120 if (PXSEG(port))
121 return *(volatile unsigned long *)port;
122 else if (CHECK_SH7751_PCIIO(port))
123 return *(volatile unsigned int *)PCI_IOMAP(port);
124 else if (port >= 0x2000)
125 return *port2adr(port);
126 else if (port <= 0x3F1)
127 return *(volatile unsigned int *)ETHER_IOMAP(port);
128 else
129 maybebadio(inl, port);
130 return 0;
131}
132
133void sh7751systemh_outb(unsigned char value, unsigned long port)
134{
135
136 if (PXSEG(port))
137 *(volatile unsigned char *)port = value;
138 else if (CHECK_SH7751_PCIIO(port))
139 *((unsigned char*)PCI_IOMAP(port)) = value;
140 else if (port <= 0x3F1)
141 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
142 else
143 *(port2adr(port)) = value;
144}
145
146void sh7751systemh_outb_p(unsigned char value, unsigned long port)
147{
148 if (PXSEG(port))
149 *(volatile unsigned char *)port = value;
150 else if (CHECK_SH7751_PCIIO(port))
151 *((unsigned char*)PCI_IOMAP(port)) = value;
152 else if (port <= 0x3F1)
153 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
154 else
155 *(port2adr(port)) = value;
156 delay();
157}
158
159void sh7751systemh_outw(unsigned short value, unsigned long port)
160{
161 if (PXSEG(port))
162 *(volatile unsigned short *)port = value;
163 else if (CHECK_SH7751_PCIIO(port))
164 *((unsigned short *)PCI_IOMAP(port)) = value;
165 else if (port >= 0x2000)
166 *port2adr(port) = value;
167 else if (port <= 0x3F1)
168 *(volatile unsigned short *)ETHER_IOMAP(port) = value;
169 else
170 maybebadio(outw, port);
171}
172
173void sh7751systemh_outl(unsigned int value, unsigned long port)
174{
175 if (PXSEG(port))
176 *(volatile unsigned long *)port = value;
177 else if (CHECK_SH7751_PCIIO(port))
178 *((unsigned long*)PCI_IOMAP(port)) = value;
179 else
180 maybebadio(outl, port);
181}
182
183void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count)
184{
185 unsigned char *p = addr;
186 while (count--) *p++ = sh7751systemh_inb(port);
187}
188
189void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count)
190{
191 unsigned short *p = addr;
192 while (count--) *p++ = sh7751systemh_inw(port);
193}
194
195void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count)
196{
197 maybebadio(insl, port);
198}
199
200void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count)
201{
202 unsigned char *p = (unsigned char*)addr;
203 while (count--) sh7751systemh_outb(*p++, port);
204}
205
206void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count)
207{
208 unsigned short *p = (unsigned short*)addr;
209 while (count--) sh7751systemh_outw(*p++, port);
210}
211
212void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count)
213{
214 maybebadio(outsw, port);
215}
216
217/* For read/write calls, just copy generic (pass-thru); PCIMBR is */
218/* already set up. For a larger memory space, these would need to */
219/* reset PCIMBR as needed on a per-call basis... */
220
221unsigned char sh7751systemh_readb(unsigned long addr)
222{
223 return *(volatile unsigned char*)addr;
224}
225
226unsigned short sh7751systemh_readw(unsigned long addr)
227{
228 return *(volatile unsigned short*)addr;
229}
230
231unsigned int sh7751systemh_readl(unsigned long addr)
232{
233 return *(volatile unsigned long*)addr;
234}
235
236void sh7751systemh_writeb(unsigned char b, unsigned long addr)
237{
238 *(volatile unsigned char*)addr = b;
239}
240
241void sh7751systemh_writew(unsigned short b, unsigned long addr)
242{
243 *(volatile unsigned short*)addr = b;
244}
245
246void sh7751systemh_writel(unsigned int b, unsigned long addr)
247{
248 *(volatile unsigned long*)addr = b;
249}
250
251
252
253/* Map ISA bus address to the real address. Only for PCMCIA. */
254
255/* ISA page descriptor. */
256static __u32 sh_isa_memmap[256];
257
258#if 0
259static int
260sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
261{
262 int idx;
263
264 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
265 return -1;
266
267 idx = start >> 12;
268 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
269 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
270 start, length, offset, idx, sh_isa_memmap[idx]);
271 return 0;
272}
273#endif
274
275unsigned long
276sh7751systemh_isa_port2addr(unsigned long offset)
277{
278 int idx;
279
280 idx = (offset >> 12) & 0xff;
281 offset &= 0xfff;
282 return sh_isa_memmap[idx] + offset;
283}
diff --git a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c
new file mode 100644
index 000000000000..5675a4134eee
--- /dev/null
+++ b/arch/sh/boards/renesas/systemh/irq.c
@@ -0,0 +1,111 @@
1/*
2 * linux/arch/sh/boards/systemh/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Hitachi SystemH Support.
7 *
8 * Modified for 7751 SystemH by
9 * Jonathan Short.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <linux/hdreg.h>
17#include <linux/ide.h>
18#include <asm/io.h>
19#include <asm/mach/7751systemh.h>
20#include <asm/smc37c93x.h>
21
22/* address of external interrupt mask register
23 * address must be set prior to use these (maybe in init_XXX_irq())
24 * XXX : is it better to use .config than specifying it in code? */
25static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004;
26static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000;
27
28/* forward declaration */
29static unsigned int startup_systemh_irq(unsigned int irq);
30static void shutdown_systemh_irq(unsigned int irq);
31static void enable_systemh_irq(unsigned int irq);
32static void disable_systemh_irq(unsigned int irq);
33static void mask_and_ack_systemh(unsigned int);
34static void end_systemh_irq(unsigned int irq);
35
36/* hw_interrupt_type */
37static struct hw_interrupt_type systemh_irq_type = {
38 " SystemH Register",
39 startup_systemh_irq,
40 shutdown_systemh_irq,
41 enable_systemh_irq,
42 disable_systemh_irq,
43 mask_and_ack_systemh,
44 end_systemh_irq
45};
46
47static unsigned int startup_systemh_irq(unsigned int irq)
48{
49 enable_systemh_irq(irq);
50 return 0; /* never anything pending */
51}
52
53static void shutdown_systemh_irq(unsigned int irq)
54{
55 disable_systemh_irq(irq);
56}
57
58static void disable_systemh_irq(unsigned int irq)
59{
60 if (systemh_irq_mask_register) {
61 unsigned long flags;
62 unsigned long val, mask = 0x01 << 1;
63
64 /* Clear the "irq"th bit in the mask and set it in the request */
65 local_irq_save(flags);
66
67 val = ctrl_inl((unsigned long)systemh_irq_mask_register);
68 val &= ~mask;
69 ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
70
71 val = ctrl_inl((unsigned long)systemh_irq_request_register);
72 val |= mask;
73 ctrl_outl(val, (unsigned long)systemh_irq_request_register);
74
75 local_irq_restore(flags);
76 }
77}
78
79static void enable_systemh_irq(unsigned int irq)
80{
81 if (systemh_irq_mask_register) {
82 unsigned long flags;
83 unsigned long val, mask = 0x01 << 1;
84
85 /* Set "irq"th bit in the mask register */
86 local_irq_save(flags);
87 val = ctrl_inl((unsigned long)systemh_irq_mask_register);
88 val |= mask;
89 ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
90 local_irq_restore(flags);
91 }
92}
93
94static void mask_and_ack_systemh(unsigned int irq)
95{
96 disable_systemh_irq(irq);
97}
98
99static void end_systemh_irq(unsigned int irq)
100{
101 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
102 enable_systemh_irq(irq);
103}
104
105void make_systemh_irq(unsigned int irq)
106{
107 disable_irq_nosync(irq);
108 irq_desc[irq].handler = &systemh_irq_type;
109 disable_systemh_irq(irq);
110}
111
diff --git a/arch/sh/boards/renesas/systemh/setup.c b/arch/sh/boards/renesas/systemh/setup.c
new file mode 100644
index 000000000000..826fa3d7669c
--- /dev/null
+++ b/arch/sh/boards/renesas/systemh/setup.c
@@ -0,0 +1,80 @@
1/*
2 * linux/arch/sh/boards/systemh/setup.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 * Copyright (C) 2003 Paul Mundt
6 *
7 * Hitachi SystemH Support.
8 *
9 * Modified for 7751 SystemH by Jonathan Short.
10 *
11 * Rewritten for 2.6 by Paul Mundt.
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */
17#include <linux/init.h>
18#include <asm/mach/7751systemh.h>
19#include <asm/mach/io.h>
20#include <asm/machvec.h>
21
22extern void make_systemh_irq(unsigned int irq);
23
24const char *get_system_type(void)
25{
26 return "7751 SystemH";
27}
28
29/*
30 * Initialize IRQ setting
31 */
32void __init init_7751systemh_IRQ(void)
33{
34/* make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); LAN */
35/* make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-4); */
36 make_systemh_irq(0xb); /* Ethernet interrupt */
37}
38
39struct sh_machine_vector mv_7751systemh __initmv = {
40 .mv_nr_irqs = 72,
41
42 .mv_inb = sh7751systemh_inb,
43 .mv_inw = sh7751systemh_inw,
44 .mv_inl = sh7751systemh_inl,
45 .mv_outb = sh7751systemh_outb,
46 .mv_outw = sh7751systemh_outw,
47 .mv_outl = sh7751systemh_outl,
48
49 .mv_inb_p = sh7751systemh_inb_p,
50 .mv_inw_p = sh7751systemh_inw,
51 .mv_inl_p = sh7751systemh_inl,
52 .mv_outb_p = sh7751systemh_outb_p,
53 .mv_outw_p = sh7751systemh_outw,
54 .mv_outl_p = sh7751systemh_outl,
55
56 .mv_insb = sh7751systemh_insb,
57 .mv_insw = sh7751systemh_insw,
58 .mv_insl = sh7751systemh_insl,
59 .mv_outsb = sh7751systemh_outsb,
60 .mv_outsw = sh7751systemh_outsw,
61 .mv_outsl = sh7751systemh_outsl,
62
63 .mv_readb = sh7751systemh_readb,
64 .mv_readw = sh7751systemh_readw,
65 .mv_readl = sh7751systemh_readl,
66 .mv_writeb = sh7751systemh_writeb,
67 .mv_writew = sh7751systemh_writew,
68 .mv_writel = sh7751systemh_writel,
69
70 .mv_isa_port2addr = sh7751systemh_isa_port2addr,
71
72 .mv_init_irq = init_7751systemh_IRQ,
73};
74ALIAS_MV(7751systemh)
75
76int __init platform_setup(void)
77{
78 return 0;
79}
80
diff --git a/arch/sh/boards/saturn/Makefile b/arch/sh/boards/saturn/Makefile
new file mode 100644
index 000000000000..75a3042e252e
--- /dev/null
+++ b/arch/sh/boards/saturn/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the Sega Saturn specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6
7obj-$(CONFIG_SMP) += smp.o
8
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 @@
1/*
2 * arch/sh/boards/saturn/io.c
3 *
4 * I/O routines for the Sega Saturn.
5 *
6 * Copyright (C) 2002 Paul Mundt
7 *
8 * Released under the terms of the GNU GPL v2.0.
9 */
10#include <asm/saturn/io.h>
11#include <asm/machvec.h>
12
13unsigned long saturn_isa_port2addr(unsigned long offset)
14{
15 return offset;
16}
17
18void *saturn_ioremap(unsigned long offset, unsigned long size)
19{
20 return (void *)offset;
21}
22
23void saturn_iounmap(void *addr)
24{
25}
26
diff --git a/arch/sh/boards/saturn/irq.c b/arch/sh/boards/saturn/irq.c
new file mode 100644
index 000000000000..15d1d3f0f787
--- /dev/null
+++ b/arch/sh/boards/saturn/irq.c
@@ -0,0 +1,118 @@
1/*
2 * arch/sh/boards/saturn/irq.c
3 *
4 * Copyright (C) 2002 Paul Mundt
5 *
6 * Released under the terms of the GNU GPL v2.0.
7 */
8#include <linux/kernel.h>
9#include <linux/init.h>
10#include <linux/interrupt.h>
11#include <asm/irq.h>
12#include <asm/io.h>
13
14/*
15 * Interrupts map out as follows:
16 *
17 * Vector Name Mask
18 *
19 * 64 VBLANKIN 0x0001
20 * 65 VBLANKOUT 0x0002
21 * 66 HBLANKIN 0x0004
22 * 67 TIMER0 0x0008
23 * 68 TIMER1 0x0010
24 * 69 DSPEND 0x0020
25 * 70 SOUNDREQUEST 0x0040
26 * 71 SYSTEMMANAGER 0x0080
27 * 72 PAD 0x0100
28 * 73 LEVEL2DMAEND 0x0200
29 * 74 LEVEL1DMAEND 0x0400
30 * 75 LEVEL0DMAEND 0x0800
31 * 76 DMAILLEGAL 0x1000
32 * 77 SRITEDRAWEND 0x2000
33 * 78 ABUS 0x8000
34 *
35 */
36#define SATURN_IRQ_MIN 64 /* VBLANKIN */
37#define SATURN_IRQ_MAX 78 /* ABUS */
38
39#define SATURN_IRQ_MASK 0xbfff
40
41static inline u32 saturn_irq_mask(unsigned int irq_nr)
42{
43 u32 mask;
44
45 mask = (1 << (irq_nr - SATURN_IRQ_MIN));
46 mask <<= (irq_nr == SATURN_IRQ_MAX);
47 mask &= SATURN_IRQ_MASK;
48
49 return mask;
50}
51
52static inline void mask_saturn_irq(unsigned int irq_nr)
53{
54 u32 mask;
55
56 mask = ctrl_inl(SATURN_IMR);
57 mask |= saturn_irq_mask(irq_nr);
58 ctrl_outl(mask, SATURN_IMR);
59}
60
61static inline void unmask_saturn_irq(unsigned int irq_nr)
62{
63 u32 mask;
64
65 mask = ctrl_inl(SATURN_IMR);
66 mask &= ~saturn_irq_mask(irq_nr);
67 ctrl_outl(mask, SATURN_IMR);
68}
69
70static void disable_saturn_irq(unsigned int irq_nr)
71{
72 mask_saturn_irq(irq_nr);
73}
74
75static void enable_saturn_irq(unsigned int irq_nr)
76{
77 unmask_saturn_irq(irq_nr);
78}
79
80static void mask_and_ack_saturn_irq(unsigned int irq_nr)
81{
82 mask_saturn_irq(irq_nr);
83}
84
85static void end_saturn_irq(unsigned int irq_nr)
86{
87 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
88 unmask_saturn_irq(irq_nr);
89}
90
91static unsigned int startup_saturn_irq(unsigned int irq_nr)
92{
93 unmask_saturn_irq(irq_nr);
94
95 return 0;
96}
97
98static void shutdown_saturn_irq(unsigned int irq_nr)
99{
100 mask_saturn_irq(irq_nr);
101}
102
103static struct hw_interrupt_type saturn_int = {
104 .typename = "Saturn",
105 .enable = enable_saturn_irq,
106 .disable = disable_saturn_irq,
107 .ack = mask_and_ack_saturn_irq,
108 .end = end_saturn_irq,
109 .startup = startup_saturn_irq,
110 .shutdown = shutdown_saturn_irq,
111};
112
113int saturn_irq_demux(int irq_nr)
114{
115 /* FIXME */
116 return irq_nr;
117}
118
diff --git a/arch/sh/boards/saturn/setup.c b/arch/sh/boards/saturn/setup.c
new file mode 100644
index 000000000000..bea6c572ad82
--- /dev/null
+++ b/arch/sh/boards/saturn/setup.c
@@ -0,0 +1,43 @@
1/*
2 * arch/sh/boards/saturn/setup.c
3 *
4 * Hardware support for the Sega Saturn.
5 *
6 * Copyright (c) 2002 Paul Mundt
7 *
8 * Released under the terms of the GNU GPL v2.0.
9 */
10#include <linux/kernel.h>
11#include <linux/init.h>
12
13#include <asm/io.h>
14#include <asm/machvec.h>
15#include <asm/mach/io.h>
16
17extern int saturn_irq_demux(int irq_nr);
18
19const char *get_system_type(void)
20{
21 return "Sega Saturn";
22}
23
24/*
25 * The Machine Vector
26 */
27struct sh_machine_vector mv_saturn __initmv = {
28 .mv_nr_irqs = 80, /* Fix this later */
29
30 .mv_isa_port2addr = saturn_isa_port2addr,
31 .mv_irq_demux = saturn_irq_demux,
32
33 .mv_ioremap = saturn_ioremap,
34 .mv_iounmap = saturn_iounmap,
35};
36
37ALIAS_MV(saturn)
38
39int __init platform_setup(void)
40{
41 return 0;
42}
43
diff --git a/arch/sh/boards/saturn/smp.c b/arch/sh/boards/saturn/smp.c
new file mode 100644
index 000000000000..76460918c9cd
--- /dev/null
+++ b/arch/sh/boards/saturn/smp.c
@@ -0,0 +1,68 @@
1/*
2 * arch/sh/boards/saturn/smp.c
3 *
4 * SMP support for the Sega Saturn.
5 *
6 * Copyright (c) 2002 Paul Mundt
7 *
8 * Released under the terms of the GNU GPL v2.0.
9 */
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/smp.h>
13
14#include <asm/saturn/smpc.h>
15
16extern void start_secondary(void);
17
18void __smp_send_ipi(unsigned int cpu, unsigned int action)
19{
20 /* Nothing here yet .. */
21}
22
23unsigned int __smp_probe_cpus(void)
24{
25 /*
26 * This is just a straightforward master/slave configuration,
27 * and probing isn't really supported..
28 */
29 return 2;
30}
31
32/*
33 * We're only allowed to do byte-access to SMPC registers. In
34 * addition to which, we treat them as write-only, since
35 * reading from them will return undefined data.
36 */
37static inline void smpc_slave_stop(unsigned int cpu)
38{
39 smpc_barrier();
40 ctrl_outb(1, SMPC_STATUS);
41
42 ctrl_outb(SMPC_CMD_SSHOFF, SMPC_COMMAND);
43 smpc_barrier();
44}
45
46static inline void smpc_slave_start(unsigned int cpu)
47{
48 ctrl_outb(1, SMPC_STATUS);
49 ctrl_outb(SMPC_CMD_SSHON, SMPC_COMMAND);
50
51 smpc_barrier();
52}
53
54void __smp_slave_init(unsigned int cpu)
55{
56 register unsigned long vbr;
57 void **entry;
58
59 __asm__ __volatile__ ("stc vbr, %0\n\t" : "=r" (vbr));
60 entry = (void **)(vbr + 0x310 + 0x94);
61
62 smpc_slave_stop(cpu);
63
64 *(void **)entry = (void *)start_secondary;
65
66 smpc_slave_start(cpu);
67}
68
diff --git a/arch/sh/boards/se/7300/Makefile b/arch/sh/boards/se/7300/Makefile
new file mode 100644
index 000000000000..0fbd4f47815c
--- /dev/null
+++ b/arch/sh/boards/se/7300/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the 7300 SolutionEngine specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6
7obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/7300/io.c b/arch/sh/boards/se/7300/io.c
new file mode 100644
index 000000000000..3c89def46480
--- /dev/null
+++ b/arch/sh/boards/se/7300/io.c
@@ -0,0 +1,265 @@
1/*
2 * arch/sh/boards/se/7300/io.c
3 *
4 * Copyright (C) 2003 YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
5 * Based on arch/sh/kernel/io_shmse.c
6 *
7 * I/O routine for SH-Mobile3 73180 SolutionEngine.
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <asm/mach/se7300.h>
14#include <asm/io.h>
15
16#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
17
18struct iop {
19 unsigned long start, end;
20 unsigned long base;
21 struct iop *(*check) (struct iop * p, unsigned long port);
22 unsigned char (*inb) (struct iop * p, unsigned long port);
23 unsigned short (*inw) (struct iop * p, unsigned long port);
24 void (*outb) (struct iop * p, unsigned char value, unsigned long port);
25 void (*outw) (struct iop * p, unsigned short value, unsigned long port);
26};
27
28struct iop *
29simple_check(struct iop *p, unsigned long port)
30{
31 if ((p->start <= port) && (port <= p->end))
32 return p;
33 else
34 badio(check, port);
35}
36
37struct iop *
38ide_check(struct iop *p, unsigned long port)
39{
40 if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
41 return p;
42 return NULL;
43}
44
45unsigned char
46simple_inb(struct iop *p, unsigned long port)
47{
48 return *(unsigned char *) (p->base + port);
49}
50
51unsigned short
52simple_inw(struct iop *p, unsigned long port)
53{
54 return *(unsigned short *) (p->base + port);
55}
56
57void
58simple_outb(struct iop *p, unsigned char value, unsigned long port)
59{
60 *(unsigned char *) (p->base + port) = value;
61}
62
63void
64simple_outw(struct iop *p, unsigned short value, unsigned long port)
65{
66 *(unsigned short *) (p->base + port) = value;
67}
68
69unsigned char
70pcc_inb(struct iop *p, unsigned long port)
71{
72 unsigned long addr = p->base + port + 0x40000;
73 unsigned long v;
74
75 if (port & 1)
76 addr += 0x00400000;
77 v = *(volatile unsigned char *) addr;
78 return v;
79}
80
81void
82pcc_outb(struct iop *p, unsigned char value, unsigned long port)
83{
84 unsigned long addr = p->base + port + 0x40000;
85
86 if (port & 1)
87 addr += 0x00400000;
88 *(volatile unsigned char *) addr = value;
89}
90
91unsigned char
92bad_inb(struct iop *p, unsigned long port)
93{
94 badio(inb, port);
95}
96
97void
98bad_outb(struct iop *p, unsigned char value, unsigned long port)
99{
100 badio(inw, port);
101}
102
103/* MSTLANEX01 LAN at 0xb400:0000 */
104static struct iop laniop = {
105 .start = 0x300,
106 .end = 0x30f,
107 .base = 0xb4000000,
108 .check = simple_check,
109 .inb = simple_inb,
110 .inw = simple_inw,
111 .outb = simple_outb,
112 .outw = simple_outw,
113};
114
115/* NE2000 pc card NIC */
116static struct iop neiop = {
117 .start = 0x280,
118 .end = 0x29f,
119 .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
120 .check = simple_check,
121 .inb = pcc_inb,
122 .inw = simple_inw,
123 .outb = pcc_outb,
124 .outw = simple_outw,
125};
126
127/* CF in CF slot */
128static struct iop cfiop = {
129 .base = 0xb0600000,
130 .check = ide_check,
131 .inb = pcc_inb,
132 .inw = simple_inw,
133 .outb = pcc_outb,
134 .outw = simple_outw,
135};
136
137static __inline__ struct iop *
138port2iop(unsigned long port)
139{
140 if (0) ;
141#if defined(CONFIG_SMC91111)
142 else if (laniop.check(&laniop, port))
143 return &laniop;
144#endif
145#if defined(CONFIG_NE2000)
146 else if (neiop.check(&neiop, port))
147 return &neiop;
148#endif
149#if defined(CONFIG_IDE)
150 else if (cfiop.check(&cfiop, port))
151 return &cfiop;
152#endif
153 else
154 return &neiop; /* fallback */
155}
156
157static inline void
158delay(void)
159{
160 ctrl_inw(0xac000000);
161 ctrl_inw(0xac000000);
162}
163
164unsigned char
165sh7300se_inb(unsigned long port)
166{
167 struct iop *p = port2iop(port);
168 return (p->inb) (p, port);
169}
170
171unsigned char
172sh7300se_inb_p(unsigned long port)
173{
174 unsigned char v = sh7300se_inb(port);
175 delay();
176 return v;
177}
178
179unsigned short
180sh7300se_inw(unsigned long port)
181{
182 struct iop *p = port2iop(port);
183 return (p->inw) (p, port);
184}
185
186unsigned int
187sh7300se_inl(unsigned long port)
188{
189 badio(inl, port);
190}
191
192void
193sh7300se_outb(unsigned char value, unsigned long port)
194{
195 struct iop *p = port2iop(port);
196 (p->outb) (p, value, port);
197}
198
199void
200sh7300se_outb_p(unsigned char value, unsigned long port)
201{
202 sh7300se_outb(value, port);
203 delay();
204}
205
206void
207sh7300se_outw(unsigned short value, unsigned long port)
208{
209 struct iop *p = port2iop(port);
210 (p->outw) (p, value, port);
211}
212
213void
214sh7300se_outl(unsigned int value, unsigned long port)
215{
216 badio(outl, port);
217}
218
219void
220sh7300se_insb(unsigned long port, void *addr, unsigned long count)
221{
222 unsigned char *a = addr;
223 struct iop *p = port2iop(port);
224 while (count--)
225 *a++ = (p->inb) (p, port);
226}
227
228void
229sh7300se_insw(unsigned long port, void *addr, unsigned long count)
230{
231 unsigned short *a = addr;
232 struct iop *p = port2iop(port);
233 while (count--)
234 *a++ = (p->inw) (p, port);
235}
236
237void
238sh7300se_insl(unsigned long port, void *addr, unsigned long count)
239{
240 badio(insl, port);
241}
242
243void
244sh7300se_outsb(unsigned long port, const void *addr, unsigned long count)
245{
246 unsigned char *a = (unsigned char *) addr;
247 struct iop *p = port2iop(port);
248 while (count--)
249 (p->outb) (p, *a++, port);
250}
251
252void
253sh7300se_outsw(unsigned long port, const void *addr, unsigned long count)
254{
255 unsigned short *a = (unsigned short *) addr;
256 struct iop *p = port2iop(port);
257 while (count--)
258 (p->outw) (p, *a++, port);
259}
260
261void
262sh7300se_outsl(unsigned long port, const void *addr, unsigned long count)
263{
264 badio(outsw, port);
265}
diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c
new file mode 100644
index 000000000000..96c8c23d6c93
--- /dev/null
+++ b/arch/sh/boards/se/7300/irq.c
@@ -0,0 +1,37 @@
1/*
2 * linux/arch/sh/boards/se/7300/irq.c
3 *
4 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
5 *
6 * SH-Mobile SolutionEngine 7300 Support.
7 *
8 */
9
10#include <linux/config.h>
11#include <linux/init.h>
12#include <linux/irq.h>
13#include <asm/irq.h>
14#include <asm/io.h>
15#include <asm/mach/se7300.h>
16
17/*
18 * Initialize IRQ setting
19 */
20void __init
21init_7300se_IRQ(void)
22{
23 ctrl_outw(0x0028, PA_EPLD_MODESET); /* mode set IRQ0,1 active low. */
24 ctrl_outw(0xa000, INTC_ICR1); /* IRQ mode; IRQ0,1 enable. */
25 ctrl_outw(0x0000, PORT_PFCR); /* use F for IRQ[3:0] and SIU. */
26
27 /* PC_IRQ[0-3] -> IRQ0 (32) */
28 make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ);
29 /* A_IRQ[0-3] -> IRQ1 (33) */
30 make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ);
31 make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
32 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
33 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
34 make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
35
36 ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */
37}
diff --git a/arch/sh/boards/se/7300/led.c b/arch/sh/boards/se/7300/led.c
new file mode 100644
index 000000000000..02c7f846c84c
--- /dev/null
+++ b/arch/sh/boards/se/7300/led.c
@@ -0,0 +1,69 @@
1/*
2 * linux/arch/sh/boards/se/7300/led.c
3 *
4 * Derived from linux/arch/sh/boards/se/770x/led.c
5 *
6 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * This file contains Solution Engine specific LED code.
12 */
13
14#include <linux/config.h>
15#include <linux/sched.h>
16#include <asm/mach/se7300.h>
17
18static void
19mach_led(int position, int value)
20{
21 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
22
23 if (value) {
24 *p |= (1 << 8);
25 } else {
26 *p &= ~(1 << 8);
27 }
28}
29
30
31/* Cycle the LED's in the clasic Knightrider/Sun pattern */
32void
33heartbeat_7300se(void)
34{
35 static unsigned int cnt = 0, period = 0;
36 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
37 static unsigned bit = 0, up = 1;
38
39 cnt += 1;
40 if (cnt < period) {
41 return;
42 }
43
44 cnt = 0;
45
46 /* Go through the points (roughly!):
47 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
48 */
49 period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
50
51 if (up) {
52 if (bit == 7) {
53 bit--;
54 up = 0;
55 } else {
56 bit++;
57 }
58 } else {
59 if (bit == 0) {
60 bit++;
61 up = 1;
62 } else {
63 bit--;
64 }
65 }
66 *p = 1 << (bit + 8);
67
68}
69
diff --git a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c
new file mode 100644
index 000000000000..08536bc224dc
--- /dev/null
+++ b/arch/sh/boards/se/7300/setup.c
@@ -0,0 +1,66 @@
1/*
2 * linux/arch/sh/boards/se/7300/setup.c
3 *
4 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
5 *
6 * SH-Mobile SolutionEngine 7300 Support.
7 *
8 */
9
10#include <linux/config.h>
11#include <linux/init.h>
12#include <asm/machvec.h>
13#include <asm/machvec_init.h>
14#include <asm/mach/io.h>
15
16void heartbeat_7300se(void);
17void init_7300se_IRQ(void);
18
19const char *
20get_system_type(void)
21{
22 return "SolutionEngine 7300";
23}
24
25/*
26 * The Machine Vector
27 */
28
29struct sh_machine_vector mv_7300se __initmv = {
30 .mv_nr_irqs = 109,
31 .mv_inb = sh7300se_inb,
32 .mv_inw = sh7300se_inw,
33 .mv_inl = sh7300se_inl,
34 .mv_outb = sh7300se_outb,
35 .mv_outw = sh7300se_outw,
36 .mv_outl = sh7300se_outl,
37
38 .mv_inb_p = sh7300se_inb_p,
39 .mv_inw_p = sh7300se_inw,
40 .mv_inl_p = sh7300se_inl,
41 .mv_outb_p = sh7300se_outb_p,
42 .mv_outw_p = sh7300se_outw,
43 .mv_outl_p = sh7300se_outl,
44
45 .mv_insb = sh7300se_insb,
46 .mv_insw = sh7300se_insw,
47 .mv_insl = sh7300se_insl,
48 .mv_outsb = sh7300se_outsb,
49 .mv_outsw = sh7300se_outsw,
50 .mv_outsl = sh7300se_outsl,
51
52 .mv_init_irq = init_7300se_IRQ,
53#ifdef CONFIG_HEARTBEAT
54 .mv_heartbeat = heartbeat_7300se,
55#endif
56};
57
58ALIAS_MV(7300se)
59/*
60 * Initialize the board
61 */
62void __init
63platform_setup(void)
64{
65
66}
diff --git a/arch/sh/boards/se/73180/Makefile b/arch/sh/boards/se/73180/Makefile
new file mode 100644
index 000000000000..8f63886a0f3f
--- /dev/null
+++ b/arch/sh/boards/se/73180/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the 73180 SolutionEngine specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6
7obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/73180/io.c b/arch/sh/boards/se/73180/io.c
new file mode 100644
index 000000000000..73648cbe3678
--- /dev/null
+++ b/arch/sh/boards/se/73180/io.c
@@ -0,0 +1,265 @@
1/*
2 * arch/sh/boards/se/73180/io.c
3 *
4 * Copyright (C) 2003 YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
5 * Based on arch/sh/boards/se/7300/io.c
6 *
7 * I/O routine for SH-Mobile3 73180 SolutionEngine.
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <asm/mach/se73180.h>
14#include <asm/io.h>
15
16#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
17
18struct iop {
19 unsigned long start, end;
20 unsigned long base;
21 struct iop *(*check) (struct iop * p, unsigned long port);
22 unsigned char (*inb) (struct iop * p, unsigned long port);
23 unsigned short (*inw) (struct iop * p, unsigned long port);
24 void (*outb) (struct iop * p, unsigned char value, unsigned long port);
25 void (*outw) (struct iop * p, unsigned short value, unsigned long port);
26};
27
28struct iop *
29simple_check(struct iop *p, unsigned long port)
30{
31 if ((p->start <= port) && (port <= p->end))
32 return p;
33 else
34 badio(check, port);
35}
36
37struct iop *
38ide_check(struct iop *p, unsigned long port)
39{
40 if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
41 return p;
42 return NULL;
43}
44
45unsigned char
46simple_inb(struct iop *p, unsigned long port)
47{
48 return *(unsigned char *) (p->base + port);
49}
50
51unsigned short
52simple_inw(struct iop *p, unsigned long port)
53{
54 return *(unsigned short *) (p->base + port);
55}
56
57void
58simple_outb(struct iop *p, unsigned char value, unsigned long port)
59{
60 *(unsigned char *) (p->base + port) = value;
61}
62
63void
64simple_outw(struct iop *p, unsigned short value, unsigned long port)
65{
66 *(unsigned short *) (p->base + port) = value;
67}
68
69unsigned char
70pcc_inb(struct iop *p, unsigned long port)
71{
72 unsigned long addr = p->base + port + 0x40000;
73 unsigned long v;
74
75 if (port & 1)
76 addr += 0x00400000;
77 v = *(volatile unsigned char *) addr;
78 return v;
79}
80
81void
82pcc_outb(struct iop *p, unsigned char value, unsigned long port)
83{
84 unsigned long addr = p->base + port + 0x40000;
85
86 if (port & 1)
87 addr += 0x00400000;
88 *(volatile unsigned char *) addr = value;
89}
90
91unsigned char
92bad_inb(struct iop *p, unsigned long port)
93{
94 badio(inb, port);
95}
96
97void
98bad_outb(struct iop *p, unsigned char value, unsigned long port)
99{
100 badio(inw, port);
101}
102
103/* MSTLANEX01 LAN at 0xb400:0000 */
104static struct iop laniop = {
105 .start = 0x300,
106 .end = 0x30f,
107 .base = 0xb4000000,
108 .check = simple_check,
109 .inb = simple_inb,
110 .inw = simple_inw,
111 .outb = simple_outb,
112 .outw = simple_outw,
113};
114
115/* NE2000 pc card NIC */
116static struct iop neiop = {
117 .start = 0x280,
118 .end = 0x29f,
119 .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
120 .check = simple_check,
121 .inb = pcc_inb,
122 .inw = simple_inw,
123 .outb = pcc_outb,
124 .outw = simple_outw,
125};
126
127/* CF in CF slot */
128static struct iop cfiop = {
129 .base = 0xb0600000,
130 .check = ide_check,
131 .inb = pcc_inb,
132 .inw = simple_inw,
133 .outb = pcc_outb,
134 .outw = simple_outw,
135};
136
137static __inline__ struct iop *
138port2iop(unsigned long port)
139{
140 if (0) ;
141#if defined(CONFIG_SMC91111)
142 else if (laniop.check(&laniop, port))
143 return &laniop;
144#endif
145#if defined(CONFIG_NE2000)
146 else if (neiop.check(&neiop, port))
147 return &neiop;
148#endif
149#if defined(CONFIG_IDE)
150 else if (cfiop.check(&cfiop, port))
151 return &cfiop;
152#endif
153 else
154 return &neiop; /* fallback */
155}
156
157static inline void
158delay(void)
159{
160 ctrl_inw(0xac000000);
161 ctrl_inw(0xac000000);
162}
163
164unsigned char
165sh73180se_inb(unsigned long port)
166{
167 struct iop *p = port2iop(port);
168 return (p->inb) (p, port);
169}
170
171unsigned char
172sh73180se_inb_p(unsigned long port)
173{
174 unsigned char v = sh73180se_inb(port);
175 delay();
176 return v;
177}
178
179unsigned short
180sh73180se_inw(unsigned long port)
181{
182 struct iop *p = port2iop(port);
183 return (p->inw) (p, port);
184}
185
186unsigned int
187sh73180se_inl(unsigned long port)
188{
189 badio(inl, port);
190}
191
192void
193sh73180se_outb(unsigned char value, unsigned long port)
194{
195 struct iop *p = port2iop(port);
196 (p->outb) (p, value, port);
197}
198
199void
200sh73180se_outb_p(unsigned char value, unsigned long port)
201{
202 sh73180se_outb(value, port);
203 delay();
204}
205
206void
207sh73180se_outw(unsigned short value, unsigned long port)
208{
209 struct iop *p = port2iop(port);
210 (p->outw) (p, value, port);
211}
212
213void
214sh73180se_outl(unsigned int value, unsigned long port)
215{
216 badio(outl, port);
217}
218
219void
220sh73180se_insb(unsigned long port, void *addr, unsigned long count)
221{
222 unsigned char *a = addr;
223 struct iop *p = port2iop(port);
224 while (count--)
225 *a++ = (p->inb) (p, port);
226}
227
228void
229sh73180se_insw(unsigned long port, void *addr, unsigned long count)
230{
231 unsigned short *a = addr;
232 struct iop *p = port2iop(port);
233 while (count--)
234 *a++ = (p->inw) (p, port);
235}
236
237void
238sh73180se_insl(unsigned long port, void *addr, unsigned long count)
239{
240 badio(insl, port);
241}
242
243void
244sh73180se_outsb(unsigned long port, const void *addr, unsigned long count)
245{
246 unsigned char *a = (unsigned char *) addr;
247 struct iop *p = port2iop(port);
248 while (count--)
249 (p->outb) (p, *a++, port);
250}
251
252void
253sh73180se_outsw(unsigned long port, const void *addr, unsigned long count)
254{
255 unsigned short *a = (unsigned short *) addr;
256 struct iop *p = port2iop(port);
257 while (count--)
258 (p->outw) (p, *a++, port);
259}
260
261void
262sh73180se_outsl(unsigned long port, const void *addr, unsigned long count)
263{
264 badio(outsw, port);
265}
diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c
new file mode 100644
index 000000000000..70f04caad9a4
--- /dev/null
+++ b/arch/sh/boards/se/73180/irq.c
@@ -0,0 +1,137 @@
1/*
2 * arch/sh/boards/se/73180/irq.c
3 *
4 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
5 * Based on arch/sh/boards/se/7300/irq.c
6 *
7 * Modified for SH-Mobile SolutionEngine 73180 Support
8 * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
9 *
10 *
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/irq.h>
16#include <asm/irq.h>
17#include <asm/io.h>
18#include <asm/mach/se73180.h>
19
20static int
21intreq2irq(int i)
22{
23 if (i == 5)
24 return 10;
25 return 32 + 7 - i;
26}
27
28static int
29irq2intreq(int irq)
30{
31 if (irq == 10)
32 return 5;
33 return 7 - (irq - 32);
34}
35
36static void
37disable_intreq_irq(unsigned int irq)
38{
39 ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSK0);
40}
41
42static void
43enable_intreq_irq(unsigned int irq)
44{
45 ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSKCLR0);
46}
47
48static void
49mask_and_ack_intreq_irq(unsigned int irq)
50{
51 disable_intreq_irq(irq);
52}
53
54static unsigned int
55startup_intreq_irq(unsigned int irq)
56{
57 enable_intreq_irq(irq);
58 return 0;
59}
60
61static void
62shutdown_intreq_irq(unsigned int irq)
63{
64 disable_intreq_irq(irq);
65}
66
67static void
68end_intreq_irq(unsigned int irq)
69{
70 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
71 enable_intreq_irq(irq);
72}
73
74static struct hw_interrupt_type intreq_irq_type = {
75 .typename = "intreq",
76 .startup = startup_intreq_irq,
77 .shutdown = shutdown_intreq_irq,
78 .enable = enable_intreq_irq,
79 .disable = disable_intreq_irq,
80 .ack = mask_and_ack_intreq_irq,
81 .end = end_intreq_irq
82};
83
84void
85make_intreq_irq(unsigned int irq)
86{
87 disable_irq_nosync(irq);
88 irq_desc[irq].handler = &intreq_irq_type;
89 disable_intreq_irq(irq);
90}
91
92int
93shmse_irq_demux(int irq)
94{
95 if (irq == IRQ5_IRQ)
96 return 10;
97 return irq;
98}
99
100/*
101 * Initialize IRQ setting
102 */
103void __init
104init_73180se_IRQ(void)
105{
106 make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
107
108 ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
109 ctrl_outw(0x2000, 0xb07fffec); /* mrshpc irq enable */
110 ctrl_outl(3 << ((7 - 5) * 4), INTC_INTPRI0); /* irq5 pri=3 */
111 ctrl_outw(2 << ((7 - 5) * 2), INTC_ICR1); /* low-level irq */
112 make_intreq_irq(10);
113
114 make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
115
116 ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */
117
118 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
119 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
120 make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
121 make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
122 make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
123 IIC0_PRIORITY);
124 make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
125 IIC0_PRIORITY);
126 make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
127 make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
128 make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
129
130 /* VIO interrupt */
131 make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
132 make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
133 make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
134
135 make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
136 ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */
137}
diff --git a/arch/sh/boards/se/73180/led.c b/arch/sh/boards/se/73180/led.c
new file mode 100644
index 000000000000..1e8f1cf3e10f
--- /dev/null
+++ b/arch/sh/boards/se/73180/led.c
@@ -0,0 +1,67 @@
1/*
2 * arch/sh/boards/se/73180/led.c
3 *
4 * Derived from arch/sh/boards/se/770x/led.c
5 *
6 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * This file contains Solution Engine specific LED code.
12 */
13
14#include <linux/config.h>
15#include <linux/sched.h>
16#include <asm/mach/se73180.h>
17
18static void
19mach_led(int position, int value)
20{
21 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
22
23 if (value) {
24 *p |= (1 << LED_SHIFT);
25 } else {
26 *p &= ~(1 << LED_SHIFT);
27 }
28}
29
30/* Cycle the LED's in the clasic Knightrider/Sun pattern */
31void
32heartbeat_73180se(void)
33{
34 static unsigned int cnt = 0, period = 0;
35 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
36 static unsigned bit = 0, up = 1;
37
38 cnt += 1;
39 if (cnt < period) {
40 return;
41 }
42
43 cnt = 0;
44
45 /* Go through the points (roughly!):
46 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
47 */
48 period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
49
50 if (up) {
51 if (bit == 7) {
52 bit--;
53 up = 0;
54 } else {
55 bit++;
56 }
57 } else {
58 if (bit == 0) {
59 bit++;
60 up = 1;
61 } else {
62 bit--;
63 }
64 }
65 *p = 1 << (bit + LED_SHIFT);
66
67}
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c
new file mode 100644
index 000000000000..07fa90c38a06
--- /dev/null
+++ b/arch/sh/boards/se/73180/setup.c
@@ -0,0 +1,68 @@
1/*
2 * arch/sh/boards/se/73180/setup.c
3 *
4 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
5 * Based on arch/sh/setup_shmse.c
6 *
7 * Modified for 73180 SolutionEngine
8 * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <asm/machvec.h>
15#include <asm/machvec_init.h>
16#include <asm/mach/io.h>
17
18void heartbeat_73180se(void);
19void init_73180se_IRQ(void);
20
21const char *
22get_system_type(void)
23{
24 return "SolutionEngine 73180";
25}
26
27/*
28 * The Machine Vector
29 */
30
31struct sh_machine_vector mv_73180se __initmv = {
32 .mv_nr_irqs = 108,
33 .mv_inb = sh73180se_inb,
34 .mv_inw = sh73180se_inw,
35 .mv_inl = sh73180se_inl,
36 .mv_outb = sh73180se_outb,
37 .mv_outw = sh73180se_outw,
38 .mv_outl = sh73180se_outl,
39
40 .mv_inb_p = sh73180se_inb_p,
41 .mv_inw_p = sh73180se_inw,
42 .mv_inl_p = sh73180se_inl,
43 .mv_outb_p = sh73180se_outb_p,
44 .mv_outw_p = sh73180se_outw,
45 .mv_outl_p = sh73180se_outl,
46
47 .mv_insb = sh73180se_insb,
48 .mv_insw = sh73180se_insw,
49 .mv_insl = sh73180se_insl,
50 .mv_outsb = sh73180se_outsb,
51 .mv_outsw = sh73180se_outsw,
52 .mv_outsl = sh73180se_outsl,
53
54 .mv_init_irq = init_73180se_IRQ,
55#ifdef CONFIG_HEARTBEAT
56 .mv_heartbeat = heartbeat_73180se,
57#endif
58};
59
60ALIAS_MV(73180se)
61/*
62 * Initialize the board
63 */
64void __init
65platform_setup(void)
66{
67
68}
diff --git a/arch/sh/boards/se/770x/Makefile b/arch/sh/boards/se/770x/Makefile
new file mode 100644
index 000000000000..be89a73cc418
--- /dev/null
+++ b/arch/sh/boards/se/770x/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the 770x SolutionEngine specific parts of the kernel
3#
4
5obj-y := mach.o setup.o io.o irq.o led.o
6
diff --git a/arch/sh/boards/se/770x/io.c b/arch/sh/boards/se/770x/io.c
new file mode 100644
index 000000000000..9a39ee963143
--- /dev/null
+++ b/arch/sh/boards/se/770x/io.c
@@ -0,0 +1,226 @@
1/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
2 *
3 * linux/arch/sh/kernel/io_se.c
4 *
5 * Copyright (C) 2000 Kazumoto Kojima
6 *
7 * I/O routine for Hitachi SolutionEngine.
8 *
9 */
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <asm/io.h>
14#include <asm/se/se.h>
15
16/* SH pcmcia io window base, start and end. */
17int sh_pcic_io_wbase = 0xb8400000;
18int sh_pcic_io_start;
19int sh_pcic_io_stop;
20int sh_pcic_io_type;
21int sh_pcic_io_dummy;
22
23static inline void delay(void)
24{
25 ctrl_inw(0xa0000000);
26}
27
28/* MS7750 requires special versions of in*, out* routines, since
29 PC-like io ports are located at upper half byte of 16-bit word which
30 can be accessed only with 16-bit wide. */
31
32static inline volatile __u16 *
33port2adr(unsigned int port)
34{
35 if (port >= 0x2000)
36 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
37 else if (port >= 0x1000)
38 return (volatile __u16 *) (PA_83902 + (port << 1));
39 else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
40 return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1));
41 else
42 return (volatile __u16 *) (PA_SUPERIO + (port << 1));
43}
44
45static inline int
46shifted_port(unsigned long port)
47{
48 /* For IDE registers, value is not shifted */
49 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
50 return 0;
51 else
52 return 1;
53}
54
55#define maybebadio(name,port) \
56 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
57 #name, (port), (__u32) __builtin_return_address(0))
58
59unsigned char se_inb(unsigned long port)
60{
61 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
62 return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
63 else if (shifted_port(port))
64 return (*port2adr(port) >> 8);
65 else
66 return (*port2adr(port))&0xff;
67}
68
69unsigned char se_inb_p(unsigned long port)
70{
71 unsigned long v;
72
73 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
74 v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
75 else if (shifted_port(port))
76 v = (*port2adr(port) >> 8);
77 else
78 v = (*port2adr(port))&0xff;
79 delay();
80 return v;
81}
82
83unsigned short se_inw(unsigned long port)
84{
85 if (port >= 0x2000 ||
86 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
87 return *port2adr(port);
88 else
89 maybebadio(inw, port);
90 return 0;
91}
92
93unsigned int se_inl(unsigned long port)
94{
95 maybebadio(inl, port);
96 return 0;
97}
98
99void se_outb(unsigned char value, unsigned long port)
100{
101 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
102 *(__u8 *)(sh_pcic_io_wbase + port) = value;
103 else if (shifted_port(port))
104 *(port2adr(port)) = value << 8;
105 else
106 *(port2adr(port)) = value;
107}
108
109void se_outb_p(unsigned char value, unsigned long port)
110{
111 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
112 *(__u8 *)(sh_pcic_io_wbase + port) = value;
113 else if (shifted_port(port))
114 *(port2adr(port)) = value << 8;
115 else
116 *(port2adr(port)) = value;
117 delay();
118}
119
120void se_outw(unsigned short value, unsigned long port)
121{
122 if (port >= 0x2000 ||
123 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
124 *port2adr(port) = value;
125 else
126 maybebadio(outw, port);
127}
128
129void se_outl(unsigned int value, unsigned long port)
130{
131 maybebadio(outl, port);
132}
133
134void se_insb(unsigned long port, void *addr, unsigned long count)
135{
136 volatile __u16 *p = port2adr(port);
137 __u8 *ap = addr;
138
139 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
140 volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
141 while (count--)
142 *ap++ = *bp;
143 } else if (shifted_port(port)) {
144 while (count--)
145 *ap++ = *p >> 8;
146 } else {
147 while (count--)
148 *ap++ = *p;
149 }
150}
151
152void se_insw(unsigned long port, void *addr, unsigned long count)
153{
154 volatile __u16 *p = port2adr(port);
155 __u16 *ap = addr;
156 while (count--)
157 *ap++ = *p;
158}
159
160void se_insl(unsigned long port, void *addr, unsigned long count)
161{
162 maybebadio(insl, port);
163}
164
165void se_outsb(unsigned long port, const void *addr, unsigned long count)
166{
167 volatile __u16 *p = port2adr(port);
168 const __u8 *ap = addr;
169
170 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
171 volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port);
172 while (count--)
173 *bp = *ap++;
174 } else if (shifted_port(port)) {
175 while (count--)
176 *p = *ap++ << 8;
177 } else {
178 while (count--)
179 *p = *ap++;
180 }
181}
182
183void se_outsw(unsigned long port, const void *addr, unsigned long count)
184{
185 volatile __u16 *p = port2adr(port);
186 const __u16 *ap = addr;
187 while (count--)
188 *p = *ap++;
189}
190
191void se_outsl(unsigned long port, const void *addr, unsigned long count)
192{
193 maybebadio(outsw, port);
194}
195
196/* Map ISA bus address to the real address. Only for PCMCIA. */
197
198/* ISA page descriptor. */
199static __u32 sh_isa_memmap[256];
200
201static int
202sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
203{
204 int idx;
205
206 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
207 return -1;
208
209 idx = start >> 12;
210 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
211#if 0
212 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
213 start, length, offset, idx, sh_isa_memmap[idx]);
214#endif
215 return 0;
216}
217
218unsigned long
219se_isa_port2addr(unsigned long offset)
220{
221 int idx;
222
223 idx = (offset >> 12) & 0xff;
224 offset &= 0xfff;
225 return sh_isa_memmap[idx] + offset;
226}
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
new file mode 100644
index 000000000000..210897b315f4
--- /dev/null
+++ b/arch/sh/boards/se/770x/irq.c
@@ -0,0 +1,80 @@
1/*
2 * linux/arch/sh/boards/se/770x/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Hitachi SolutionEngine Support.
7 *
8 */
9
10#include <linux/config.h>
11#include <linux/init.h>
12#include <linux/irq.h>
13#include <asm/irq.h>
14#include <asm/io.h>
15#include <asm/se/se.h>
16
17/*
18 * Initialize IRQ setting
19 */
20void __init init_se_IRQ(void)
21{
22 /*
23 * Super I/O (Just mimic PC):
24 * 1: keyboard
25 * 3: serial 0
26 * 4: serial 1
27 * 5: printer
28 * 6: floppy
29 * 8: rtc
30 * 12: mouse
31 * 14: ide0
32 */
33#if defined(CONFIG_CPU_SUBTYPE_SH7705)
34 /* Disable all interrupts */
35 ctrl_outw(0, BCR_ILCRA);
36 ctrl_outw(0, BCR_ILCRB);
37 ctrl_outw(0, BCR_ILCRC);
38 ctrl_outw(0, BCR_ILCRD);
39 ctrl_outw(0, BCR_ILCRE);
40 ctrl_outw(0, BCR_ILCRF);
41 ctrl_outw(0, BCR_ILCRG);
42 /* This is default value */
43 make_ipr_irq(0xf-0x2, BCR_ILCRA, 2, 0x2);
44 make_ipr_irq(0xf-0xa, BCR_ILCRA, 1, 0xa);
45 make_ipr_irq(0xf-0x5, BCR_ILCRB, 0, 0x5);
46 make_ipr_irq(0xf-0x8, BCR_ILCRC, 1, 0x8);
47 make_ipr_irq(0xf-0xc, BCR_ILCRC, 0, 0xc);
48 make_ipr_irq(0xf-0xe, BCR_ILCRD, 3, 0xe);
49 make_ipr_irq(0xf-0x3, BCR_ILCRD, 1, 0x3); /* LAN */
50 make_ipr_irq(0xf-0xd, BCR_ILCRE, 2, 0xd);
51 make_ipr_irq(0xf-0x9, BCR_ILCRE, 1, 0x9);
52 make_ipr_irq(0xf-0x1, BCR_ILCRE, 0, 0x1);
53 make_ipr_irq(0xf-0xf, BCR_ILCRF, 3, 0xf);
54 make_ipr_irq(0xf-0xb, BCR_ILCRF, 1, 0xb);
55 make_ipr_irq(0xf-0x7, BCR_ILCRG, 3, 0x7);
56 make_ipr_irq(0xf-0x6, BCR_ILCRG, 2, 0x6);
57 make_ipr_irq(0xf-0x4, BCR_ILCRG, 1, 0x4);
58#else
59 make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
60 make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
61 make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
62 make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
63 make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
64 make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
65 make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
66 make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
67
68 make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
69
70 make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
71 make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
72 make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
73 make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
74
75 /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
76 /* NOTE: #2 and #13 are not used on PC */
77 make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
78 make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
79#endif
80}
diff --git a/arch/sh/boards/se/770x/led.c b/arch/sh/boards/se/770x/led.c
new file mode 100644
index 000000000000..5c64e8ab2cfb
--- /dev/null
+++ b/arch/sh/boards/se/770x/led.c
@@ -0,0 +1,68 @@
1/*
2 * linux/arch/sh/kernel/led_se.c
3 *
4 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains Solution Engine specific LED code.
10 */
11
12#include <linux/config.h>
13#include <asm/se/se.h>
14
15static void mach_led(int position, int value)
16{
17 volatile unsigned short* p = (volatile unsigned short*)PA_LED;
18
19 if (value) {
20 *p |= (1<<8);
21 } else {
22 *p &= ~(1<<8);
23 }
24}
25
26#ifdef CONFIG_HEARTBEAT
27
28#include <linux/sched.h>
29
30/* Cycle the LED's in the clasic Knightrider/Sun pattern */
31void heartbeat_se(void)
32{
33 static unsigned int cnt = 0, period = 0;
34 volatile unsigned short* p = (volatile unsigned short*)PA_LED;
35 static unsigned bit = 0, up = 1;
36
37 cnt += 1;
38 if (cnt < period) {
39 return;
40 }
41
42 cnt = 0;
43
44 /* Go through the points (roughly!):
45 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
46 */
47 period = 110 - ( (300<<FSHIFT)/
48 ((avenrun[0]/5) + (3<<FSHIFT)) );
49
50 if (up) {
51 if (bit == 7) {
52 bit--;
53 up=0;
54 } else {
55 bit ++;
56 }
57 } else {
58 if (bit == 0) {
59 bit++;
60 up=1;
61 } else {
62 bit--;
63 }
64 }
65 *p = 1<<(bit+8);
66
67}
68#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/se/770x/mach.c b/arch/sh/boards/se/770x/mach.c
new file mode 100644
index 000000000000..f9b4c56cc47e
--- /dev/null
+++ b/arch/sh/boards/se/770x/mach.c
@@ -0,0 +1,68 @@
1/*
2 * linux/arch/sh/kernel/mach_se.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Hitachi SolutionEngine
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14
15#include <asm/machvec.h>
16#include <asm/rtc.h>
17#include <asm/machvec_init.h>
18
19#include <asm/se/io.h>
20
21void heartbeat_se(void);
22void setup_se(void);
23void init_se_IRQ(void);
24
25/*
26 * The Machine Vector
27 */
28
29struct sh_machine_vector mv_se __initmv = {
30#if defined(CONFIG_CPU_SH4)
31 .mv_nr_irqs = 48,
32#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
33 .mv_nr_irqs = 32,
34#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
35 .mv_nr_irqs = 61,
36#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
37 .mv_nr_irqs = 86,
38#endif
39
40 .mv_inb = se_inb,
41 .mv_inw = se_inw,
42 .mv_inl = se_inl,
43 .mv_outb = se_outb,
44 .mv_outw = se_outw,
45 .mv_outl = se_outl,
46
47 .mv_inb_p = se_inb_p,
48 .mv_inw_p = se_inw,
49 .mv_inl_p = se_inl,
50 .mv_outb_p = se_outb_p,
51 .mv_outw_p = se_outw,
52 .mv_outl_p = se_outl,
53
54 .mv_insb = se_insb,
55 .mv_insw = se_insw,
56 .mv_insl = se_insl,
57 .mv_outsb = se_outsb,
58 .mv_outsw = se_outsw,
59 .mv_outsl = se_outsl,
60
61 .mv_isa_port2addr = se_isa_port2addr,
62
63 .mv_init_irq = init_se_IRQ,
64#ifdef CONFIG_HEARTBEAT
65 .mv_heartbeat = heartbeat_se,
66#endif
67};
68ALIAS_MV(se)
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
new file mode 100644
index 000000000000..2bed46fb607d
--- /dev/null
+++ b/arch/sh/boards/se/770x/setup.c
@@ -0,0 +1,85 @@
1/* $Id: setup.c,v 1.1.2.4 2002/03/02 21:57:07 lethal Exp $
2 *
3 * linux/arch/sh/boards/se/770x/setup.c
4 *
5 * Copyright (C) 2000 Kazumoto Kojima
6 *
7 * Hitachi SolutionEngine Support.
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/init.h>
13#include <linux/irq.h>
14
15#include <linux/hdreg.h>
16#include <linux/ide.h>
17#include <asm/io.h>
18#include <asm/se/se.h>
19#include <asm/se/smc37c93x.h>
20
21/*
22 * Configure the Super I/O chip
23 */
24static void __init smsc_config(int index, int data)
25{
26 outb_p(index, INDEX_PORT);
27 outb_p(data, DATA_PORT);
28}
29
30static void __init init_smsc(void)
31{
32 outb_p(CONFIG_ENTER, CONFIG_PORT);
33 outb_p(CONFIG_ENTER, CONFIG_PORT);
34
35 /* FDC */
36 smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
37 smsc_config(ACTIVATE_INDEX, 0x01);
38 smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
39
40 /* IDE1 */
41 smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
42 smsc_config(ACTIVATE_INDEX, 0x01);
43 smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
44
45 /* AUXIO (GPIO): to use IDE1 */
46 smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
47 smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
48 smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
49
50 /* COM1 */
51 smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
52 smsc_config(ACTIVATE_INDEX, 0x01);
53 smsc_config(IO_BASE_HI_INDEX, 0x03);
54 smsc_config(IO_BASE_LO_INDEX, 0xf8);
55 smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
56
57 /* COM2 */
58 smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
59 smsc_config(ACTIVATE_INDEX, 0x01);
60 smsc_config(IO_BASE_HI_INDEX, 0x02);
61 smsc_config(IO_BASE_LO_INDEX, 0xf8);
62 smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
63
64 /* RTC */
65 smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
66 smsc_config(ACTIVATE_INDEX, 0x01);
67 smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
68
69 /* XXX: PARPORT, KBD, and MOUSE will come here... */
70 outb_p(CONFIG_EXIT, CONFIG_PORT);
71}
72
73const char *get_system_type(void)
74{
75 return "SolutionEngine";
76}
77
78/*
79 * Initialize the board
80 */
81void __init platform_setup(void)
82{
83 init_smsc();
84 /* XXX: RTC setting comes here */
85}
diff --git a/arch/sh/boards/se/7751/Makefile b/arch/sh/boards/se/7751/Makefile
new file mode 100644
index 000000000000..ce7ca247f84d
--- /dev/null
+++ b/arch/sh/boards/se/7751/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the 7751 SolutionEngine specific parts of the kernel
3#
4
5obj-y := mach.o setup.o io.o irq.o led.o
6
7obj-$(CONFIG_PCI) += pci.o
8
diff --git a/arch/sh/boards/se/7751/io.c b/arch/sh/boards/se/7751/io.c
new file mode 100644
index 000000000000..99041b269261
--- /dev/null
+++ b/arch/sh/boards/se/7751/io.c
@@ -0,0 +1,244 @@
1/*
2 * linux/arch/sh/kernel/io_7751se.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for Hitachi 7751 SolutionEngine.
8 *
9 * Initial version only to support LAN access; some
10 * placeholder code from io_se.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
12 */
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <asm/io.h>
17#include <asm/se7751/se7751.h>
18#include <asm/addrspace.h>
19
20#include <linux/pci.h>
21#include "../../../drivers/pci/pci-sh7751.h"
22
23#if 0
24/******************************************************************
25 * Variables from io_se.c, related to PCMCIA (not PCI); we're not
26 * compiling them in, and have removed references from functions
27 * which follow. [Many checked for IO ports in the range bounded
28 * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset.
29 * As start/stop are uninitialized, only port 0x0 would match?]
30 * When used, remember to adjust names to avoid clash with io_se?
31 *****************************************************************/
32/* SH pcmcia io window base, start and end. */
33int sh_pcic_io_wbase = 0xb8400000;
34int sh_pcic_io_start;
35int sh_pcic_io_stop;
36int sh_pcic_io_type;
37int sh_pcic_io_dummy;
38/*************************************************************/
39#endif
40
41/*
42 * The 7751 Solution Engine uses the built-in PCI controller (PCIC)
43 * of the 7751 processor, and has a SuperIO accessible via the PCI.
44 * The board also includes a PCMCIA controller on its memory bus,
45 * like the other Solution Engine boards.
46 */
47
48#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
49#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
50#define PCI_IO_AREA SH7751_PCI_IO_BASE
51#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
52
53#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
54
55#define maybebadio(name,port) \
56 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
57 #name, (port), (__u32) __builtin_return_address(0))
58
59static inline void delay(void)
60{
61 ctrl_inw(0xa0000000);
62}
63
64static inline volatile __u16 *
65port2adr(unsigned int port)
66{
67 if (port >= 0x2000)
68 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
69#if 0
70 else
71 return (volatile __u16 *) (PA_SUPERIO + (port << 1));
72#endif
73 maybebadio(name,(unsigned long)port);
74 return (volatile __u16*)port;
75}
76
77#if 0
78/* The 7751 Solution Engine seems to have everything hooked */
79/* up pretty normally (nothing on high-bytes only...) so this */
80/* shouldn't be needed */
81static inline int
82shifted_port(unsigned long port)
83{
84 /* For IDE registers, value is not shifted */
85 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
86 return 0;
87 else
88 return 1;
89}
90#endif
91
92/* In case someone configures the kernel w/o PCI support: in that */
93/* scenario, don't ever bother to check for PCI-window addresses */
94
95/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
96#if defined(CONFIG_PCI)
97#define CHECK_SH7751_PCIIO(port) \
98 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
99#else
100#define CHECK_SH7751_PCIIO(port) (0)
101#endif
102
103/*
104 * General outline: remap really low stuff [eventually] to SuperIO,
105 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
106 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
107 * should be way beyond the window, and is used w/o translation for
108 * compatibility.
109 */
110unsigned char sh7751se_inb(unsigned long port)
111{
112 if (PXSEG(port))
113 return *(volatile unsigned char *)port;
114 else if (CHECK_SH7751_PCIIO(port))
115 return *(volatile unsigned char *)PCI_IOMAP(port);
116 else
117 return (*port2adr(port))&0xff;
118}
119
120unsigned char sh7751se_inb_p(unsigned long port)
121{
122 unsigned char v;
123
124 if (PXSEG(port))
125 v = *(volatile unsigned char *)port;
126 else if (CHECK_SH7751_PCIIO(port))
127 v = *(volatile unsigned char *)PCI_IOMAP(port);
128 else
129 v = (*port2adr(port))&0xff;
130 delay();
131 return v;
132}
133
134unsigned short sh7751se_inw(unsigned long port)
135{
136 if (PXSEG(port))
137 return *(volatile unsigned short *)port;
138 else if (CHECK_SH7751_PCIIO(port))
139 return *(volatile unsigned short *)PCI_IOMAP(port);
140 else if (port >= 0x2000)
141 return *port2adr(port);
142 else
143 maybebadio(inw, port);
144 return 0;
145}
146
147unsigned int sh7751se_inl(unsigned long port)
148{
149 if (PXSEG(port))
150 return *(volatile unsigned long *)port;
151 else if (CHECK_SH7751_PCIIO(port))
152 return *(volatile unsigned int *)PCI_IOMAP(port);
153 else if (port >= 0x2000)
154 return *port2adr(port);
155 else
156 maybebadio(inl, port);
157 return 0;
158}
159
160void sh7751se_outb(unsigned char value, unsigned long port)
161{
162
163 if (PXSEG(port))
164 *(volatile unsigned char *)port = value;
165 else if (CHECK_SH7751_PCIIO(port))
166 *((unsigned char*)PCI_IOMAP(port)) = value;
167 else
168 *(port2adr(port)) = value;
169}
170
171void sh7751se_outb_p(unsigned char value, unsigned long port)
172{
173 if (PXSEG(port))
174 *(volatile unsigned char *)port = value;
175 else if (CHECK_SH7751_PCIIO(port))
176 *((unsigned char*)PCI_IOMAP(port)) = value;
177 else
178 *(port2adr(port)) = value;
179 delay();
180}
181
182void sh7751se_outw(unsigned short value, unsigned long port)
183{
184 if (PXSEG(port))
185 *(volatile unsigned short *)port = value;
186 else if (CHECK_SH7751_PCIIO(port))
187 *((unsigned short *)PCI_IOMAP(port)) = value;
188 else if (port >= 0x2000)
189 *port2adr(port) = value;
190 else
191 maybebadio(outw, port);
192}
193
194void sh7751se_outl(unsigned int value, unsigned long port)
195{
196 if (PXSEG(port))
197 *(volatile unsigned long *)port = value;
198 else if (CHECK_SH7751_PCIIO(port))
199 *((unsigned long*)PCI_IOMAP(port)) = value;
200 else
201 maybebadio(outl, port);
202}
203
204void sh7751se_insl(unsigned long port, void *addr, unsigned long count)
205{
206 maybebadio(insl, port);
207}
208
209void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count)
210{
211 maybebadio(outsw, port);
212}
213
214/* Map ISA bus address to the real address. Only for PCMCIA. */
215
216/* ISA page descriptor. */
217static __u32 sh_isa_memmap[256];
218
219#if 0
220static int
221sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
222{
223 int idx;
224
225 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
226 return -1;
227
228 idx = start >> 12;
229 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
230 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
231 start, length, offset, idx, sh_isa_memmap[idx]);
232 return 0;
233}
234#endif
235
236unsigned long
237sh7751se_isa_port2addr(unsigned long offset)
238{
239 int idx;
240
241 idx = (offset >> 12) & 0xff;
242 offset &= 0xfff;
243 return sh_isa_memmap[idx] + offset;
244}
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 @@
1/*
2 * linux/arch/sh/boards/se/7751/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Hitachi SolutionEngine Support.
7 *
8 * Modified for 7751 Solution Engine by
9 * Ian da Silva and Jeremy Siegel, 2001.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15#include <asm/irq.h>
16#include <asm/se7751/se7751.h>
17
18/*
19 * Initialize IRQ setting
20 */
21void __init init_7751se_IRQ(void)
22{
23
24 /* Leave old Solution Engine code in for reference. */
25#if defined(CONFIG_SH_SOLUTION_ENGINE)
26 /*
27 * Super I/O (Just mimic PC):
28 * 1: keyboard
29 * 3: serial 0
30 * 4: serial 1
31 * 5: printer
32 * 6: floppy
33 * 8: rtc
34 * 12: mouse
35 * 14: ide0
36 */
37 make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
38 make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
39 make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
40 make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
41 make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
42 make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
43 make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
44 make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
45
46 make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
47
48 make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
49 make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
50 make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
51 make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
52
53 /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
54 /* NOTE: #2 and #13 are not used on PC */
55 make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
56 make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
57
58#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
59
60 make_ipr_irq(13, BCR_ILCRD, 3, 2);
61
62 /* Add additional calls to make_ipr_irq() as drivers are added
63 * and tested.
64 */
65#endif
66
67}
diff --git a/arch/sh/boards/se/7751/led.c b/arch/sh/boards/se/7751/led.c
new file mode 100644
index 000000000000..0c788230cf8f
--- /dev/null
+++ b/arch/sh/boards/se/7751/led.c
@@ -0,0 +1,68 @@
1/*
2 * linux/arch/sh/kernel/led_se.c
3 *
4 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains Solution Engine specific LED code.
10 */
11
12#include <linux/config.h>
13#include <asm/se7751/se7751.h>
14
15static void mach_led(int position, int value)
16{
17 volatile unsigned short* p = (volatile unsigned short*)PA_LED;
18
19 if (value) {
20 *p |= (1<<8);
21 } else {
22 *p &= ~(1<<8);
23 }
24}
25
26#ifdef CONFIG_HEARTBEAT
27
28#include <linux/sched.h>
29
30/* Cycle the LED's in the clasic Knightrider/Sun pattern */
31void heartbeat_7751se(void)
32{
33 static unsigned int cnt = 0, period = 0;
34 volatile unsigned short* p = (volatile unsigned short*)PA_LED;
35 static unsigned bit = 0, up = 1;
36
37 cnt += 1;
38 if (cnt < period) {
39 return;
40 }
41
42 cnt = 0;
43
44 /* Go through the points (roughly!):
45 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
46 */
47 period = 110 - ( (300<<FSHIFT)/
48 ((avenrun[0]/5) + (3<<FSHIFT)) );
49
50 if (up) {
51 if (bit == 7) {
52 bit--;
53 up=0;
54 } else {
55 bit ++;
56 }
57 } else {
58 if (bit == 0) {
59 bit++;
60 up=1;
61 } else {
62 bit--;
63 }
64 }
65 *p = 1<<(bit+8);
66
67}
68#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/se/7751/mach.c b/arch/sh/boards/se/7751/mach.c
new file mode 100644
index 000000000000..16d386b7e3bf
--- /dev/null
+++ b/arch/sh/boards/se/7751/mach.c
@@ -0,0 +1,55 @@
1/*
2 * linux/arch/sh/kernel/mach_7751se.c
3 *
4 * Minor tweak of mach_se.c file to reference 7751se-specific items.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Hitachi 7751 SolutionEngine
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14
15#include <asm/machvec.h>
16#include <asm/rtc.h>
17#include <asm/machvec_init.h>
18
19#include <asm/se7751/io.h>
20
21void heartbeat_7751se(void);
22void init_7751se_IRQ(void);
23
24/*
25 * The Machine Vector
26 */
27
28struct sh_machine_vector mv_7751se __initmv = {
29 .mv_nr_irqs = 72,
30
31 .mv_inb = sh7751se_inb,
32 .mv_inw = sh7751se_inw,
33 .mv_inl = sh7751se_inl,
34 .mv_outb = sh7751se_outb,
35 .mv_outw = sh7751se_outw,
36 .mv_outl = sh7751se_outl,
37
38 .mv_inb_p = sh7751se_inb_p,
39 .mv_inw_p = sh7751se_inw,
40 .mv_inl_p = sh7751se_inl,
41 .mv_outb_p = sh7751se_outb_p,
42 .mv_outw_p = sh7751se_outw,
43 .mv_outl_p = sh7751se_outl,
44
45 .mv_insl = sh7751se_insl,
46 .mv_outsl = sh7751se_outsl,
47
48 .mv_isa_port2addr = sh7751se_isa_port2addr,
49
50 .mv_init_irq = init_7751se_IRQ,
51#ifdef CONFIG_HEARTBEAT
52 .mv_heartbeat = heartbeat_7751se,
53#endif
54};
55ALIAS_MV(7751se)
diff --git a/arch/sh/boards/se/7751/pci.c b/arch/sh/boards/se/7751/pci.c
new file mode 100644
index 000000000000..1f273efd2cf5
--- /dev/null
+++ b/arch/sh/boards/se/7751/pci.c
@@ -0,0 +1,148 @@
1/*
2 * linux/arch/sh/kernel/pci-7751se.c
3 *
4 * Author: Ian DaSilva (idasilva@mvista.com)
5 *
6 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * PCI initialization for the Hitachi SH7751 Solution Engine board (MS7751SE01)
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <asm/io.h>
22#include "../../../drivers/pci/pci-sh7751.h"
23
24#define PCIMCR_MRSET_OFF 0xBFFFFFFF
25#define PCIMCR_RFSH_OFF 0xFFFFFFFB
26
27/*
28 * Only long word accesses of the PCIC's internal local registers and the
29 * configuration registers from the CPU is supported.
30 */
31#define PCIC_WRITE(x,v) writel((v), PCI_REG(x))
32#define PCIC_READ(x) readl(PCI_REG(x))
33
34/*
35 * Description: This function sets up and initializes the pcic, sets
36 * up the BARS, maps the DRAM into the address space etc, etc.
37 */
38int __init pcibios_init_platform(void)
39{
40 unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
41 unsigned short bcr2;
42
43 /*
44 * Initialize the slave bus controller on the pcic. The values used
45 * here should not be hardcoded, but they should be taken from the bsc
46 * on the processor, to make this function as generic as possible.
47 * (i.e. Another sbc may usr different SDRAM timing settings -- in order
48 * for the pcic to work, its settings need to be exactly the same.)
49 */
50 bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
51 bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
52 wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
53 wcr2 = (*(volatile unsigned long*)(SH7751_WCR2));
54 wcr3 = (*(volatile unsigned long*)(SH7751_WCR3));
55 mcr = (*(volatile unsigned long*)(SH7751_MCR));
56
57 bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */
58 (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1;
59
60 bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
61 PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */
62 PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */
63 PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */
64 PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */
65 PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */
66 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
67 PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */
68
69
70 /* Enable all interrupts, so we know what to fix */
71 PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
72 PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
73
74 /* Set up standard PCI config registers */
75 PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7); /* Bus Master, Mem & I/O access */
76 PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */
77 PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */
78 PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */
79 PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */
80 PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
81 PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */
82 PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */
83 PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */
84 PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */
85
86 /* Now turn it on... */
87 PCIC_WRITE(SH7751_PCICR, 0xa5000001);
88
89 /*
90 * Set PCIMBR and PCIIOBR here, assuming a single window
91 * (16M MEM, 256K IO) is enough. If a larger space is
92 * needed, the readx/writex and inx/outx functions will
93 * have to do more (e.g. setting registers for each call).
94 */
95
96 /*
97 * Set the MBR so PCI address is one-to-one with window,
98 * meaning all calls go straight through... use BUG_ON to
99 * catch erroneous assumption.
100 */
101 BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE);
102
103 PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM);
104
105 /* Set IOBR for window containing area specified in pci.h */
106 PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK));
107
108 /* All done, may as well say so... */
109 printk("SH7751 PCI: Finished initialization of the PCI controller\n");
110
111 return 1;
112}
113
114int __init pcibios_map_platform_irq(u8 slot, u8 pin)
115{
116 switch (slot) {
117 case 0: return 13;
118 case 1: return 13; /* AMD Ethernet controller */
119 case 2: return -1;
120 case 3: return -1;
121 case 4: return -1;
122 default:
123 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
124 return -1;
125 }
126}
127
128static struct resource sh7751_io_resource = {
129 .name = "SH7751 IO",
130 .start = SH7751_PCI_IO_BASE,
131 .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
132 .flags = IORESOURCE_IO
133};
134
135static struct resource sh7751_mem_resource = {
136 .name = "SH7751 mem",
137 .start = SH7751_PCI_MEMORY_BASE,
138 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
139 .flags = IORESOURCE_MEM
140};
141
142extern struct pci_ops sh7751_pci_ops;
143
144struct pci_channel board_pci_channels[] = {
145 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
146 { NULL, NULL, NULL, 0, 0 },
147};
148
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 @@
1/*
2 * linux/arch/sh/kernel/setup_7751se.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Hitachi SolutionEngine Support.
7 *
8 * Modified for 7751 Solution Engine by
9 * Ian da Silva and Jeremy Siegel, 2001.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <linux/hdreg.h>
17#include <linux/ide.h>
18#include <asm/io.h>
19#include <asm/se7751/se7751.h>
20
21#ifdef CONFIG_SH_KGDB
22#include <asm/kgdb.h>
23#endif
24
25/*
26 * Configure the Super I/O chip
27 */
28#if 0
29/* Leftover code from regular Solution Engine, for reference. */
30/* The SH7751 Solution Engine has a different SuperIO. */
31static void __init smsc_config(int index, int data)
32{
33 outb_p(index, INDEX_PORT);
34 outb_p(data, DATA_PORT);
35}
36
37static void __init init_smsc(void)
38{
39 outb_p(CONFIG_ENTER, CONFIG_PORT);
40 outb_p(CONFIG_ENTER, CONFIG_PORT);
41
42 /* FDC */
43 smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
44 smsc_config(ACTIVATE_INDEX, 0x01);
45 smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
46
47 /* IDE1 */
48 smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
49 smsc_config(ACTIVATE_INDEX, 0x01);
50 smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
51
52 /* AUXIO (GPIO): to use IDE1 */
53 smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
54 smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
55 smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
56
57 /* COM1 */
58 smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
59 smsc_config(ACTIVATE_INDEX, 0x01);
60 smsc_config(IO_BASE_HI_INDEX, 0x03);
61 smsc_config(IO_BASE_LO_INDEX, 0xf8);
62 smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
63
64 /* COM2 */
65 smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
66 smsc_config(ACTIVATE_INDEX, 0x01);
67 smsc_config(IO_BASE_HI_INDEX, 0x02);
68 smsc_config(IO_BASE_LO_INDEX, 0xf8);
69 smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
70
71 /* RTC */
72 smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
73 smsc_config(ACTIVATE_INDEX, 0x01);
74 smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
75
76 /* XXX: PARPORT, KBD, and MOUSE will come here... */
77 outb_p(CONFIG_EXIT, CONFIG_PORT);
78}
79#endif
80
81const char *get_system_type(void)
82{
83 return "7751 SolutionEngine";
84}
85
86#ifdef CONFIG_SH_KGDB
87static int kgdb_uart_setup(void);
88static struct kgdb_sermap kgdb_uart_sermap =
89{ "ttyS", 0, kgdb_uart_setup, NULL };
90#endif
91
92/*
93 * Initialize the board
94 */
95void __init platform_setup(void)
96{
97 /* Call init_smsc() replacement to set up SuperIO. */
98 /* XXX: RTC setting comes here */
99#ifdef CONFIG_SH_KGDB
100 kgdb_register_sermap(&kgdb_uart_sermap);
101#endif
102}
103
104/*********************************************************************
105 * Currently a hack (e.g. does not interact well w/serial.c, lots of *
106 * hardcoded stuff) but may be useful if SCI/F needs debugging. *
107 * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and *
108 * arch/i386/lib/kgdb_serial.c). *
109 *********************************************************************/
110
111#ifdef CONFIG_SH_KGDB
112#include <linux/types.h>
113#include <linux/serial.h>
114#include <linux/serialP.h>
115#include <linux/serial_reg.h>
116
117#define COM1_PORT 0x3f8 /* Base I/O address */
118#define COM1_IRQ 4 /* IRQ not used yet */
119#define COM2_PORT 0x2f8 /* Base I/O address */
120#define COM2_IRQ 3 /* IRQ not used yet */
121
122#define SB_CLOCK 1843200 /* Serial baud clock */
123#define SB_BASE (SB_CLOCK/16)
124#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
125
126struct uart_port {
127 int base;
128};
129#define UART_NPORTS 2
130struct uart_port uart_ports[] = {
131 { COM1_PORT },
132 { COM2_PORT },
133};
134struct uart_port *kgdb_uart_port;
135
136#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg)
137#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
138
139/* Basic read/write functions for the UART */
140#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
141static int kgdb_uart_getchar(void)
142{
143 int lsr;
144 int c = -1;
145
146 while (c == -1) {
147 lsr = UART_IN(UART_LSR);
148 if (lsr & UART_LSR_DR)
149 c = UART_IN(UART_RX);
150 if ((lsr & UART_LSR_RXCERR))
151 c = -1;
152 }
153 return c;
154}
155
156static void kgdb_uart_putchar(int c)
157{
158 while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
159 ;
160 UART_OUT(UART_TX, c);
161}
162
163/*
164 * Initialize UART to configured/requested values.
165 * (But we don't interrupts yet, or interact w/serial.c)
166 */
167static int kgdb_uart_setup(void)
168{
169 int port;
170 int lcr = 0;
171 int bdiv = 0;
172
173 if (kgdb_portnum >= UART_NPORTS) {
174 KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
175 return -1;
176 }
177
178 kgdb_uart_port = &uart_ports[kgdb_portnum];
179
180 /* Init sequence from gdb_hook_interrupt */
181 UART_IN(UART_RX);
182 UART_OUT(UART_IER, 0);
183
184 UART_IN(UART_RX); /* Serial driver comments say */
185 UART_IN(UART_IIR); /* this clears interrupt regs */
186 UART_IN(UART_MSR);
187
188 /* Figure basic LCR values */
189 switch (kgdb_bits) {
190 case '7':
191 lcr |= UART_LCR_WLEN7;
192 break;
193 default: case '8':
194 lcr |= UART_LCR_WLEN8;
195 break;
196 }
197 switch (kgdb_parity) {
198 case 'O':
199 lcr |= UART_LCR_PARITY;
200 break;
201 case 'E':
202 lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
203 break;
204 default: break;
205 }
206
207 /* Figure the baud rate divisor */
208 bdiv = (SB_BASE/kgdb_baud);
209
210 /* Set the baud rate and LCR values */
211 UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
212 UART_OUT(UART_DLL, (bdiv & 0xff));
213 UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
214 UART_OUT(UART_LCR, lcr);
215
216 /* Set the MCR */
217 UART_OUT(UART_MCR, SB_MCR);
218
219 /* Turn off FIFOs for now */
220 UART_OUT(UART_FCR, 0);
221
222 /* Setup complete: initialize function pointers */
223 kgdb_getchar = kgdb_uart_getchar;
224 kgdb_putchar = kgdb_uart_putchar;
225
226 return 0;
227}
228#endif /* CONFIG_SH_KGDB */
diff --git a/arch/sh/boards/sh03/Makefile b/arch/sh/boards/sh03/Makefile
new file mode 100644
index 000000000000..321be50e36a5
--- /dev/null
+++ b/arch/sh/boards/sh03/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the Interface (CTP/PCI-SH03) specific parts of the kernel
3#
4
5obj-y := setup.o rtc.o
6obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/sh03/led.c b/arch/sh/boards/sh03/led.c
new file mode 100644
index 000000000000..c851b0bec80f
--- /dev/null
+++ b/arch/sh/boards/sh03/led.c
@@ -0,0 +1,49 @@
1/*
2 * linux/arch/sh/boards/sh03/led.c
3 *
4 * Copyright (C) 2004 Saito.K Interface Corporation.
5 *
6 * This file contains Interface CTP/PCI-SH03 specific LED code.
7 */
8
9#include <linux/config.h>
10#include <linux/sched.h>
11
12/* Cycle the LED's in the clasic Knightrider/Sun pattern */
13void heartbeat_sh03(void)
14{
15 static unsigned int cnt = 0, period = 0;
16 volatile unsigned char* p = (volatile unsigned char*)0xa0800000;
17 static unsigned bit = 0, up = 1;
18
19 cnt += 1;
20 if (cnt < period) {
21 return;
22 }
23
24 cnt = 0;
25
26 /* Go through the points (roughly!):
27 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
28 */
29 period = 110 - ( (300<<FSHIFT)/
30 ((avenrun[0]/5) + (3<<FSHIFT)) );
31
32 if (up) {
33 if (bit == 7) {
34 bit--;
35 up=0;
36 } else {
37 bit ++;
38 }
39 } else {
40 if (bit == 0) {
41 bit++;
42 up=1;
43 } else {
44 bit--;
45 }
46 }
47 *p = 1<<bit;
48
49}
diff --git a/arch/sh/boards/sh03/rtc.c b/arch/sh/boards/sh03/rtc.c
new file mode 100644
index 000000000000..cbeca7037ba5
--- /dev/null
+++ b/arch/sh/boards/sh03/rtc.c
@@ -0,0 +1,144 @@
1/*
2 * linux/arch/sh/boards/sh03/rtc.c -- CTP/PCI-SH03 on-chip RTC support
3 *
4 * Copyright (C) 2004 Saito.K & Jeanne(ksaito@interface.co.jp)
5 *
6 */
7
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/time.h>
12#include <asm/io.h>
13#include <linux/rtc.h>
14#include <linux/spinlock.h>
15
16#define RTC_BASE 0xb0000000
17#define RTC_SEC1 (RTC_BASE + 0)
18#define RTC_SEC10 (RTC_BASE + 1)
19#define RTC_MIN1 (RTC_BASE + 2)
20#define RTC_MIN10 (RTC_BASE + 3)
21#define RTC_HOU1 (RTC_BASE + 4)
22#define RTC_HOU10 (RTC_BASE + 5)
23#define RTC_WEE1 (RTC_BASE + 6)
24#define RTC_DAY1 (RTC_BASE + 7)
25#define RTC_DAY10 (RTC_BASE + 8)
26#define RTC_MON1 (RTC_BASE + 9)
27#define RTC_MON10 (RTC_BASE + 10)
28#define RTC_YEA1 (RTC_BASE + 11)
29#define RTC_YEA10 (RTC_BASE + 12)
30#define RTC_YEA100 (RTC_BASE + 13)
31#define RTC_YEA1000 (RTC_BASE + 14)
32#define RTC_CTL (RTC_BASE + 15)
33#define RTC_BUSY 1
34#define RTC_STOP 2
35
36#ifndef BCD_TO_BIN
37#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
38#endif
39
40#ifndef BIN_TO_BCD
41#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
42#endif
43
44extern void (*rtc_get_time)(struct timespec *);
45extern int (*rtc_set_time)(const time_t);
46extern spinlock_t rtc_lock;
47
48unsigned long get_cmos_time(void)
49{
50 unsigned int year, mon, day, hour, min, sec;
51 int i;
52
53 spin_lock(&rtc_lock);
54 again:
55 for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
56 if (!(ctrl_inb(RTC_CTL) & RTC_BUSY))
57 break;
58 do {
59 sec = (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10;
60 min = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10;
61 hour = (ctrl_inb(RTC_HOU1) & 0xf) + (ctrl_inb(RTC_HOU10) & 0xf) * 10;
62 day = (ctrl_inb(RTC_DAY1) & 0xf) + (ctrl_inb(RTC_DAY10) & 0xf) * 10;
63 mon = (ctrl_inb(RTC_MON1) & 0xf) + (ctrl_inb(RTC_MON10) & 0xf) * 10;
64 year = (ctrl_inb(RTC_YEA1) & 0xf) + (ctrl_inb(RTC_YEA10) & 0xf) * 10
65 + (ctrl_inb(RTC_YEA100 ) & 0xf) * 100
66 + (ctrl_inb(RTC_YEA1000) & 0xf) * 1000;
67 } while (sec != (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10);
68 if (year == 0 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
69 hour > 23 || min > 59 || sec > 59) {
70 printk(KERN_ERR
71 "SH-03 RTC: invalid value, resetting to 1 Jan 2000\n");
72 printk("year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n",
73 year, mon, day, hour, min, sec);
74
75 ctrl_outb(0, RTC_SEC1); ctrl_outb(0, RTC_SEC10);
76 ctrl_outb(0, RTC_MIN1); ctrl_outb(0, RTC_MIN10);
77 ctrl_outb(0, RTC_HOU1); ctrl_outb(0, RTC_HOU10);
78 ctrl_outb(6, RTC_WEE1);
79 ctrl_outb(1, RTC_DAY1); ctrl_outb(0, RTC_DAY10);
80 ctrl_outb(1, RTC_MON1); ctrl_outb(0, RTC_MON10);
81 ctrl_outb(0, RTC_YEA1); ctrl_outb(0, RTC_YEA10);
82 ctrl_outb(0, RTC_YEA100);
83 ctrl_outb(2, RTC_YEA1000);
84 ctrl_outb(0, RTC_CTL);
85 goto again;
86 }
87
88 spin_unlock(&rtc_lock);
89 return mktime(year, mon, day, hour, min, sec);
90}
91
92void sh03_rtc_gettimeofday(struct timespec *tv)
93{
94
95 tv->tv_sec = get_cmos_time();
96 tv->tv_nsec = 0;
97}
98
99static int set_rtc_mmss(unsigned long nowtime)
100{
101 int retval = 0;
102 int real_seconds, real_minutes, cmos_minutes;
103 int i;
104
105 /* gets recalled with irq locally disabled */
106 spin_lock(&rtc_lock);
107 for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
108 if (!(ctrl_inb(RTC_CTL) & RTC_BUSY))
109 break;
110 cmos_minutes = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10;
111 real_seconds = nowtime % 60;
112 real_minutes = nowtime / 60;
113 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
114 real_minutes += 30; /* correct for half hour time zone */
115 real_minutes %= 60;
116
117 if (abs(real_minutes - cmos_minutes) < 30) {
118 ctrl_outb(real_seconds % 10, RTC_SEC1);
119 ctrl_outb(real_seconds / 10, RTC_SEC10);
120 ctrl_outb(real_minutes % 10, RTC_MIN1);
121 ctrl_outb(real_minutes / 10, RTC_MIN10);
122 } else {
123 printk(KERN_WARNING
124 "set_rtc_mmss: can't update from %d to %d\n",
125 cmos_minutes, real_minutes);
126 retval = -1;
127 }
128 spin_unlock(&rtc_lock);
129
130 return retval;
131}
132
133int sh03_rtc_settimeofday(const time_t secs)
134{
135 unsigned long nowtime = secs;
136
137 return set_rtc_mmss(nowtime);
138}
139
140void sh03_time_init(void)
141{
142 rtc_get_time = sh03_rtc_gettimeofday;
143 rtc_set_time = sh03_rtc_settimeofday;
144}
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
new file mode 100644
index 000000000000..d2a08ca5eb85
--- /dev/null
+++ b/arch/sh/boards/sh03/setup.c
@@ -0,0 +1,72 @@
1/*
2 * linux/arch/sh/boards/sh03/setup.c
3 *
4 * Copyright (C) 2004 Interface Co.,Ltd. Saito.K
5 *
6 */
7
8#include <linux/config.h>
9#include <linux/init.h>
10#include <linux/irq.h>
11#include <linux/hdreg.h>
12#include <linux/ide.h>
13#include <asm/io.h>
14#include <asm/sh03/io.h>
15#include <asm/sh03/sh03.h>
16#include <asm/addrspace.h>
17#include "../../drivers/pci/pci-sh7751.h"
18
19extern void (*board_time_init)(void);
20
21const char *get_system_type(void)
22{
23 return "Interface CTP/PCI-SH03)";
24}
25
26void init_sh03_IRQ(void)
27{
28 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
29
30 make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
31 make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
32 make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
33 make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
34}
35
36extern void *cf_io_base;
37
38unsigned long sh03_isa_port2addr(unsigned long port)
39{
40 if (PXSEG(port))
41 return port;
42 /* CompactFlash (IDE) */
43 if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) {
44 return (unsigned long)cf_io_base + port;
45 }
46 return port + SH7751_PCI_IO_BASE;
47}
48
49/*
50 * The Machine Vector
51 */
52
53struct sh_machine_vector mv_sh03 __initmv = {
54 .mv_nr_irqs = 48,
55 .mv_isa_port2addr = sh03_isa_port2addr,
56 .mv_init_irq = init_sh03_IRQ,
57
58#ifdef CONFIG_HEARTBEAT
59 .mv_heartbeat = heartbeat_sh03,
60#endif
61};
62
63ALIAS_MV(sh03)
64
65/* arch/sh/boards/sh03/rtc.c */
66void sh03_time_init(void);
67
68int __init platform_setup(void)
69{
70 board_time_init = sh03_time_init;
71 return 0;
72}
diff --git a/arch/sh/boards/sh2000/Makefile b/arch/sh/boards/sh2000/Makefile
new file mode 100644
index 000000000000..05d390c3599c
--- /dev/null
+++ b/arch/sh/boards/sh2000/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the SH2000 specific parts of the kernel
3#
4
5obj-y := setup.o
6
diff --git a/arch/sh/boards/sh2000/setup.c b/arch/sh/boards/sh2000/setup.c
new file mode 100644
index 000000000000..a290b1d09fb2
--- /dev/null
+++ b/arch/sh/boards/sh2000/setup.c
@@ -0,0 +1,71 @@
1/*
2 * linux/arch/sh/kernel/setup_sh2000.c
3 *
4 * Copyright (C) 2001 SUGIOKA Tochinobu
5 *
6 * SH-2000 Support.
7 *
8 */
9
10#include <linux/config.h>
11#include <linux/init.h>
12#include <linux/irq.h>
13
14#include <asm/io.h>
15#include <asm/machvec.h>
16#include <asm/mach/sh2000.h>
17
18#define CF_CIS_BASE 0xb4200000
19
20#define PORT_PECR 0xa4000108
21#define PORT_PHCR 0xa400010E
22#define PORT_ICR1 0xa4000010
23#define PORT_IRR0 0xa4000004
24
25#define IDE_OFFSET 0xb6200000
26#define NIC_OFFSET 0xb6000000
27#define EXTBUS_OFFSET 0xba000000
28
29
30const char *get_system_type(void)
31{
32 return "sh2000";
33}
34
35static unsigned long sh2000_isa_port2addr(unsigned long offset)
36{
37 if((offset & ~7) == 0x1f0 || offset == 0x3f6)
38 return IDE_OFFSET + offset;
39 else if((offset & ~0x1f) == 0x300)
40 return NIC_OFFSET + offset;
41 return EXTBUS_OFFSET + offset;
42}
43
44/*
45 * The Machine Vector
46 */
47struct sh_machine_vector mv_sh2000 __initmv = {
48 .mv_nr_irqs = 80,
49 .mv_isa_port2addr = sh2000_isa_port2addr,
50};
51ALIAS_MV(sh2000)
52
53/*
54 * Initialize the board
55 */
56int __init platform_setup(void)
57{
58 /* XXX: RTC setting comes here */
59
60 /* These should be done by BIOS/IPL ... */
61 /* Enable nCE2A, nCE2B output */
62 ctrl_outw(ctrl_inw(PORT_PECR) & ~0xf00, PORT_PECR);
63 /* Enable the Compact Flash card, and set the level interrupt */
64 ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
65 /* Enable interrupt */
66 ctrl_outw(ctrl_inw(PORT_PHCR) & ~0x03f3, PORT_PHCR);
67 ctrl_outw(1, PORT_ICR1);
68 ctrl_outw(ctrl_inw(PORT_IRR0) & ~0xff3f, PORT_IRR0);
69 printk(KERN_INFO "SH-2000 Setup...done\n");
70 return 0;
71}
diff --git a/arch/sh/boards/snapgear/Makefile b/arch/sh/boards/snapgear/Makefile
new file mode 100644
index 000000000000..59fc976bfc2f
--- /dev/null
+++ b/arch/sh/boards/snapgear/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the SnapGear specific parts of the kernel
3#
4
5obj-y := setup.o io.o rtc.o
6
diff --git a/arch/sh/boards/snapgear/io.c b/arch/sh/boards/snapgear/io.c
new file mode 100644
index 000000000000..e2eb78fc381d
--- /dev/null
+++ b/arch/sh/boards/snapgear/io.c
@@ -0,0 +1,226 @@
1/*
2 * linux/arch/sh/kernel/io_7751se.c
3 *
4 * Copyright (C) 2002 David McCullough <davidm@snapgear.com>
5 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
6 * Based largely on io_se.c.
7 *
8 * I/O routine for Hitachi 7751 SolutionEngine.
9 *
10 * Initial version only to support LAN access; some
11 * placeholder code from io_se.c left in with the
12 * expectation of later SuperIO and PCMCIA access.
13 */
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/pci.h>
18#include <asm/io.h>
19#include <asm/addrspace.h>
20
21#include <asm/pci.h>
22#include "../../drivers/pci/pci-sh7751.h"
23
24#ifdef CONFIG_SH_SECUREEDGE5410
25unsigned short secureedge5410_ioport;
26#endif
27
28/*
29 * The SnapGear uses the built-in PCI controller (PCIC)
30 * of the 7751 processor
31 */
32
33#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
34#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
35#define PCI_IO_AREA SH7751_PCI_IO_BASE
36#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
37
38
39#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
40
41
42#define maybebadio(name,port) \
43 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
44 #name, (port), (__u32) __builtin_return_address(0))
45
46
47static inline void delay(void)
48{
49 ctrl_inw(0xa0000000);
50}
51
52
53static inline volatile __u16 *port2adr(unsigned int port)
54{
55#if 0
56 if (port >= 0x2000)
57 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
58#endif
59 maybebadio(name,(unsigned long)port);
60 return (volatile __u16*)port;
61}
62
63
64/* In case someone configures the kernel w/o PCI support: in that */
65/* scenario, don't ever bother to check for PCI-window addresses */
66
67/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
68#if defined(CONFIG_PCI)
69#define CHECK_SH7751_PCIIO(port) \
70 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
71#else
72#define CHECK_SH7751_PCIIO(port) (0)
73#endif
74
75/*
76 * General outline: remap really low stuff [eventually] to SuperIO,
77 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
78 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
79 * should be way beyond the window, and is used w/o translation for
80 * compatibility.
81 */
82
83unsigned char snapgear_inb(unsigned long port)
84{
85 if (PXSEG(port))
86 return *(volatile unsigned char *)port;
87 else if (CHECK_SH7751_PCIIO(port))
88 return *(volatile unsigned char *)PCI_IOMAP(port);
89 else
90 return (*port2adr(port))&0xff;
91}
92
93
94unsigned char snapgear_inb_p(unsigned long port)
95{
96 unsigned char v;
97
98 if (PXSEG(port))
99 v = *(volatile unsigned char *)port;
100 else if (CHECK_SH7751_PCIIO(port))
101 v = *(volatile unsigned char *)PCI_IOMAP(port);
102 else
103 v = (*port2adr(port))&0xff;
104 delay();
105 return v;
106}
107
108
109unsigned short snapgear_inw(unsigned long port)
110{
111 if (PXSEG(port))
112 return *(volatile unsigned short *)port;
113 else if (CHECK_SH7751_PCIIO(port))
114 return *(volatile unsigned short *)PCI_IOMAP(port);
115 else if (port >= 0x2000)
116 return *port2adr(port);
117 else
118 maybebadio(inw, port);
119 return 0;
120}
121
122
123unsigned int snapgear_inl(unsigned long port)
124{
125 if (PXSEG(port))
126 return *(volatile unsigned long *)port;
127 else if (CHECK_SH7751_PCIIO(port))
128 return *(volatile unsigned int *)PCI_IOMAP(port);
129 else if (port >= 0x2000)
130 return *port2adr(port);
131 else
132 maybebadio(inl, port);
133 return 0;
134}
135
136
137void snapgear_outb(unsigned char value, unsigned long port)
138{
139
140 if (PXSEG(port))
141 *(volatile unsigned char *)port = value;
142 else if (CHECK_SH7751_PCIIO(port))
143 *((unsigned char*)PCI_IOMAP(port)) = value;
144 else
145 *(port2adr(port)) = value;
146}
147
148
149void snapgear_outb_p(unsigned char value, unsigned long port)
150{
151 if (PXSEG(port))
152 *(volatile unsigned char *)port = value;
153 else if (CHECK_SH7751_PCIIO(port))
154 *((unsigned char*)PCI_IOMAP(port)) = value;
155 else
156 *(port2adr(port)) = value;
157 delay();
158}
159
160
161void snapgear_outw(unsigned short value, unsigned long port)
162{
163 if (PXSEG(port))
164 *(volatile unsigned short *)port = value;
165 else if (CHECK_SH7751_PCIIO(port))
166 *((unsigned short *)PCI_IOMAP(port)) = value;
167 else if (port >= 0x2000)
168 *port2adr(port) = value;
169 else
170 maybebadio(outw, port);
171}
172
173
174void snapgear_outl(unsigned int value, unsigned long port)
175{
176 if (PXSEG(port))
177 *(volatile unsigned long *)port = value;
178 else if (CHECK_SH7751_PCIIO(port))
179 *((unsigned long*)PCI_IOMAP(port)) = value;
180 else
181 maybebadio(outl, port);
182}
183
184void snapgear_insl(unsigned long port, void *addr, unsigned long count)
185{
186 maybebadio(insl, port);
187}
188
189void snapgear_outsl(unsigned long port, const void *addr, unsigned long count)
190{
191 maybebadio(outsw, port);
192}
193
194/* Map ISA bus address to the real address. Only for PCMCIA. */
195
196
197/* ISA page descriptor. */
198static __u32 sh_isa_memmap[256];
199
200
201#if 0
202static int sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
203{
204 int idx;
205
206 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
207 return -1;
208
209 idx = start >> 12;
210 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
211#if 0
212 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
213 start, length, offset, idx, sh_isa_memmap[idx]);
214#endif
215 return 0;
216}
217#endif
218
219unsigned long snapgear_isa_port2addr(unsigned long offset)
220{
221 int idx;
222
223 idx = (offset >> 12) & 0xff;
224 offset &= 0xfff;
225 return sh_isa_memmap[idx] + offset;
226}
diff --git a/arch/sh/boards/snapgear/rtc.c b/arch/sh/boards/snapgear/rtc.c
new file mode 100644
index 000000000000..b71e009da35c
--- /dev/null
+++ b/arch/sh/boards/snapgear/rtc.c
@@ -0,0 +1,333 @@
1/****************************************************************************/
2/*
3 * linux/arch/sh/boards/snapgear/rtc.c -- Secureedge5410 RTC code
4 *
5 * Copyright (C) 2002 David McCullough <davidm@snapgear.com>
6 * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org>
7 *
8 * The SecureEdge5410 can have one of 2 real time clocks, the SH
9 * built in version or the preferred external DS1302. Here we work out
10 * each to see what we have and then run with it.
11 */
12/****************************************************************************/
13
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/time.h>
18#include <linux/rtc.h>
19#include <linux/mc146818rtc.h>
20
21#include <asm/io.h>
22#include <asm/rtc.h>
23#include <asm/mc146818rtc.h>
24
25/****************************************************************************/
26
27static int use_ds1302 = 0;
28
29/****************************************************************************/
30/*
31 * we need to implement a DS1302 driver here that can operate in
32 * conjunction with the builtin rtc driver which is already quite friendly
33 */
34/*****************************************************************************/
35
36#define RTC_CMD_READ 0x81 /* Read command */
37#define RTC_CMD_WRITE 0x80 /* Write command */
38
39#define RTC_ADDR_YEAR 0x06 /* Address of year register */
40#define RTC_ADDR_DAY 0x05 /* Address of day of week register */
41#define RTC_ADDR_MON 0x04 /* Address of month register */
42#define RTC_ADDR_DATE 0x03 /* Address of day of month register */
43#define RTC_ADDR_HOUR 0x02 /* Address of hour register */
44#define RTC_ADDR_MIN 0x01 /* Address of minute register */
45#define RTC_ADDR_SEC 0x00 /* Address of second register */
46
47#define RTC_RESET 0x1000
48#define RTC_IODATA 0x0800
49#define RTC_SCLK 0x0400
50
51#define set_dirp(x)
52#define get_dirp(x) 0
53#define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
54#define get_dp(x) SECUREEDGE_READ_IOPORT()
55
56static void ds1302_sendbits(unsigned int val)
57{
58 int i;
59
60 for (i = 8; (i); i--, val >>= 1) {
61 set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? RTC_IODATA : 0));
62 set_dp(get_dp() | RTC_SCLK); // clock high
63 set_dp(get_dp() & ~RTC_SCLK); // clock low
64 }
65}
66
67static unsigned int ds1302_recvbits(void)
68{
69 unsigned int val;
70 int i;
71
72 for (i = 0, val = 0; (i < 8); i++) {
73 val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i);
74 set_dp(get_dp() | RTC_SCLK); // clock high
75 set_dp(get_dp() & ~RTC_SCLK); // clock low
76 }
77 return(val);
78}
79
80static unsigned int ds1302_readbyte(unsigned int addr)
81{
82 unsigned int val;
83 unsigned long flags;
84
85#if 0
86 printk("SnapGear RTC: ds1302_readbyte(addr=%x)\n", addr);
87#endif
88
89 local_irq_save(flags);
90 set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
91 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
92
93 set_dp(get_dp() | RTC_RESET);
94 ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
95 set_dirp(get_dirp() & ~RTC_IODATA);
96 val = ds1302_recvbits();
97 set_dp(get_dp() & ~RTC_RESET);
98 local_irq_restore(flags);
99
100 return(val);
101}
102
103static void ds1302_writebyte(unsigned int addr, unsigned int val)
104{
105 unsigned long flags;
106
107#if 0
108 printk("SnapGear RTC: ds1302_writebyte(addr=%x)\n", addr);
109#endif
110
111 local_irq_save(flags);
112 set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
113 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
114 set_dp(get_dp() | RTC_RESET);
115 ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
116 ds1302_sendbits(val);
117 set_dp(get_dp() & ~RTC_RESET);
118 local_irq_restore(flags);
119}
120
121static void ds1302_reset(void)
122{
123 unsigned long flags;
124 /* Hardware dependant reset/init */
125 local_irq_save(flags);
126 set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
127 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
128 local_irq_restore(flags);
129}
130
131/*****************************************************************************/
132
133static inline int bcd2int(int val)
134{
135 return((((val & 0xf0) >> 4) * 10) + (val & 0xf));
136}
137
138static inline int int2bcd(int val)
139{
140 return(((val / 10) << 4) + (val % 10));
141}
142
143/*****************************************************************************/
144/*
145 * Write and Read some RAM in the DS1302, if it works assume it's there
146 * Otherwise use the SH4 internal RTC
147 */
148
149void snapgear_rtc_gettimeofday(struct timespec *);
150int snapgear_rtc_settimeofday(const time_t);
151
152void __init secureedge5410_rtc_init(void)
153{
154 unsigned char *test = "snapgear";
155 int i;
156
157 ds1302_reset();
158
159 use_ds1302 = 1;
160
161 for (i = 0; test[i]; i++)
162 ds1302_writebyte(32 + i, test[i]);
163
164 for (i = 0; test[i]; i++)
165 if (ds1302_readbyte(32 + i) != test[i]) {
166 use_ds1302 = 0;
167 break;
168 }
169
170 if (use_ds1302) {
171 rtc_get_time = snapgear_rtc_gettimeofday;
172 rtc_set_time = snapgear_rtc_settimeofday;
173 } else {
174 rtc_get_time = sh_rtc_gettimeofday;
175 rtc_set_time = sh_rtc_settimeofday;
176 }
177
178 printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal");
179}
180
181/****************************************************************************/
182/*
183 * our generic interface that chooses the correct code to use
184 */
185
186void snapgear_rtc_gettimeofday(struct timespec *ts)
187{
188 unsigned int sec, min, hr, day, mon, yr;
189
190 if (!use_ds1302) {
191 sh_rtc_gettimeofday(ts);
192 return;
193 }
194
195 sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
196 min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
197 hr = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR));
198 day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE));
199 mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON));
200 yr = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR));
201
202bad_time:
203 if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
204 hr > 23 || min > 59 || sec > 59) {
205 printk(KERN_ERR
206 "SnapGear RTC: invalid value, resetting to 1 Jan 2000\n");
207 ds1302_writebyte(RTC_ADDR_MIN, min = 0);
208 ds1302_writebyte(RTC_ADDR_HOUR, hr = 0);
209 ds1302_writebyte(RTC_ADDR_DAY, 7);
210 ds1302_writebyte(RTC_ADDR_DATE, day = 1);
211 ds1302_writebyte(RTC_ADDR_MON, mon = 1);
212 ds1302_writebyte(RTC_ADDR_YEAR, yr = 0);
213 ds1302_writebyte(RTC_ADDR_SEC, sec = 0);
214 }
215
216 ts->tv_sec = mktime(2000 + yr, mon, day, hr, min, sec);
217 if (ts->tv_sec < 0) {
218#if 0
219 printk("BAD TIME %d %d %d %d %d %d\n", yr, mon, day, hr, min, sec);
220#endif
221 yr = 100;
222 goto bad_time;
223 }
224 ts->tv_nsec = 0;
225}
226
227int snapgear_rtc_settimeofday(const time_t secs)
228{
229 int retval = 0;
230 int real_seconds, real_minutes, cmos_minutes;
231 unsigned long nowtime;
232
233 if (!use_ds1302)
234 return sh_rtc_settimeofday(secs);
235
236/*
237 * This is called direct from the kernel timer handling code.
238 * It is supposed to synchronize the kernel clock to the RTC.
239 */
240
241 nowtime = secs;
242
243#if 1
244 printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime);
245#endif
246
247 /* STOP RTC */
248 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
249
250 cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
251
252 /*
253 * since we're only adjusting minutes and seconds,
254 * don't interfere with hour overflow. This avoids
255 * messing with unknown time zones but requires your
256 * RTC not to be off by more than 15 minutes
257 */
258 real_seconds = nowtime % 60;
259 real_minutes = nowtime / 60;
260 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
261 real_minutes += 30; /* correct for half hour time zone */
262 real_minutes %= 60;
263
264 if (abs(real_minutes - cmos_minutes) < 30) {
265 ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes));
266 ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds));
267 } else {
268 printk(KERN_WARNING
269 "SnapGear RTC: can't update from %d to %d\n",
270 cmos_minutes, real_minutes);
271 retval = -1;
272 }
273
274 /* START RTC */
275 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
276 return(0);
277}
278
279unsigned char secureedge5410_cmos_read(int addr)
280{
281 unsigned char val = 0;
282
283 if (!use_ds1302)
284 return(__CMOS_READ(addr, w));
285
286 switch(addr) {
287 case RTC_SECONDS: val = ds1302_readbyte(RTC_ADDR_SEC); break;
288 case RTC_SECONDS_ALARM: break;
289 case RTC_MINUTES: val = ds1302_readbyte(RTC_ADDR_MIN); break;
290 case RTC_MINUTES_ALARM: break;
291 case RTC_HOURS: val = ds1302_readbyte(RTC_ADDR_HOUR); break;
292 case RTC_HOURS_ALARM: break;
293 case RTC_DAY_OF_WEEK: val = ds1302_readbyte(RTC_ADDR_DAY); break;
294 case RTC_DAY_OF_MONTH: val = ds1302_readbyte(RTC_ADDR_DATE); break;
295 case RTC_MONTH: val = ds1302_readbyte(RTC_ADDR_MON); break;
296 case RTC_YEAR: val = ds1302_readbyte(RTC_ADDR_YEAR); break;
297 case RTC_REG_A: /* RTC_FREQ_SELECT */ break;
298 case RTC_REG_B: /* RTC_CONTROL */ break;
299 case RTC_REG_C: /* RTC_INTR_FLAGS */ break;
300 case RTC_REG_D: val = RTC_VRT /* RTC_VALID */; break;
301 default: break;
302 }
303
304 return(val);
305}
306
307void secureedge5410_cmos_write(unsigned char val, int addr)
308{
309 if (!use_ds1302) {
310 __CMOS_WRITE(val, addr, w);
311 return;
312 }
313
314 switch(addr) {
315 case RTC_SECONDS: ds1302_writebyte(RTC_ADDR_SEC, val); break;
316 case RTC_SECONDS_ALARM: break;
317 case RTC_MINUTES: ds1302_writebyte(RTC_ADDR_MIN, val); break;
318 case RTC_MINUTES_ALARM: break;
319 case RTC_HOURS: ds1302_writebyte(RTC_ADDR_HOUR, val); break;
320 case RTC_HOURS_ALARM: break;
321 case RTC_DAY_OF_WEEK: ds1302_writebyte(RTC_ADDR_DAY, val); break;
322 case RTC_DAY_OF_MONTH: ds1302_writebyte(RTC_ADDR_DATE, val); break;
323 case RTC_MONTH: ds1302_writebyte(RTC_ADDR_MON, val); break;
324 case RTC_YEAR: ds1302_writebyte(RTC_ADDR_YEAR, val); break;
325 case RTC_REG_A: /* RTC_FREQ_SELECT */ break;
326 case RTC_REG_B: /* RTC_CONTROL */ break;
327 case RTC_REG_C: /* RTC_INTR_FLAGS */ break;
328 case RTC_REG_D: /* RTC_VALID */ break;
329 default: break;
330 }
331}
332
333/****************************************************************************/
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c
new file mode 100644
index 000000000000..08fc98342a0b
--- /dev/null
+++ b/arch/sh/boards/snapgear/setup.c
@@ -0,0 +1,216 @@
1/****************************************************************************/
2/*
3 * linux/arch/sh/boards/snapgear/setup.c
4 *
5 * Copyright (C) 2002 David McCullough <davidm@snapgear.com>
6 * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org>
7 *
8 * Based on files with the following comments:
9 *
10 * Copyright (C) 2000 Kazumoto Kojima
11 *
12 * Modified for 7751 Solution Engine by
13 * Ian da Silva and Jeremy Siegel, 2001.
14 */
15/****************************************************************************/
16
17#include <linux/config.h>
18#include <linux/init.h>
19#include <linux/irq.h>
20#include <linux/interrupt.h>
21#include <linux/timer.h>
22#include <linux/delay.h>
23#include <linux/module.h>
24#include <linux/sched.h>
25
26#include <asm/machvec.h>
27#include <asm/mach/io.h>
28#include <asm/irq.h>
29#include <asm/io.h>
30#include <asm/cpu/timer.h>
31
32extern void (*board_time_init)(void);
33extern void secureedge5410_rtc_init(void);
34extern void pcibios_init(void);
35
36/****************************************************************************/
37/*
38 * EraseConfig handling functions
39 */
40
41static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs)
42{
43 volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000;
44
45 printk("SnapGear: erase switch interrupt!\n");
46
47 return IRQ_HANDLED;
48}
49
50static int __init eraseconfig_init(void)
51{
52 printk("SnapGear: EraseConfig init\n");
53 /* Setup "EraseConfig" switch on external IRQ 0 */
54 if (request_irq(IRL0_IRQ, eraseconfig_interrupt, SA_INTERRUPT,
55 "Erase Config", NULL))
56 printk("SnapGear: failed to register IRQ%d for Reset witch\n",
57 IRL0_IRQ);
58 else
59 printk("SnapGear: registered EraseConfig switch on IRQ%d\n",
60 IRL0_IRQ);
61 return(0);
62}
63
64module_init(eraseconfig_init);
65
66/****************************************************************************/
67/*
68 * Initialize IRQ setting
69 *
70 * IRL0 = erase switch
71 * IRL1 = eth0
72 * IRL2 = eth1
73 * IRL3 = crypto
74 */
75
76static void __init init_snapgear_IRQ(void)
77{
78 /* enable individual interrupt mode for externals */
79 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
80
81 printk("Setup SnapGear IRQ/IPR ...\n");
82
83 make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
84 make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
85 make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
86 make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
87}
88
89/****************************************************************************/
90/*
91 * Fast poll interrupt simulator.
92 */
93
94/*
95 * Leave all of the fast timer/fast poll stuff commented out for now, since
96 * it's not clear whether it actually works or not. Since it wasn't being used
97 * at all in 2.4, we'll assume it's not sane for 2.6 either.. -- PFM
98 */
99#if 0
100#define FAST_POLL 1000
101//#define FAST_POLL_INTR
102
103#define FASTTIMER_IRQ 17
104#define FASTTIMER_IPR_ADDR INTC_IPRA
105#define FASTTIMER_IPR_POS 2
106#define FASTTIMER_PRIORITY 3
107
108#ifdef FAST_POLL_INTR
109#define TMU1_TCR_INIT 0x0020
110#else
111#define TMU1_TCR_INIT 0
112#endif
113#define TMU_TSTR_INIT 1
114#define TMU1_TCR_CALIB 0x0000
115
116
117#ifdef FAST_POLL_INTR
118static void fast_timer_irq(int irq, void *dev_instance, struct pt_regs *regs)
119{
120 unsigned long timer_status;
121 timer_status = ctrl_inw(TMU1_TCR);
122 timer_status &= ~0x100;
123 ctrl_outw(timer_status, TMU1_TCR);
124}
125#endif
126
127/*
128 * return the current ticks on the fast timer
129 */
130
131unsigned long fast_timer_count(void)
132{
133 return(ctrl_inl(TMU1_TCNT));
134}
135
136/*
137 * setup a fast timer for profiling etc etc
138 */
139
140static void setup_fast_timer()
141{
142 unsigned long interval;
143
144#ifdef FAST_POLL_INTR
145 interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL;
146
147 make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS,
148 FASTTIMER_PRIORITY);
149
150 printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ);
151
152 if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer",
153 NULL) != 0)
154 printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__);
155#else
156 printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ);
157 interval = 0xffffffff;
158#endif
159
160 ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */
161 ctrl_outw(TMU1_TCR_INIT, TMU1_TCR);
162 ctrl_outl(interval, TMU1_TCOR);
163 ctrl_outl(interval, TMU1_TCNT);
164 ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */
165
166 printk("Timer count 1 = 0x%x\n", fast_timer_count());
167 udelay(1000);
168 printk("Timer count 2 = 0x%x\n", fast_timer_count());
169}
170#endif
171
172/****************************************************************************/
173
174const char *get_system_type(void)
175{
176 return "SnapGear SecureEdge5410";
177}
178
179/*
180 * The Machine Vector
181 */
182
183struct sh_machine_vector mv_snapgear __initmv = {
184 .mv_nr_irqs = 72,
185
186 .mv_inb = snapgear_inb,
187 .mv_inw = snapgear_inw,
188 .mv_inl = snapgear_inl,
189 .mv_outb = snapgear_outb,
190 .mv_outw = snapgear_outw,
191 .mv_outl = snapgear_outl,
192
193 .mv_inb_p = snapgear_inb_p,
194 .mv_inw_p = snapgear_inw,
195 .mv_inl_p = snapgear_inl,
196 .mv_outb_p = snapgear_outb_p,
197 .mv_outw_p = snapgear_outw,
198 .mv_outl_p = snapgear_outl,
199
200 .mv_isa_port2addr = snapgear_isa_port2addr,
201
202 .mv_init_irq = init_snapgear_IRQ,
203};
204ALIAS_MV(snapgear)
205
206/*
207 * Initialize the board
208 */
209
210int __init platform_setup(void)
211{
212 board_time_init = secureedge5410_rtc_init;
213
214 return 0;
215}
216
diff --git a/arch/sh/boards/superh/microdev/Makefile b/arch/sh/boards/superh/microdev/Makefile
new file mode 100644
index 000000000000..1387dd6c85eb
--- /dev/null
+++ b/arch/sh/boards/superh/microdev/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the SuperH MicroDev specific parts of the kernel
3#
4
5obj-y := setup.o irq.o io.o
6
7obj-$(CONFIG_HEARTBEAT) += led.o
8
diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c
new file mode 100644
index 000000000000..fe83b2c03076
--- /dev/null
+++ b/arch/sh/boards/superh/microdev/io.c
@@ -0,0 +1,370 @@
1/*
2 * linux/arch/sh/kernel/io_microdev.c
3 *
4 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5 * Copyright (C) 2003, 2004 SuperH, Inc.
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * SuperH SH4-202 MicroDev board support.
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/pci.h>
17#include <linux/wait.h>
18#include <asm/io.h>
19#include <asm/mach/io.h>
20
21 /*
22 * we need to have a 'safe' address to re-direct all I/O requests
23 * that we do not explicitly wish to handle. This safe address
24 * must have the following properies:
25 *
26 * * writes are ignored (no exception)
27 * * reads are benign (no side-effects)
28 * * accesses of width 1, 2 and 4-bytes are all valid.
29 *
30 * The Processor Version Register (PVR) has these properties.
31 */
32#define PVR 0xff000030 /* Processor Version Register */
33
34
35#define IO_IDE2_BASE 0x170ul /* I/O base for SMSC FDC37C93xAPM IDE #2 */
36#define IO_IDE1_BASE 0x1f0ul /* I/O base for SMSC FDC37C93xAPM IDE #1 */
37#define IO_ISP1161_BASE 0x290ul /* I/O port for Philips ISP1161x USB chip */
38#define IO_SERIAL2_BASE 0x2f8ul /* I/O base for SMSC FDC37C93xAPM Serial #2 */
39#define IO_LAN91C111_BASE 0x300ul /* I/O base for SMSC LAN91C111 Ethernet chip */
40#define IO_IDE2_MISC 0x376ul /* I/O misc for SMSC FDC37C93xAPM IDE #2 */
41#define IO_SUPERIO_BASE 0x3f0ul /* I/O base for SMSC FDC37C93xAPM SuperIO chip */
42#define IO_IDE1_MISC 0x3f6ul /* I/O misc for SMSC FDC37C93xAPM IDE #1 */
43#define IO_SERIAL1_BASE 0x3f8ul /* I/O base for SMSC FDC37C93xAPM Serial #1 */
44
45#define IO_ISP1161_EXTENT 0x04ul /* I/O extent for Philips ISP1161x USB chip */
46#define IO_LAN91C111_EXTENT 0x10ul /* I/O extent for SMSC LAN91C111 Ethernet chip */
47#define IO_SUPERIO_EXTENT 0x02ul /* I/O extent for SMSC FDC37C93xAPM SuperIO chip */
48#define IO_IDE_EXTENT 0x08ul /* I/O extent for IDE Task Register set */
49#define IO_SERIAL_EXTENT 0x10ul
50
51#define IO_LAN91C111_PHYS 0xa7500000ul /* Physical address of SMSC LAN91C111 Ethernet chip */
52#define IO_ISP1161_PHYS 0xa7700000ul /* Physical address of Philips ISP1161x USB chip */
53#define IO_SUPERIO_PHYS 0xa7800000ul /* Physical address of SMSC FDC37C93xAPM SuperIO chip */
54
55#define PORT2ADDR(x) (microdev_isa_port2addr(x))
56
57
58static inline void delay(void)
59{
60#if defined(CONFIG_PCI)
61 /* System board present, just make a dummy SRAM access. (CS0 will be
62 mapped to PCI memory, probably good to avoid it.) */
63 ctrl_inw(0xa6800000);
64#else
65 /* CS0 will be mapped to flash, ROM etc so safe to access it. */
66 ctrl_inw(0xa0000000);
67#endif
68}
69
70unsigned char microdev_inb(unsigned long port)
71{
72#ifdef CONFIG_PCI
73 if (port >= PCIBIOS_MIN_IO)
74 return microdev_pci_inb(port);
75#endif
76 return *(volatile unsigned char*)PORT2ADDR(port);
77}
78
79unsigned short microdev_inw(unsigned long port)
80{
81#ifdef CONFIG_PCI
82 if (port >= PCIBIOS_MIN_IO)
83 return microdev_pci_inw(port);
84#endif
85 return *(volatile unsigned short*)PORT2ADDR(port);
86}
87
88unsigned int microdev_inl(unsigned long port)
89{
90#ifdef CONFIG_PCI
91 if (port >= PCIBIOS_MIN_IO)
92 return microdev_pci_inl(port);
93#endif
94 return *(volatile unsigned int*)PORT2ADDR(port);
95}
96
97void microdev_outb(unsigned char b, unsigned long port)
98{
99#ifdef CONFIG_PCI
100 if (port >= PCIBIOS_MIN_IO) {
101 microdev_pci_outb(b, port);
102 return;
103 }
104#endif
105
106 /*
107 * There is a board feature with the current SH4-202 MicroDev in
108 * that the 2 byte enables (nBE0 and nBE1) are tied together (and
109 * to the Chip Select Line (Ethernet_CS)). Due to this conectivity,
110 * it is not possible to safely perform 8-bit writes to the
111 * Ethernet registers, as 16-bits will be consumed from the Data
112 * lines (corrupting the other byte). Hence, this function is
113 * written to impliment 16-bit read/modify/write for all byte-wide
114 * acceses.
115 *
116 * Note: there is no problem with byte READS (even or odd).
117 *
118 * Sean McGoogan - 16th June 2003.
119 */
120 if ((port >= IO_LAN91C111_BASE) &&
121 (port < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
122 /*
123 * Then are trying to perform a byte-write to the
124 * LAN91C111. This needs special care.
125 */
126 if (port % 2 == 1) { /* is the port odd ? */
127 /* unset bit-0, i.e. make even */
128 const unsigned long evenPort = port-1;
129 unsigned short word;
130
131 /*
132 * do a 16-bit read/write to write to 'port',
133 * preserving even byte.
134 *
135 * Even addresses are bits 0-7
136 * Odd addresses are bits 8-15
137 */
138 word = microdev_inw(evenPort);
139 word = (word & 0xffu) | (b << 8);
140 microdev_outw(word, evenPort);
141 } else {
142 /* else, we are trying to do an even byte write */
143 unsigned short word;
144
145 /*
146 * do a 16-bit read/write to write to 'port',
147 * preserving odd byte.
148 *
149 * Even addresses are bits 0-7
150 * Odd addresses are bits 8-15
151 */
152 word = microdev_inw(port);
153 word = (word & 0xff00u) | (b);
154 microdev_outw(word, port);
155 }
156 } else {
157 *(volatile unsigned char*)PORT2ADDR(port) = b;
158 }
159}
160
161void microdev_outw(unsigned short b, unsigned long port)
162{
163#ifdef CONFIG_PCI
164 if (port >= PCIBIOS_MIN_IO) {
165 microdev_pci_outw(b, port);
166 return;
167 }
168#endif
169 *(volatile unsigned short*)PORT2ADDR(port) = b;
170}
171
172void microdev_outl(unsigned int b, unsigned long port)
173{
174#ifdef CONFIG_PCI
175 if (port >= PCIBIOS_MIN_IO) {
176 microdev_pci_outl(b, port);
177 return;
178 }
179#endif
180 *(volatile unsigned int*)PORT2ADDR(port) = b;
181}
182
183unsigned char microdev_inb_p(unsigned long port)
184{
185 unsigned char v = microdev_inb(port);
186 delay();
187 return v;
188}
189
190unsigned short microdev_inw_p(unsigned long port)
191{
192 unsigned short v = microdev_inw(port);
193 delay();
194 return v;
195}
196
197unsigned int microdev_inl_p(unsigned long port)
198{
199 unsigned int v = microdev_inl(port);
200 delay();
201 return v;
202}
203
204void microdev_outb_p(unsigned char b, unsigned long port)
205{
206 microdev_outb(b, port);
207 delay();
208}
209
210void microdev_outw_p(unsigned short b, unsigned long port)
211{
212 microdev_outw(b, port);
213 delay();
214}
215
216void microdev_outl_p(unsigned int b, unsigned long port)
217{
218 microdev_outl(b, port);
219 delay();
220}
221
222void microdev_insb(unsigned long port, void *buffer, unsigned long count)
223{
224 volatile unsigned char *port_addr;
225 unsigned char *buf = buffer;
226
227 port_addr = (volatile unsigned char *)PORT2ADDR(port);
228
229 while (count--)
230 *buf++ = *port_addr;
231}
232
233void microdev_insw(unsigned long port, void *buffer, unsigned long count)
234{
235 volatile unsigned short *port_addr;
236 unsigned short *buf = buffer;
237
238 port_addr = (volatile unsigned short *)PORT2ADDR(port);
239
240 while (count--)
241 *buf++ = *port_addr;
242}
243
244void microdev_insl(unsigned long port, void *buffer, unsigned long count)
245{
246 volatile unsigned long *port_addr;
247 unsigned int *buf = buffer;
248
249 port_addr = (volatile unsigned long *)PORT2ADDR(port);
250
251 while (count--)
252 *buf++ = *port_addr;
253}
254
255void microdev_outsb(unsigned long port, const void *buffer, unsigned long count)
256{
257 volatile unsigned char *port_addr;
258 const unsigned char *buf = buffer;
259
260 port_addr = (volatile unsigned char *)PORT2ADDR(port);
261
262 while (count--)
263 *port_addr = *buf++;
264}
265
266void microdev_outsw(unsigned long port, const void *buffer, unsigned long count)
267{
268 volatile unsigned short *port_addr;
269 const unsigned short *buf = buffer;
270
271 port_addr = (volatile unsigned short *)PORT2ADDR(port);
272
273 while (count--)
274 *port_addr = *buf++;
275}
276
277void microdev_outsl(unsigned long port, const void *buffer, unsigned long count)
278{
279 volatile unsigned long *port_addr;
280 const unsigned int *buf = buffer;
281
282 port_addr = (volatile unsigned long *)PORT2ADDR(port);
283
284 while (count--)
285 *port_addr = *buf++;
286}
287
288/*
289 * map I/O ports to memory-mapped addresses
290 */
291unsigned long microdev_isa_port2addr(unsigned long offset)
292{
293 unsigned long result;
294
295 if ((offset >= IO_LAN91C111_BASE) &&
296 (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
297 /*
298 * SMSC LAN91C111 Ethernet chip
299 */
300 result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE;
301 } else if ((offset >= IO_SUPERIO_BASE) &&
302 (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) {
303 /*
304 * SMSC FDC37C93xAPM SuperIO chip
305 *
306 * Configuration Registers
307 */
308 result = IO_SUPERIO_PHYS + (offset << 1);
309#if 0
310 } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG ||
311 offset == KBD_STATUS_REG) {
312 /*
313 * SMSC FDC37C93xAPM SuperIO chip
314 *
315 * PS/2 Keyboard + Mouse (ports 0x60 and 0x64).
316 */
317 result = IO_SUPERIO_PHYS + (offset << 1);
318#endif
319 } else if (((offset >= IO_IDE1_BASE) &&
320 (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) ||
321 (offset == IO_IDE1_MISC)) {
322 /*
323 * SMSC FDC37C93xAPM SuperIO chip
324 *
325 * IDE #1
326 */
327 result = IO_SUPERIO_PHYS + (offset << 1);
328 } else if (((offset >= IO_IDE2_BASE) &&
329 (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) ||
330 (offset == IO_IDE2_MISC)) {
331 /*
332 * SMSC FDC37C93xAPM SuperIO chip
333 *
334 * IDE #2
335 */
336 result = IO_SUPERIO_PHYS + (offset << 1);
337 } else if ((offset >= IO_SERIAL1_BASE) &&
338 (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) {
339 /*
340 * SMSC FDC37C93xAPM SuperIO chip
341 *
342 * Serial #1
343 */
344 result = IO_SUPERIO_PHYS + (offset << 1);
345 } else if ((offset >= IO_SERIAL2_BASE) &&
346 (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) {
347 /*
348 * SMSC FDC37C93xAPM SuperIO chip
349 *
350 * Serial #2
351 */
352 result = IO_SUPERIO_PHYS + (offset << 1);
353 } else if ((offset >= IO_ISP1161_BASE) &&
354 (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) {
355 /*
356 * Philips USB ISP1161x chip
357 */
358 result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE;
359 } else {
360 /*
361 * safe default.
362 */
363 printk("Warning: unexpected port in %s( offset = 0x%lx )\n",
364 __FUNCTION__, offset);
365 result = PVR;
366 }
367
368 return result;
369}
370
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c
new file mode 100644
index 000000000000..1298883eca4b
--- /dev/null
+++ b/arch/sh/boards/superh/microdev/irq.c
@@ -0,0 +1,200 @@
1/*
2 * arch/sh/boards/superh/microdev/irq.c
3 *
4 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5 *
6 * SuperH SH4-202 MicroDev board support.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <asm/system.h>
17#include <asm/io.h>
18#include <asm/mach/irq.h>
19
20#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */
21
22
23static const struct {
24 unsigned char fpgaIrq;
25 unsigned char mapped;
26 const char *name;
27} fpgaIrqTable[NUM_EXTERNAL_IRQS] = {
28 { 0, 0, "unused" }, /* IRQ #0 IRL=15 0x200 */
29 { MICRODEV_FPGA_IRQ_KEYBOARD, 1, "keyboard" }, /* IRQ #1 IRL=14 0x220 */
30 { MICRODEV_FPGA_IRQ_SERIAL1, 1, "Serial #1"}, /* IRQ #2 IRL=13 0x240 */
31 { MICRODEV_FPGA_IRQ_ETHERNET, 1, "Ethernet" }, /* IRQ #3 IRL=12 0x260 */
32 { MICRODEV_FPGA_IRQ_SERIAL2, 0, "Serial #2"}, /* IRQ #4 IRL=11 0x280 */
33 { 0, 0, "unused" }, /* IRQ #5 IRL=10 0x2a0 */
34 { 0, 0, "unused" }, /* IRQ #6 IRL=9 0x2c0 */
35 { MICRODEV_FPGA_IRQ_USB_HC, 1, "USB" }, /* IRQ #7 IRL=8 0x2e0 */
36 { MICRODEV_IRQ_PCI_INTA, 1, "PCI INTA" }, /* IRQ #8 IRL=7 0x300 */
37 { MICRODEV_IRQ_PCI_INTB, 1, "PCI INTB" }, /* IRQ #9 IRL=6 0x320 */
38 { MICRODEV_IRQ_PCI_INTC, 1, "PCI INTC" }, /* IRQ #10 IRL=5 0x340 */
39 { MICRODEV_IRQ_PCI_INTD, 1, "PCI INTD" }, /* IRQ #11 IRL=4 0x360 */
40 { MICRODEV_FPGA_IRQ_MOUSE, 1, "mouse" }, /* IRQ #12 IRL=3 0x380 */
41 { MICRODEV_FPGA_IRQ_IDE2, 1, "IDE #2" }, /* IRQ #13 IRL=2 0x3a0 */
42 { MICRODEV_FPGA_IRQ_IDE1, 1, "IDE #1" }, /* IRQ #14 IRL=1 0x3c0 */
43 { 0, 0, "unused" }, /* IRQ #15 IRL=0 0x3e0 */
44};
45
46#if (MICRODEV_LINUX_IRQ_KEYBOARD != 1)
47# error Inconsistancy in defining the IRQ# for Keyboard!
48#endif
49
50#if (MICRODEV_LINUX_IRQ_ETHERNET != 3)
51# error Inconsistancy in defining the IRQ# for Ethernet!
52#endif
53
54#if (MICRODEV_LINUX_IRQ_USB_HC != 7)
55# error Inconsistancy in defining the IRQ# for USB!
56#endif
57
58#if (MICRODEV_LINUX_IRQ_MOUSE != 12)
59# error Inconsistancy in defining the IRQ# for PS/2 Mouse!
60#endif
61
62#if (MICRODEV_LINUX_IRQ_IDE2 != 13)
63# error Inconsistancy in defining the IRQ# for secondary IDE!
64#endif
65
66#if (MICRODEV_LINUX_IRQ_IDE1 != 14)
67# error Inconsistancy in defining the IRQ# for primary IDE!
68#endif
69
70static void enable_microdev_irq(unsigned int irq);
71static void disable_microdev_irq(unsigned int irq);
72
73 /* shutdown is same as "disable" */
74#define shutdown_microdev_irq disable_microdev_irq
75
76static void mask_and_ack_microdev(unsigned int);
77static void end_microdev_irq(unsigned int irq);
78
79static unsigned int startup_microdev_irq(unsigned int irq)
80{
81 enable_microdev_irq(irq);
82 return 0; /* never anything pending */
83}
84
85static struct hw_interrupt_type microdev_irq_type = {
86 "MicroDev-IRQ",
87 startup_microdev_irq,
88 shutdown_microdev_irq,
89 enable_microdev_irq,
90 disable_microdev_irq,
91 mask_and_ack_microdev,
92 end_microdev_irq
93};
94
95static void disable_microdev_irq(unsigned int irq)
96{
97 unsigned int flags;
98 unsigned int fpgaIrq;
99
100 if (irq >= NUM_EXTERNAL_IRQS) return;
101 if (!fpgaIrqTable[irq].mapped) return;
102
103 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
104
105 /* disable interrupts */
106 local_irq_save(flags);
107
108 /* disable interupts on the FPGA INTC register */
109 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
110
111 /* restore interrupts */
112 local_irq_restore(flags);
113}
114
115static void enable_microdev_irq(unsigned int irq)
116{
117 unsigned long priorityReg, priorities, pri;
118 unsigned int flags;
119 unsigned int fpgaIrq;
120
121
122 if (irq >= NUM_EXTERNAL_IRQS) return;
123 if (!fpgaIrqTable[irq].mapped) return;
124
125 pri = 15 - irq;
126
127 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
128 priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
129
130 /* disable interrupts */
131 local_irq_save(flags);
132
133 /* set priority for the interrupt */
134 priorities = ctrl_inl(priorityReg);
135 priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
136 priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
137 ctrl_outl(priorities, priorityReg);
138
139 /* enable interupts on the FPGA INTC register */
140 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
141
142 /* restore interrupts */
143 local_irq_restore(flags);
144}
145
146 /* This functions sets the desired irq handler to be a MicroDev type */
147static void __init make_microdev_irq(unsigned int irq)
148{
149 disable_irq_nosync(irq);
150 irq_desc[irq].handler = &microdev_irq_type;
151 disable_microdev_irq(irq);
152}
153
154static void mask_and_ack_microdev(unsigned int irq)
155{
156 disable_microdev_irq(irq);
157}
158
159static void end_microdev_irq(unsigned int irq)
160{
161 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
162 {
163 enable_microdev_irq(irq);
164 }
165}
166
167extern void __init init_microdev_irq(void)
168{
169 int i;
170
171 /* disable interupts on the FPGA INTC register */
172 ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
173
174 for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
175 {
176 make_microdev_irq(i);
177 }
178}
179
180extern void microdev_print_fpga_intc_status(void)
181{
182 volatile unsigned int * const intenb = (unsigned int*)MICRODEV_FPGA_INTENB_REG;
183 volatile unsigned int * const intdsb = (unsigned int*)MICRODEV_FPGA_INTDSB_REG;
184 volatile unsigned int * const intpria = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(0);
185 volatile unsigned int * const intprib = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(8);
186 volatile unsigned int * const intpric = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(16);
187 volatile unsigned int * const intprid = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(24);
188 volatile unsigned int * const intsrc = (unsigned int*)MICRODEV_FPGA_INTSRC_REG;
189 volatile unsigned int * const intreq = (unsigned int*)MICRODEV_FPGA_INTREQ_REG;
190
191 printk("-------------------------- microdev_print_fpga_intc_status() ------------------\n");
192 printk("FPGA_INTENB = 0x%08x\n", *intenb);
193 printk("FPGA_INTDSB = 0x%08x\n", *intdsb);
194 printk("FPGA_INTSRC = 0x%08x\n", *intsrc);
195 printk("FPGA_INTREQ = 0x%08x\n", *intreq);
196 printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);
197 printk("-------------------------------------------------------------------------------\n");
198}
199
200
diff --git a/arch/sh/boards/superh/microdev/led.c b/arch/sh/boards/superh/microdev/led.c
new file mode 100644
index 000000000000..52a98e69d3f0
--- /dev/null
+++ b/arch/sh/boards/superh/microdev/led.c
@@ -0,0 +1,102 @@
1/*
2 * linux/arch/sh/kernel/led_microdev.c
3 *
4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
5 * Copyright (C) 2003 Richard Curnow (Richard.Curnow@superh.com)
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 */
11
12#include <linux/config.h>
13#include <asm/io.h>
14
15#define LED_REGISTER 0xa6104d20
16
17static void mach_led_d9(int value)
18{
19 unsigned long reg;
20 reg = ctrl_inl(LED_REGISTER);
21 reg &= ~1;
22 reg |= (value & 1);
23 ctrl_outl(reg, LED_REGISTER);
24 return;
25}
26
27static void mach_led_d10(int value)
28{
29 unsigned long reg;
30 reg = ctrl_inl(LED_REGISTER);
31 reg &= ~2;
32 reg |= ((value & 1) << 1);
33 ctrl_outl(reg, LED_REGISTER);
34 return;
35}
36
37
38#ifdef CONFIG_HEARTBEAT
39#include <linux/sched.h>
40
41static unsigned char banner_table[] = {
42 0x11, 0x01, 0x11, 0x01, 0x11, 0x03,
43 0x11, 0x01, 0x11, 0x01, 0x13, 0x03,
44 0x11, 0x01, 0x13, 0x01, 0x13, 0x01, 0x11, 0x03,
45 0x11, 0x03,
46 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
47 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x07,
48 0x13, 0x01, 0x13, 0x03,
49 0x11, 0x01, 0x11, 0x03,
50 0x13, 0x01, 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
51 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
52 0x13, 0x01, 0x13, 0x01, 0x13, 0x03,
53 0x13, 0x01, 0x11, 0x01, 0x11, 0x03,
54 0x11, 0x03,
55 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x13, 0x07,
56 0xff
57};
58
59static void banner(void)
60{
61 static int pos = 0;
62 static int count = 0;
63
64 if (count) {
65 count--;
66 } else {
67 int val = banner_table[pos];
68 if (val == 0xff) {
69 pos = 0;
70 val = banner_table[pos];
71 }
72 pos++;
73 mach_led_d10((val >> 4) & 1);
74 count = 10 * (val & 0xf);
75 }
76}
77
78/* From heartbeat_harp in the stboards directory */
79/* acts like an actual heart beat -- ie thump-thump-pause... */
80void microdev_heartbeat(void)
81{
82 static unsigned cnt = 0, period = 0, dist = 0;
83
84 if (cnt == 0 || cnt == dist)
85 mach_led_d9(1);
86 else if (cnt == 7 || cnt == dist+7)
87 mach_led_d9(0);
88
89 if (++cnt > period) {
90 cnt = 0;
91 /* The hyperbolic function below modifies the heartbeat period
92 * length in dependency of the current (5min) load. It goes
93 * through the points f(0)=126, f(1)=86, f(5)=51,
94 * f(inf)->30. */
95 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
96 dist = period / 4;
97 }
98
99 banner();
100}
101
102#endif
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c
new file mode 100644
index 000000000000..c18919941ec0
--- /dev/null
+++ b/arch/sh/boards/superh/microdev/setup.c
@@ -0,0 +1,278 @@
1/*
2 * arch/sh/boards/superh/microdev/setup.c
3 *
4 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5 * Copyright (C) 2003, 2004 SuperH, Inc.
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * SuperH SH4-202 MicroDev board support.
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <linux/ioport.h>
18#include <asm/io.h>
19#include <asm/mach/irq.h>
20#include <asm/mach/io.h>
21#include <asm/machvec.h>
22#include <asm/machvec_init.h>
23
24extern void microdev_heartbeat(void);
25
26/*
27 * The Machine Vector
28 */
29
30struct sh_machine_vector mv_sh4202_microdev __initmv = {
31 .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */
32
33 .mv_inb = microdev_inb,
34 .mv_inw = microdev_inw,
35 .mv_inl = microdev_inl,
36 .mv_outb = microdev_outb,
37 .mv_outw = microdev_outw,
38 .mv_outl = microdev_outl,
39
40 .mv_inb_p = microdev_inb_p,
41 .mv_inw_p = microdev_inw_p,
42 .mv_inl_p = microdev_inl_p,
43 .mv_outb_p = microdev_outb_p,
44 .mv_outw_p = microdev_outw_p,
45 .mv_outl_p = microdev_outl_p,
46
47 .mv_insb = microdev_insb,
48 .mv_insw = microdev_insw,
49 .mv_insl = microdev_insl,
50 .mv_outsb = microdev_outsb,
51 .mv_outsw = microdev_outsw,
52 .mv_outsl = microdev_outsl,
53
54 .mv_isa_port2addr = microdev_isa_port2addr,
55
56 .mv_init_irq = init_microdev_irq,
57
58#ifdef CONFIG_HEARTBEAT
59 .mv_heartbeat = microdev_heartbeat,
60#endif
61};
62ALIAS_MV(sh4202_microdev)
63
64/****************************************************************************/
65
66
67 /*
68 * Setup for the SMSC FDC37C93xAPM
69 */
70#define SMSC_CONFIG_PORT_ADDR (0x3F0)
71#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR
72#define SMSC_DATA_PORT_ADDR (SMSC_INDEX_PORT_ADDR + 1)
73
74#define SMSC_ENTER_CONFIG_KEY 0x55
75#define SMSC_EXIT_CONFIG_KEY 0xaa
76
77#define SMCS_LOGICAL_DEV_INDEX 0x07 /* Logical Device Number */
78#define SMSC_DEVICE_ID_INDEX 0x20 /* Device ID */
79#define SMSC_DEVICE_REV_INDEX 0x21 /* Device Revision */
80#define SMSC_ACTIVATE_INDEX 0x30 /* Activate */
81#define SMSC_PRIMARY_BASE_INDEX 0x60 /* Primary Base Address */
82#define SMSC_SECONDARY_BASE_INDEX 0x62 /* Secondary Base Address */
83#define SMSC_PRIMARY_INT_INDEX 0x70 /* Primary Interrupt Select */
84#define SMSC_SECONDARY_INT_INDEX 0x72 /* Secondary Interrupt Select */
85#define SMSC_HDCS0_INDEX 0xf0 /* HDCS0 Address Decoder */
86#define SMSC_HDCS1_INDEX 0xf1 /* HDCS1 Address Decoder */
87
88#define SMSC_IDE1_DEVICE 1 /* IDE #1 logical device */
89#define SMSC_IDE2_DEVICE 2 /* IDE #2 logical device */
90#define SMSC_PARALLEL_DEVICE 3 /* Parallel Port logical device */
91#define SMSC_SERIAL1_DEVICE 4 /* Serial #1 logical device */
92#define SMSC_SERIAL2_DEVICE 5 /* Serial #2 logical device */
93#define SMSC_KEYBOARD_DEVICE 7 /* Keyboard logical device */
94#define SMSC_CONFIG_REGISTERS 8 /* Configuration Registers (Aux I/O) */
95
96#define SMSC_READ_INDEXED(index) ({ \
97 outb((index), SMSC_INDEX_PORT_ADDR); \
98 inb(SMSC_DATA_PORT_ADDR); })
99#define SMSC_WRITE_INDEXED(val, index) ({ \
100 outb((index), SMSC_INDEX_PORT_ADDR); \
101 outb((val), SMSC_DATA_PORT_ADDR); })
102
103#define IDE1_PRIMARY_BASE 0x01f0 /* Task File Registe base for IDE #1 */
104#define IDE1_SECONDARY_BASE 0x03f6 /* Miscellaneous AT registers for IDE #1 */
105#define IDE2_PRIMARY_BASE 0x0170 /* Task File Registe base for IDE #2 */
106#define IDE2_SECONDARY_BASE 0x0376 /* Miscellaneous AT registers for IDE #2 */
107
108#define SERIAL1_PRIMARY_BASE 0x03f8
109#define SERIAL2_PRIMARY_BASE 0x02f8
110
111#define MSB(x) ( (x) >> 8 )
112#define LSB(x) ( (x) & 0xff )
113
114 /* General-Purpose base address on CPU-board FPGA */
115#define MICRODEV_FPGA_GP_BASE 0xa6100000ul
116
117 /* assume a Keyboard Controller is present */
118int microdev_kbd_controller_present = 1;
119
120const char *get_system_type(void)
121{
122 return "SH4-202 MicroDev";
123}
124
125static struct resource smc91x_resources[] = {
126 [0] = {
127 .start = 0x300,
128 .end = 0x300 + 0x0001000 - 1,
129 .flags = IORESOURCE_MEM,
130 },
131 [1] = {
132 .start = MICRODEV_LINUX_IRQ_ETHERNET,
133 .end = MICRODEV_LINUX_IRQ_ETHERNET,
134 .flags = IORESOURCE_IRQ,
135 },
136};
137
138static struct platform_device smc91x_device = {
139 .name = "smc91x",
140 .id = -1,
141 .num_resources = ARRAY_SIZE(smc91x_resources),
142 .resource = smc91x_resources,
143};
144
145static int __init smc91x_setup(void)
146{
147 return platform_device_register(&smc91x_device);
148}
149
150__initcall(smc91x_setup);
151
152 /*
153 * Initialize the board
154 */
155void __init platform_setup(void)
156{
157 int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
158 const int fpgaRevision = *fpgaRevisionRegister;
159 int * const CacheControlRegister = (int*)CCR;
160
161 printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
162 get_system_type(), fpgaRevision, *CacheControlRegister);
163}
164
165
166/****************************************************************************/
167
168
169 /*
170 * Setup for the SMSC FDC37C93xAPM
171 */
172static int __init smsc_superio_setup(void)
173{
174
175 unsigned char devid, devrev;
176
177 /* Initially the chip is in run state */
178 /* Put it into configuration state */
179 outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
180
181 /* Read device ID info */
182 devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
183 devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
184 if ( (devid==0x30) && (devrev==0x01) )
185 {
186 printk("SMSC FDC37C93xAPM SuperIO device detected\n");
187 }
188 else
189 { /* not the device identity we expected */
190 printk("Not detected a SMSC FDC37C93xAPM SuperIO device (devid=0x%02x, rev=0x%02x)\n",
191 devid, devrev);
192 /* inform the keyboard driver that we have no keyboard controller */
193 microdev_kbd_controller_present = 0;
194 /* little point in doing anything else in this functon */
195 return 0;
196 }
197
198 /* Select the keyboard device */
199 SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
200 /* enable it */
201 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
202 /* enable the interrupts */
203 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
204 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
205
206 /* Select the Serial #1 device */
207 SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
208 /* enable it */
209 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
210 /* program with port addresses */
211 SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
212 SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
213 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
214 /* enable the interrupts */
215 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
216
217 /* Select the Serial #2 device */
218 SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
219 /* enable it */
220 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
221 /* program with port addresses */
222 SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
223 SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
224 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
225 /* enable the interrupts */
226 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
227
228 /* Select the IDE#1 device */
229 SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
230 /* enable it */
231 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
232 /* program with port addresses */
233 SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
234 SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
235 SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
236 SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
237 SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
238 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
239 /* select the interrupt */
240 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
241
242 /* Select the IDE#2 device */
243 SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
244 /* enable it */
245 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
246 /* program with port addresses */
247 SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
248 SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
249 SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
250 SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
251 /* select the interrupt */
252 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
253
254 /* Select the configuration registers */
255 SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
256 /* enable the appropriate GPIO pins for IDE functionality:
257 * bit[0] In/Out 1==input; 0==output
258 * bit[1] Polarity 1==invert; 0==no invert
259 * bit[2] Int Enb #1 1==Enable Combined IRQ #1; 0==disable
260 * bit[3:4] Function Select 00==original; 01==Alternate Function #1
261 */
262 SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
263 SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
264 SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
265 SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
266 SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
267
268 /* Exit the configuraton state */
269 outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
270
271 return 0;
272}
273
274
275/* This is grotty, but, because kernel is always referenced on the link line
276 * before any devices, this is safe.
277 */
278__initcall(smsc_superio_setup);
diff --git a/arch/sh/boards/unknown/Makefile b/arch/sh/boards/unknown/Makefile
new file mode 100644
index 000000000000..cffc21031e71
--- /dev/null
+++ b/arch/sh/boards/unknown/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for unknown SH boards
3#
4
5obj-y := mach.o io.o setup.o
6
diff --git a/arch/sh/boards/unknown/io.c b/arch/sh/boards/unknown/io.c
new file mode 100644
index 000000000000..8f3f17267bd9
--- /dev/null
+++ b/arch/sh/boards/unknown/io.c
@@ -0,0 +1,46 @@
1/*
2 * linux/arch/sh/kernel/io_unknown.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * I/O routine for unknown hardware.
10 */
11
12static unsigned int unknown_handler(void)
13{
14 return 0;
15}
16
17#define UNKNOWN_ALIAS(fn) \
18 void unknown_##fn(void) __attribute__ ((alias ("unknown_handler")));
19
20UNKNOWN_ALIAS(inb)
21UNKNOWN_ALIAS(inw)
22UNKNOWN_ALIAS(inl)
23UNKNOWN_ALIAS(outb)
24UNKNOWN_ALIAS(outw)
25UNKNOWN_ALIAS(outl)
26UNKNOWN_ALIAS(inb_p)
27UNKNOWN_ALIAS(inw_p)
28UNKNOWN_ALIAS(inl_p)
29UNKNOWN_ALIAS(outb_p)
30UNKNOWN_ALIAS(outw_p)
31UNKNOWN_ALIAS(outl_p)
32UNKNOWN_ALIAS(insb)
33UNKNOWN_ALIAS(insw)
34UNKNOWN_ALIAS(insl)
35UNKNOWN_ALIAS(outsb)
36UNKNOWN_ALIAS(outsw)
37UNKNOWN_ALIAS(outsl)
38UNKNOWN_ALIAS(readb)
39UNKNOWN_ALIAS(readw)
40UNKNOWN_ALIAS(readl)
41UNKNOWN_ALIAS(writeb)
42UNKNOWN_ALIAS(writew)
43UNKNOWN_ALIAS(writel)
44UNKNOWN_ALIAS(isa_port2addr)
45UNKNOWN_ALIAS(ioremap)
46UNKNOWN_ALIAS(iounmap)
diff --git a/arch/sh/boards/unknown/mach.c b/arch/sh/boards/unknown/mach.c
new file mode 100644
index 000000000000..ad0bcc60a640
--- /dev/null
+++ b/arch/sh/boards/unknown/mach.c
@@ -0,0 +1,67 @@
1/*
2 * linux/arch/sh/kernel/mach_unknown.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine specific code for an unknown machine (internal peripherials only)
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14
15#include <asm/machvec.h>
16#include <asm/machvec_init.h>
17
18#include <asm/io_unknown.h>
19
20#include <asm/rtc.h>
21/*
22 * The Machine Vector
23 */
24
25struct sh_machine_vector mv_unknown __initmv = {
26#if defined(CONFIG_CPU_SH4)
27 .mv_nr_irqs = 48,
28#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
29 .mv_nr_irqs = 32,
30#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
31 .mv_nr_irqs = 61,
32#endif
33
34 .mv_inb = unknown_inb,
35 .mv_inw = unknown_inw,
36 .mv_inl = unknown_inl,
37 .mv_outb = unknown_outb,
38 .mv_outw = unknown_outw,
39 .mv_outl = unknown_outl,
40
41 .mv_inb_p = unknown_inb_p,
42 .mv_inw_p = unknown_inw_p,
43 .mv_inl_p = unknown_inl_p,
44 .mv_outb_p = unknown_outb_p,
45 .mv_outw_p = unknown_outw_p,
46 .mv_outl_p = unknown_outl_p,
47
48 .mv_insb = unknown_insb,
49 .mv_insw = unknown_insw,
50 .mv_insl = unknown_insl,
51 .mv_outsb = unknown_outsb,
52 .mv_outsw = unknown_outsw,
53 .mv_outsl = unknown_outsl,
54
55 .mv_readb = unknown_readb,
56 .mv_readw = unknown_readw,
57 .mv_readl = unknown_readl,
58 .mv_writeb = unknown_writeb,
59 .mv_writew = unknown_writew,
60 .mv_writel = unknown_writel,
61
62 .mv_ioremap = unknown_ioremap,
63 .mv_iounmap = unknown_iounmap,
64
65 .mv_isa_port2addr = unknown_isa_port2addr,
66};
67ALIAS_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 @@
1/*
2 * linux/arch/sh/boards/unknown/setup.c
3 *
4 * Copyright (C) 2002 Paul Mundt
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Setup code for an unknown machine (internal peripherials only)
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14
15const char *get_system_type(void)
16{
17 return "Unknown";
18}
19
20void __init platform_setup(void)
21{
22}
23
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
new file mode 100644
index 000000000000..60797b31089c
--- /dev/null
+++ b/arch/sh/boot/Makefile
@@ -0,0 +1,20 @@
1#
2# arch/sh/boot/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8# Copyright (C) 1999 Stuart Menefy
9#
10
11targets := zImage
12subdir- := compressed
13
14$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
15 $(call if_changed,objcopy)
16 @echo 'Kernel: $@ is ready'
17
18$(obj)/compressed/vmlinux: FORCE
19 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
20
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
new file mode 100644
index 000000000000..75a6876bf6c6
--- /dev/null
+++ b/arch/sh/boot/compressed/Makefile
@@ -0,0 +1,41 @@
1#
2# linux/arch/sh/boot/compressed/Makefile
3#
4# create a compressed vmlinux image from the original vmlinux
5#
6
7targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
8EXTRA_AFLAGS := -traditional
9
10OBJECTS = $(obj)/head.o $(obj)/misc.o
11
12ifdef CONFIG_SH_STANDARD_BIOS
13OBJECTS += $(obj)/../../kernel/sh_bios.o
14endif
15
16#
17# IMAGE_OFFSET is the load offset of the compression loader
18# Assign dummy values if these 2 variables are not defined,
19# in order to suppress error message.
20#
21CONFIG_MEMORY_START ?= 0x0c000000
22CONFIG_BOOT_LINK_OFFSET ?= 0x00800000
23IMAGE_OFFSET := $(shell printf "0x%8x" $$[0x80000000+$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)])
24
25LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds
26
27$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
28 $(call if_changed,ld)
29 @:
30
31$(obj)/vmlinux.bin: vmlinux FORCE
32 $(call if_changed,objcopy)
33
34$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
35 $(call if_changed,gzip)
36
37LDFLAGS_piggy.o := -r --format binary --oformat elf32-sh-linux -T
38OBJCOPYFLAGS += -R .empty_zero_page
39
40$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
41 $(call if_changed,ld)
diff --git a/arch/sh/boot/compressed/head.S b/arch/sh/boot/compressed/head.S
new file mode 100644
index 000000000000..88db04d325fb
--- /dev/null
+++ b/arch/sh/boot/compressed/head.S
@@ -0,0 +1,120 @@
1/*
2 * linux/arch/sh/boot/compressed/head.S
3 *
4 * Copyright (C) 1999 Stuart Menefy
5 * Copyright (C) 2003 SUGIOKA Toshinobu
6 */
7
8.text
9
10#include <linux/config.h>
11#include <linux/linkage.h>
12
13 .global startup
14startup:
15 /* Load initial status register */
16 mov.l init_sr, r1
17 ldc r1, sr
18
19 /* Move myself to proper location if necessary */
20 mova 1f, r0
21 mov.l 1f, r2
22 cmp/eq r2, r0
23 bt clear_bss
24 sub r0, r2
25 mov.l bss_start_addr, r0
26 mov #0xe0, r1
27 and r1, r0 ! align cache line
28 mov.l text_start_addr, r3
29 mov r0, r1
30 sub r2, r1
313:
32 mov.l @r1, r4
33 mov.l @(4,r1), r5
34 mov.l @(8,r1), r6
35 mov.l @(12,r1), r7
36 mov.l @(16,r1), r8
37 mov.l @(20,r1), r9
38 mov.l @(24,r1), r10
39 mov.l @(28,r1), r11
40 mov.l r4, @r0
41 mov.l r5, @(4,r0)
42 mov.l r6, @(8,r0)
43 mov.l r7, @(12,r0)
44 mov.l r8, @(16,r0)
45 mov.l r9, @(20,r0)
46 mov.l r10, @(24,r0)
47 mov.l r11, @(28,r0)
48#ifdef CONFIG_CPU_SH4
49 ocbwb @r0
50#endif
51 cmp/hi r3, r0
52 add #-32, r0
53 bt/s 3b
54 add #-32, r1
55 mov.l 2f, r0
56 jmp @r0
57 nop
58
59 .align 2
601: .long 1b
612: .long clear_bss
62text_start_addr:
63 .long startup
64
65 /* Clear BSS */
66clear_bss:
67 mov.l end_addr, r1
68 mov.l bss_start_addr, r2
69 mov #0, r0
70l1:
71 mov.l r0, @-r1
72 cmp/eq r1,r2
73 bf l1
74
75 /* Set the initial pointer. */
76 mov.l init_stack_addr, r0
77 mov.l @r0, r15
78
79 /* Decompress the kernel */
80 mov.l decompress_kernel_addr, r0
81 jsr @r0
82 nop
83
84 /* Jump to the start of the decompressed kernel */
85 mov.l kernel_start_addr, r0
86 jmp @r0
87 nop
88
89 .align 2
90bss_start_addr:
91 .long __bss_start
92end_addr:
93 .long _end
94init_sr:
95 .long 0x400000F0 /* Privileged mode, Bank=0, Block=0, IMASK=0xF */
96init_stack_addr:
97 .long stack_start
98decompress_kernel_addr:
99 .long decompress_kernel
100kernel_start_addr:
101 .long _text+0x1000
102
103 .align 9
104fake_headers_as_bzImage:
105 .word 0
106 .ascii "HdrS" ! header signature
107 .word 0x0202 ! header version number (>= 0x0105)
108 ! or else old loadlin-1.5 will fail)
109 .word 0 ! default_switch
110 .word 0 ! SETUPSEG
111 .word 0x1000
112 .word 0 ! pointing to kernel version string
113 .byte 0 ! = 0, old one (LILO, Loadlin,
114 ! 0xTV: T=0 for LILO
115 ! V = version
116 .byte 1 ! Load flags bzImage=1
117 .word 0x8000 ! size to move, when setup is not
118 .long 0x100000 ! 0x100000 = default for big kernel
119 .long 0 ! address of loaded ramdisk image
120 .long 0 # its size in bytes
diff --git a/arch/sh/boot/compressed/install.sh b/arch/sh/boot/compressed/install.sh
new file mode 100644
index 000000000000..90589f0fec12
--- /dev/null
+++ b/arch/sh/boot/compressed/install.sh
@@ -0,0 +1,56 @@
1#!/bin/sh
2#
3# arch/sh/boot/install.sh
4#
5# This file is subject to the terms and conditions of the GNU General Public
6# License. See the file "COPYING" in the main directory of this archive
7# for more details.
8#
9# Copyright (C) 1995 by Linus Torvalds
10#
11# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
12# Adapted from code in arch/i386/boot/install.sh by Russell King
13# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
14#
15# "make install" script for sh architecture
16#
17# Arguments:
18# $1 - kernel version
19# $2 - kernel image file
20# $3 - kernel map file
21# $4 - default install path (blank if root directory)
22#
23
24# User may have a custom install script
25
26if [ -x /sbin/installkernel ]; then
27 exec /sbin/installkernel "$@"
28fi
29
30if [ "$2" = "zImage" ]; then
31# Compressed install
32 echo "Installing compressed kernel"
33 if [ -f $4/vmlinuz-$1 ]; then
34 mv $4/vmlinuz-$1 $4/vmlinuz.old
35 fi
36
37 if [ -f $4/System.map-$1 ]; then
38 mv $4/System.map-$1 $4/System.old
39 fi
40
41 cat $2 > $4/vmlinuz-$1
42 cp $3 $4/System.map-$1
43else
44# Normal install
45 echo "Installing normal kernel"
46 if [ -f $4/vmlinux-$1 ]; then
47 mv $4/vmlinux-$1 $4/vmlinux.old
48 fi
49
50 if [ -f $4/System.map ]; then
51 mv $4/System.map $4/System.old
52 fi
53
54 cat $2 > $4/vmlinux-$1
55 cp $3 $4/System.map
56fi
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
new file mode 100644
index 000000000000..211e9110074f
--- /dev/null
+++ b/arch/sh/boot/compressed/misc.c
@@ -0,0 +1,240 @@
1/*
2 * arch/sh/boot/compressed/misc.c
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 *
9 * Adapted for SH by Stuart Menefy, Aug 1999
10 *
11 * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
12 */
13
14#include <linux/config.h>
15#include <asm/uaccess.h>
16#ifdef CONFIG_SH_STANDARD_BIOS
17#include <asm/sh_bios.h>
18#endif
19
20/*
21 * gzip declarations
22 */
23
24#define OF(args) args
25#define STATIC static
26
27#undef memset
28#undef memcpy
29#define memzero(s, n) memset ((s), 0, (n))
30
31typedef unsigned char uch;
32typedef unsigned short ush;
33typedef unsigned long ulg;
34
35#define WSIZE 0x8000 /* Window size must be at least 32k, */
36 /* and a power of two */
37
38static uch *inbuf; /* input buffer */
39static uch window[WSIZE]; /* Sliding window buffer */
40
41static unsigned insize = 0; /* valid bytes in inbuf */
42static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
43static unsigned outcnt = 0; /* bytes in output buffer */
44
45/* gzip flag byte */
46#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
47#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
48#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
49#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
50#define COMMENT 0x10 /* bit 4 set: file comment present */
51#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
52#define RESERVED 0xC0 /* bit 6,7: reserved */
53
54#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
55
56/* Diagnostic functions */
57#ifdef DEBUG
58# define Assert(cond,msg) {if(!(cond)) error(msg);}
59# define Trace(x) fprintf x
60# define Tracev(x) {if (verbose) fprintf x ;}
61# define Tracevv(x) {if (verbose>1) fprintf x ;}
62# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
63# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
64#else
65# define Assert(cond,msg)
66# define Trace(x)
67# define Tracev(x)
68# define Tracevv(x)
69# define Tracec(c,x)
70# define Tracecv(c,x)
71#endif
72
73static int fill_inbuf(void);
74static void flush_window(void);
75static void error(char *m);
76static void gzip_mark(void **);
77static void gzip_release(void **);
78
79extern char input_data[];
80extern int input_len;
81
82static long bytes_out = 0;
83static uch *output_data;
84static unsigned long output_ptr = 0;
85
86static void *malloc(int size);
87static void free(void *where);
88static void error(char *m);
89static void gzip_mark(void **);
90static void gzip_release(void **);
91
92int puts(const char *);
93
94extern int _text; /* Defined in vmlinux.lds.S */
95extern int _end;
96static unsigned long free_mem_ptr;
97static unsigned long free_mem_end_ptr;
98
99#define HEAP_SIZE 0x10000
100
101#include "../../../../lib/inflate.c"
102
103static void *malloc(int size)
104{
105 void *p;
106
107 if (size <0) error("Malloc error");
108 if (free_mem_ptr == 0) error("Memory error");
109
110 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
111
112 p = (void *)free_mem_ptr;
113 free_mem_ptr += size;
114
115 if (free_mem_ptr >= free_mem_end_ptr)
116 error("Out of memory");
117
118 return p;
119}
120
121static void free(void *where)
122{ /* Don't care */
123}
124
125static void gzip_mark(void **ptr)
126{
127 *ptr = (void *) free_mem_ptr;
128}
129
130static void gzip_release(void **ptr)
131{
132 free_mem_ptr = (long) *ptr;
133}
134
135#ifdef CONFIG_SH_STANDARD_BIOS
136size_t strlen(const char *s)
137{
138 int i = 0;
139
140 while (*s++)
141 i++;
142 return i;
143}
144
145int puts(const char *s)
146{
147 int len = strlen(s);
148 sh_bios_console_write(s, len);
149 return len;
150}
151#else
152int puts(const char *s)
153{
154 /* This should be updated to use the sh-sci routines */
155 return 0;
156}
157#endif
158
159void* memset(void* s, int c, size_t n)
160{
161 int i;
162 char *ss = (char*)s;
163
164 for (i=0;i<n;i++) ss[i] = c;
165 return s;
166}
167
168void* memcpy(void* __dest, __const void* __src,
169 size_t __n)
170{
171 int i;
172 char *d = (char *)__dest, *s = (char *)__src;
173
174 for (i=0;i<__n;i++) d[i] = s[i];
175 return __dest;
176}
177
178/* ===========================================================================
179 * Fill the input buffer. This is called only when the buffer is empty
180 * and at least one byte is really needed.
181 */
182static int fill_inbuf(void)
183{
184 if (insize != 0) {
185 error("ran out of input data");
186 }
187
188 inbuf = input_data;
189 insize = input_len;
190 inptr = 1;
191 return inbuf[0];
192}
193
194/* ===========================================================================
195 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
196 * (Used for the decompressed data only.)
197 */
198static void flush_window(void)
199{
200 ulg c = crc; /* temporary variable */
201 unsigned n;
202 uch *in, *out, ch;
203
204 in = window;
205 out = &output_data[output_ptr];
206 for (n = 0; n < outcnt; n++) {
207 ch = *out++ = *in++;
208 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
209 }
210 crc = c;
211 bytes_out += (ulg)outcnt;
212 output_ptr += (ulg)outcnt;
213 outcnt = 0;
214}
215
216static void error(char *x)
217{
218 puts("\n\n");
219 puts(x);
220 puts("\n\n -- System halted");
221
222 while(1); /* Halt */
223}
224
225#define STACK_SIZE (4096)
226long user_stack [STACK_SIZE];
227long* stack_start = &user_stack[STACK_SIZE];
228
229void decompress_kernel(void)
230{
231 output_data = 0;
232 output_ptr = (unsigned long)&_text+0x20001000;
233 free_mem_ptr = (unsigned long)&_end;
234 free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
235
236 makecrc();
237 puts("Uncompressing Linux... ");
238 gunzip();
239 puts("Ok, booting the kernel.\n");
240}
diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr
new file mode 100644
index 000000000000..1ed9d791f863
--- /dev/null
+++ b/arch/sh/boot/compressed/vmlinux.scr
@@ -0,0 +1,9 @@
1SECTIONS
2{
3 .data : {
4 input_len = .;
5 LONG(input_data_end - input_data) input_data = .;
6 *(.data)
7 input_data_end = .;
8 }
9}
diff --git a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig
new file mode 100644
index 000000000000..155d139884c3
--- /dev/null
+++ b/arch/sh/cchips/Kconfig
@@ -0,0 +1,96 @@
1menu "Companion Chips"
2
3config VOYAGERGX
4 bool "VoyagerGX chip support"
5 depends on SH_RTS7751R2D
6 help
7 Selecting this option will support Silicon Motion, Inc. SM501.
8 Designed to complement needs for the embedded industry, it
9 provides video and 2D capability. To reduce system cost a
10 wide variety of include I/O is supported, including analog RGB
11 and digital LCD Panel interface, 8-bit parallel interface, USB,
12 UART, IrDA, Zoom Video, AC97 or I2S, SSP, PWM, and I2C. There
13 are additional GPIO bits that can be used to interface to
14 external as well.
15
16# A board must have defined HD6446X_SERIES in order to see these
17config HD6446X_SERIES
18 bool "HD6446x support"
19 default n
20
21choice
22 prompt "HD6446x options"
23 depends on HD6446X_SERIES
24 default HD64461
25
26config HD64461
27 bool "Hitachi HD64461 companion chip support"
28 depends on CPU_SUBTYPE_SH7709
29 ---help---
30 The Hitachi HD64461 provides an interface for
31 the SH7709 CPU, supporting a LCD controller,
32 CRT color controller, IrDA up to 4 Mbps, and a
33 PCMCIA controller supporting 2 slots.
34
35 More information is available at
36 <http://semiconductor.hitachi.com/windowsce/superh/sld013.htm>.
37
38 Say Y if you want support for the HD64461.
39 Otherwise, say N.
40
41config HD64465
42 bool "Hitachi HD64465 companion chip support"
43 depends on CPU_SUBTYPE_SH7750
44 ---help---
45 The Hitachi HD64465 provides an interface for
46 the SH7750 CPU, supporting a LCD controller,
47 CRT color controller, IrDA, USB, PCMCIA,
48 keyboard controller, and a printer interface.
49
50 More information is available at
51 <http://global.hitachi.com/New/cnews/E/1998/981019B.html>.
52
53 Say Y if you want support for the HD64465.
54 Otherwise, say N.
55
56endchoice
57
58# These will also be split into the Kconfig's below
59config HD64461_IRQ
60 int "HD64461 IRQ"
61 depends on HD64461
62 default "36"
63 help
64 The default setting of the HD64461 IRQ is 36.
65
66 Do not change this unless you know what you are doing.
67
68config HD64461_ENABLER
69 bool "HD64461 PCMCIA enabler"
70 depends on HD64461
71 help
72 Say Y here if you want to enable PCMCIA support
73 via the HD64461 companion chip.
74 Otherwise, say N.
75
76
77config HD64465_IOBASE
78 hex "HD64465 start address"
79 depends on HD64465
80 default "0xb0000000"
81 help
82 The default setting of the HD64465 IO base address is 0xb0000000.
83
84 Do not change this unless you know what you are doing.
85
86config HD64465_IRQ
87 int "HD64465 IRQ"
88 depends on HD64465
89 default "5"
90 help
91 The default setting of the HD64465 IRQ is 5.
92
93 Do not change this unless you know what you are doing.
94
95endmenu
96
diff --git a/arch/sh/cchips/hd6446x/hd64461/Makefile b/arch/sh/cchips/hd6446x/hd64461/Makefile
new file mode 100644
index 000000000000..bff4b92e388c
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64461/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the HD64461
3#
4
5obj-y := setup.o io.o
6
diff --git a/arch/sh/cchips/hd6446x/hd64461/io.c b/arch/sh/cchips/hd6446x/hd64461/io.c
new file mode 100644
index 000000000000..4c062d6b7a97
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64461/io.c
@@ -0,0 +1,157 @@
1/*
2 * $Id: io.c,v 1.6 2004/03/16 00:07:50 lethal Exp $
3 * Copyright (C) 2000 YAEGASHI Takeshi
4 * Typical I/O routines for HD64461 system.
5 */
6
7#include <linux/config.h>
8#include <asm/io.h>
9#include <asm/hd64461/hd64461.h>
10
11#define MEM_BASE (CONFIG_HD64461_IOBASE - HD64461_STBCR)
12
13static __inline__ unsigned long PORT2ADDR(unsigned long port)
14{
15 /* 16550A: HD64461 internal */
16 if (0x3f8<=port && port<=0x3ff)
17 return CONFIG_HD64461_IOBASE + 0x8000 + ((port-0x3f8)<<1);
18 if (0x2f8<=port && port<=0x2ff)
19 return CONFIG_HD64461_IOBASE + 0x7000 + ((port-0x2f8)<<1);
20
21#ifdef CONFIG_HD64461_ENABLER
22 /* NE2000: HD64461 PCMCIA channel 0 (I/O) */
23 if (0x300<=port && port<=0x31f)
24 return 0xba000000 + port;
25
26 /* ide0: HD64461 PCMCIA channel 1 (memory) */
27 /* On HP690, CF in slot 1 is configured as a memory card
28 device. See CF+ and CompactFlash Specification for the
29 detail of CF's memory mapped addressing. */
30 if (0x1f0<=port && port<=0x1f7) return 0xb5000000 + port;
31 if (port == 0x3f6) return 0xb50001fe;
32 if (port == 0x3f7) return 0xb50001ff;
33
34 /* ide1 */
35 if (0x170<=port && port<=0x177) return 0xba000000 + port;
36 if (port == 0x376) return 0xba000376;
37 if (port == 0x377) return 0xba000377;
38#endif
39
40 /* ??? */
41 if (port < 0xf000) return 0xa0000000 + port;
42 /* PCMCIA channel 0, I/O (0xba000000) */
43 if (port < 0x10000) return 0xba000000 + port - 0xf000;
44
45 /* HD64461 internal devices (0xb0000000) */
46 if (port < 0x20000) return CONFIG_HD64461_IOBASE + port - 0x10000;
47
48 /* PCMCIA channel 0, I/O (0xba000000) */
49 if (port < 0x30000) return 0xba000000 + port - 0x20000;
50
51 /* PCMCIA channel 1, memory (0xb5000000) */
52 if (port < 0x40000) return 0xb5000000 + port - 0x30000;
53
54 /* Whole physical address space (0xa0000000) */
55 return 0xa0000000 + (port & 0x1fffffff);
56}
57
58static inline void delay(void)
59{
60 ctrl_inw(0xa0000000);
61}
62
63unsigned char hd64461_inb(unsigned long port)
64{
65 return *(volatile unsigned char*)PORT2ADDR(port);
66}
67
68unsigned char hd64461_inb_p(unsigned long port)
69{
70 unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
71 delay();
72 return v;
73}
74
75unsigned short hd64461_inw(unsigned long port)
76{
77 return *(volatile unsigned short*)PORT2ADDR(port);
78}
79
80unsigned int hd64461_inl(unsigned long port)
81{
82 return *(volatile unsigned long*)PORT2ADDR(port);
83}
84
85void hd64461_outb(unsigned char b, unsigned long port)
86{
87 *(volatile unsigned char*)PORT2ADDR(port) = b;
88}
89
90void hd64461_outb_p(unsigned char b, unsigned long port)
91{
92 *(volatile unsigned char*)PORT2ADDR(port) = b;
93 delay();
94}
95
96void hd64461_outw(unsigned short b, unsigned long port)
97{
98 *(volatile unsigned short*)PORT2ADDR(port) = b;
99}
100
101void hd64461_outl(unsigned int b, unsigned long port)
102{
103 *(volatile unsigned long*)PORT2ADDR(port) = b;
104}
105
106void hd64461_insb(unsigned long port, void *buffer, unsigned long count)
107{
108 volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port);
109 unsigned char *buf=buffer;
110 while(count--) *buf++=*addr;
111}
112
113void hd64461_insw(unsigned long port, void *buffer, unsigned long count)
114{
115 volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port);
116 unsigned short *buf=buffer;
117 while(count--) *buf++=*addr;
118}
119
120void hd64461_insl(unsigned long port, void *buffer, unsigned long count)
121{
122 volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port);
123 unsigned long *buf=buffer;
124 while(count--) *buf++=*addr;
125}
126
127void hd64461_outsb(unsigned long port, const void *buffer, unsigned long count)
128{
129 volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port);
130 const unsigned char *buf=buffer;
131 while(count--) *addr=*buf++;
132}
133
134void hd64461_outsw(unsigned long port, const void *buffer, unsigned long count)
135{
136 volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port);
137 const unsigned short *buf=buffer;
138 while(count--) *addr=*buf++;
139}
140
141void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count)
142{
143 volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port);
144 const unsigned long *buf=buffer;
145 while(count--) *addr=*buf++;
146}
147
148unsigned short hd64461_readw(unsigned long addr)
149{
150 return *(volatile unsigned short*)(MEM_BASE+addr);
151}
152
153void hd64461_writew(unsigned short b, unsigned long addr)
154{
155 *(volatile unsigned short*)(MEM_BASE+addr) = b;
156}
157
diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c
new file mode 100644
index 000000000000..f014b9bf6922
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64461/setup.c
@@ -0,0 +1,171 @@
1/*
2 * $Id: setup.c,v 1.5 2004/03/16 00:07:50 lethal Exp $
3 * Copyright (C) 2000 YAEGASHI Takeshi
4 * Hitachi HD64461 companion chip support
5 */
6
7#include <linux/config.h>
8#include <linux/sched.h>
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/param.h>
12#include <linux/interrupt.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15
16#include <asm/io.h>
17#include <asm/irq.h>
18
19#include <asm/hd64461/hd64461.h>
20
21static void disable_hd64461_irq(unsigned int irq)
22{
23 unsigned long flags;
24 unsigned short nimr;
25 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
26
27 local_irq_save(flags);
28 nimr = inw(HD64461_NIMR);
29 nimr |= mask;
30 outw(nimr, HD64461_NIMR);
31 local_irq_restore(flags);
32}
33
34static void enable_hd64461_irq(unsigned int irq)
35{
36 unsigned long flags;
37 unsigned short nimr;
38 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
39
40 local_irq_save(flags);
41 nimr = inw(HD64461_NIMR);
42 nimr &= ~mask;
43 outw(nimr, HD64461_NIMR);
44 local_irq_restore(flags);
45}
46
47static void mask_and_ack_hd64461(unsigned int irq)
48{
49 disable_hd64461_irq(irq);
50#ifdef CONFIG_HD64461_ENABLER
51 if (irq == HD64461_IRQBASE + 13)
52 outb(0x00, HD64461_PCC1CSCR);
53#endif
54}
55
56static void end_hd64461_irq(unsigned int irq)
57{
58 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
59 enable_hd64461_irq(irq);
60}
61
62static unsigned int startup_hd64461_irq(unsigned int irq)
63{
64 enable_hd64461_irq(irq);
65 return 0;
66}
67
68static void shutdown_hd64461_irq(unsigned int irq)
69{
70 disable_hd64461_irq(irq);
71}
72
73static struct hw_interrupt_type hd64461_irq_type = {
74 .typename = "HD64461-IRQ",
75 .startup = startup_hd64461_irq,
76 .shutdown = shutdown_hd64461_irq,
77 .enable = enable_hd64461_irq,
78 .disable = disable_hd64461_irq,
79 .ack = mask_and_ack_hd64461,
80 .end = end_hd64461_irq,
81};
82
83static irqreturn_t hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs)
84{
85 printk(KERN_INFO
86 "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
87 inw(HD64461_NIRR), inw(HD64461_NIMR));
88
89 return IRQ_NONE;
90}
91
92static struct {
93 int (*func) (int, void *);
94 void *dev;
95} hd64461_demux[HD64461_IRQ_NUM];
96
97void hd64461_register_irq_demux(int irq,
98 int (*demux) (int irq, void *dev), void *dev)
99{
100 hd64461_demux[irq - HD64461_IRQBASE].func = demux;
101 hd64461_demux[irq - HD64461_IRQBASE].dev = dev;
102}
103
104EXPORT_SYMBOL(hd64461_register_irq_demux);
105
106void hd64461_unregister_irq_demux(int irq)
107{
108 hd64461_demux[irq - HD64461_IRQBASE].func = 0;
109}
110
111EXPORT_SYMBOL(hd64461_unregister_irq_demux);
112
113int hd64461_irq_demux(int irq)
114{
115 if (irq == CONFIG_HD64461_IRQ) {
116 unsigned short bit;
117 unsigned short nirr = inw(HD64461_NIRR);
118 unsigned short nimr = inw(HD64461_NIMR);
119 int i;
120
121 nirr &= ~nimr;
122 for (bit = 1, i = 0; i < 16; bit <<= 1, i++)
123 if (nirr & bit)
124 break;
125 if (i == 16)
126 irq = CONFIG_HD64461_IRQ;
127 else {
128 irq = HD64461_IRQBASE + i;
129 if (hd64461_demux[i].func != 0) {
130 irq = hd64461_demux[i].func(irq, hd64461_demux[i].dev);
131 }
132 }
133 }
134 return __irq_demux(irq);
135}
136
137static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64461", NULL, NULL };
138
139int __init setup_hd64461(void)
140{
141 int i;
142
143 if (!MACH_HD64461)
144 return 0;
145
146 printk(KERN_INFO
147 "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n",
148 CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE,
149 HD64461_IRQBASE + 15);
150
151#if defined(CONFIG_CPU_SUBTYPE_SH7709) /* Should be at processor specific part.. */
152 outw(0x2240, INTC_ICR1);
153#endif
154 outw(0xffff, HD64461_NIMR);
155
156 for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
157 irq_desc[i].handler = &hd64461_irq_type;
158 }
159
160 setup_irq(CONFIG_HD64461_IRQ, &irq0);
161
162#ifdef CONFIG_HD64461_ENABLER
163 printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
164 outb(0x4c, HD64461_PCC1CSCIER);
165 outb(0x00, HD64461_PCC1CSCR);
166#endif
167
168 return 0;
169}
170
171module_init(setup_hd64461);
diff --git a/arch/sh/cchips/hd6446x/hd64465/Makefile b/arch/sh/cchips/hd6446x/hd64465/Makefile
new file mode 100644
index 000000000000..f66edcb52c5b
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64465/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the HD64465
3#
4
5obj-y := setup.o io.o gpio.o
6
diff --git a/arch/sh/cchips/hd6446x/hd64465/gpio.c b/arch/sh/cchips/hd6446x/hd64465/gpio.c
new file mode 100644
index 000000000000..9785fdef868e
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64465/gpio.c
@@ -0,0 +1,196 @@
1/*
2 * $Id: gpio.c,v 1.4 2003/05/19 22:24:18 lethal Exp $
3 * by Greg Banks <gbanks@pocketpenguins.com>
4 * (c) 2000 PocketPenguins Inc
5 *
6 * GPIO pin support for HD64465 companion chip.
7 */
8
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/sched.h>
13#include <linux/ioport.h>
14#include <asm/io.h>
15#include <asm/hd64465/gpio.h>
16
17#define _PORTOF(portpin) (((portpin)>>3)&0x7)
18#define _PINOF(portpin) ((portpin)&0x7)
19
20/* Register addresses parametrised on port */
21#define GPIO_CR(port) (HD64465_REG_GPACR+((port)<<1))
22#define GPIO_DR(port) (HD64465_REG_GPADR+((port)<<1))
23#define GPIO_ICR(port) (HD64465_REG_GPAICR+((port)<<1))
24#define GPIO_ISR(port) (HD64465_REG_GPAISR+((port)<<1))
25
26#define GPIO_NPORTS 5
27
28#define MODNAME "hd64465_gpio"
29
30EXPORT_SYMBOL(hd64465_gpio_configure);
31EXPORT_SYMBOL(hd64465_gpio_get_pin);
32EXPORT_SYMBOL(hd64465_gpio_get_port);
33EXPORT_SYMBOL(hd64465_gpio_register_irq);
34EXPORT_SYMBOL(hd64465_gpio_set_pin);
35EXPORT_SYMBOL(hd64465_gpio_set_port);
36EXPORT_SYMBOL(hd64465_gpio_unregister_irq);
37
38/* TODO: each port should be protected with a spinlock */
39
40
41void hd64465_gpio_configure(int portpin, int direction)
42{
43 unsigned short cr;
44 unsigned int shift = (_PINOF(portpin)<<1);
45
46 cr = inw(GPIO_CR(_PORTOF(portpin)));
47 cr &= ~(3<<shift);
48 cr |= direction<<shift;
49 outw(cr, GPIO_CR(_PORTOF(portpin)));
50}
51
52void hd64465_gpio_set_pin(int portpin, unsigned int value)
53{
54 unsigned short d;
55 unsigned short mask = 1<<(_PINOF(portpin));
56
57 d = inw(GPIO_DR(_PORTOF(portpin)));
58 if (value)
59 d |= mask;
60 else
61 d &= ~mask;
62 outw(d, GPIO_DR(_PORTOF(portpin)));
63}
64
65unsigned int hd64465_gpio_get_pin(int portpin)
66{
67 return inw(GPIO_DR(_PORTOF(portpin))) & (1<<(_PINOF(portpin)));
68}
69
70/* TODO: for cleaner atomicity semantics, add a mask to this routine */
71
72void hd64465_gpio_set_port(int port, unsigned int value)
73{
74 outw(value, GPIO_DR(port));
75}
76
77unsigned int hd64465_gpio_get_port(int port)
78{
79 return inw(GPIO_DR(port));
80}
81
82
83static struct {
84 void (*func)(int portpin, void *dev);
85 void *dev;
86} handlers[GPIO_NPORTS * 8];
87
88static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev, struct pt_regs *regs)
89{
90 unsigned short port, pin, isr, mask, portpin;
91
92 for (port=0 ; port<GPIO_NPORTS ; port++) {
93 isr = inw(GPIO_ISR(port));
94
95 for (pin=0 ; pin<8 ; pin++) {
96 mask = 1<<pin;
97 if (isr & mask) {
98 portpin = (port<<3)|pin;
99 if (handlers[portpin].func != 0)
100 handlers[portpin].func(portpin, handlers[portpin].dev);
101 else
102 printk(KERN_NOTICE "unexpected GPIO interrupt, pin %c%d\n",
103 port+'A', (int)pin);
104 }
105 }
106
107 /* Write 1s back to ISR to clear it? That's what the manual says.. */
108 outw(isr, GPIO_ISR(port));
109 }
110
111 return IRQ_HANDLED;
112}
113
114void hd64465_gpio_register_irq(int portpin, int mode,
115 void (*handler)(int portpin, void *dev), void *dev)
116{
117 unsigned long flags;
118 unsigned short icr, mask;
119
120 if (handler == 0)
121 return;
122
123 local_irq_save(flags);
124
125 handlers[portpin].func = handler;
126 handlers[portpin].dev = dev;
127
128 /*
129 * Configure Interrupt Control Register
130 */
131 icr = inw(GPIO_ICR(_PORTOF(portpin)));
132 mask = (1<<_PINOF(portpin));
133
134 /* unmask interrupt */
135 icr &= ~mask;
136
137 /* set TS bit */
138 mask <<= 8;
139 icr &= ~mask;
140 if (mode == HD64465_GPIO_RISING)
141 icr |= mask;
142
143 outw(icr, GPIO_ICR(_PORTOF(portpin)));
144
145 local_irq_restore(flags);
146}
147
148void hd64465_gpio_unregister_irq(int portpin)
149{
150 unsigned long flags;
151 unsigned short icr;
152
153 local_irq_save(flags);
154
155 /*
156 * Configure Interrupt Control Register
157 */
158 icr = inw(GPIO_ICR(_PORTOF(portpin)));
159 icr |= (1<<_PINOF(portpin)); /* mask interrupt */
160 outw(icr, GPIO_ICR(_PORTOF(portpin)));
161
162 handlers[portpin].func = 0;
163 handlers[portpin].dev = 0;
164
165 local_irq_restore(flags);
166}
167
168static int __init hd64465_gpio_init(void)
169{
170 if (!request_region(HD64465_REG_GPACR, 0x1000, MODNAME))
171 return -EBUSY;
172 if (request_irq(HD64465_IRQ_GPIO, hd64465_gpio_interrupt,
173 SA_INTERRUPT, MODNAME, 0))
174 goto out_irqfailed;
175
176 printk("HD64465 GPIO layer on irq %d\n", HD64465_IRQ_GPIO);
177
178 return 0;
179
180out_irqfailed:
181 release_region(HD64465_REG_GPACR, 0x1000);
182
183 return -EINVAL;
184}
185
186static void __exit hd64465_gpio_exit(void)
187{
188 release_region(HD64465_REG_GPACR, 0x1000);
189 free_irq(HD64465_IRQ_GPIO, 0);
190}
191
192module_init(hd64465_gpio_init);
193module_exit(hd64465_gpio_exit);
194
195MODULE_LICENSE("GPL");
196
diff --git a/arch/sh/cchips/hd6446x/hd64465/io.c b/arch/sh/cchips/hd6446x/hd64465/io.c
new file mode 100644
index 000000000000..99ac709c550e
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64465/io.c
@@ -0,0 +1,216 @@
1/*
2 * $Id: io.c,v 1.4 2003/08/03 03:05:10 lethal Exp $
3 * by Greg Banks <gbanks@pocketpenguins.com>
4 * (c) 2000 PocketPenguins Inc
5 *
6 * Derived from io_hd64461.c, which bore the message:
7 * Copyright (C) 2000 YAEGASHI Takeshi
8 *
9 * Typical I/O routines for HD64465 system.
10 */
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <asm/io.h>
16#include <asm/hd64465/hd64465.h>
17
18
19#define HD64465_DEBUG 0
20
21#if HD64465_DEBUG
22#define DPRINTK(args...) printk(args)
23#define DIPRINTK(n, args...) if (hd64465_io_debug>(n)) printk(args)
24#else
25#define DPRINTK(args...)
26#define DIPRINTK(n, args...)
27#endif
28
29
30
31/* This is a hack suitable only for debugging IO port problems */
32int hd64465_io_debug;
33EXPORT_SYMBOL(hd64465_io_debug);
34
35/* Low iomap maps port 0-1K to addresses in 8byte chunks */
36#define HD64465_IOMAP_LO_THRESH 0x400
37#define HD64465_IOMAP_LO_SHIFT 3
38#define HD64465_IOMAP_LO_MASK ((1<<HD64465_IOMAP_LO_SHIFT)-1)
39#define HD64465_IOMAP_LO_NMAP (HD64465_IOMAP_LO_THRESH>>HD64465_IOMAP_LO_SHIFT)
40static unsigned long hd64465_iomap_lo[HD64465_IOMAP_LO_NMAP];
41static unsigned char hd64465_iomap_lo_shift[HD64465_IOMAP_LO_NMAP];
42
43/* High iomap maps port 1K-64K to addresses in 1K chunks */
44#define HD64465_IOMAP_HI_THRESH 0x10000
45#define HD64465_IOMAP_HI_SHIFT 10
46#define HD64465_IOMAP_HI_MASK ((1<<HD64465_IOMAP_HI_SHIFT)-1)
47#define HD64465_IOMAP_HI_NMAP (HD64465_IOMAP_HI_THRESH>>HD64465_IOMAP_HI_SHIFT)
48static unsigned long hd64465_iomap_hi[HD64465_IOMAP_HI_NMAP];
49static unsigned char hd64465_iomap_hi_shift[HD64465_IOMAP_HI_NMAP];
50
51#ifndef MAX
52#define MAX(a,b) ((a)>(b)?(a):(b))
53#endif
54
55#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
56
57void hd64465_port_map(unsigned short baseport, unsigned int nports,
58 unsigned long addr, unsigned char shift)
59{
60 unsigned int port, endport = baseport + nports;
61
62 DPRINTK("hd64465_port_map(base=0x%04hx, n=0x%04hx, addr=0x%08lx,endport=0x%04x)\n",
63 baseport, nports, addr,endport);
64
65 for (port = baseport ;
66 port < endport && port < HD64465_IOMAP_LO_THRESH ;
67 port += (1<<HD64465_IOMAP_LO_SHIFT)) {
68 DPRINTK(" maplo[0x%x] = 0x%08lx\n", port, addr);
69 hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = addr;
70 hd64465_iomap_lo_shift[port>>HD64465_IOMAP_LO_SHIFT] = shift;
71 addr += (1<<(HD64465_IOMAP_LO_SHIFT));
72 }
73
74 for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
75 port < endport && port < HD64465_IOMAP_HI_THRESH ;
76 port += (1<<HD64465_IOMAP_HI_SHIFT)) {
77 DPRINTK(" maphi[0x%x] = 0x%08lx\n", port, addr);
78 hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = addr;
79 hd64465_iomap_hi_shift[port>>HD64465_IOMAP_HI_SHIFT] = shift;
80 addr += (1<<(HD64465_IOMAP_HI_SHIFT));
81 }
82}
83EXPORT_SYMBOL(hd64465_port_map);
84
85void hd64465_port_unmap(unsigned short baseport, unsigned int nports)
86{
87 unsigned int port, endport = baseport + nports;
88
89 DPRINTK("hd64465_port_unmap(base=0x%04hx, n=0x%04hx)\n",
90 baseport, nports);
91
92 for (port = baseport ;
93 port < endport && port < HD64465_IOMAP_LO_THRESH ;
94 port += (1<<HD64465_IOMAP_LO_SHIFT)) {
95 hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = 0;
96 }
97
98 for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
99 port < endport && port < HD64465_IOMAP_HI_THRESH ;
100 port += (1<<HD64465_IOMAP_HI_SHIFT)) {
101 hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = 0;
102 }
103}
104EXPORT_SYMBOL(hd64465_port_unmap);
105
106unsigned long hd64465_isa_port2addr(unsigned long port)
107{
108 unsigned long addr = 0;
109 unsigned char shift;
110
111 /* handle remapping of low IO ports */
112 if (port < HD64465_IOMAP_LO_THRESH) {
113 addr = hd64465_iomap_lo[port >> HD64465_IOMAP_LO_SHIFT];
114 shift = hd64465_iomap_lo_shift[port >> HD64465_IOMAP_LO_SHIFT];
115 if (addr != 0)
116 addr += (port & HD64465_IOMAP_LO_MASK) << shift;
117 else
118 printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lx\n", port);
119 } else if (port < HD64465_IOMAP_HI_THRESH) {
120 addr = hd64465_iomap_hi[port >> HD64465_IOMAP_HI_SHIFT];
121 shift = hd64465_iomap_hi_shift[port >> HD64465_IOMAP_HI_SHIFT];
122 if (addr != 0)
123 addr += (port & HD64465_IOMAP_HI_MASK) << shift;
124 else
125 printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lx\n", port);
126 }
127
128 /* HD64465 internal devices (0xb0000000) */
129 else if (port < 0x20000)
130 addr = CONFIG_HD64465_IOBASE + port - 0x10000;
131
132 /* Whole physical address space (0xa0000000) */
133 else
134 addr = P2SEGADDR(port);
135
136 DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lx\n", port, addr);
137
138 return addr;
139}
140
141static inline void delay(void)
142{
143 ctrl_inw(0xa0000000);
144}
145
146unsigned char hd64465_inb(unsigned long port)
147{
148 unsigned long addr = PORT2ADDR(port);
149 unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
150
151 DIPRINTK(0, "inb(%08lx) = %02x\n", addr, (unsigned)b);
152 return b;
153}
154
155unsigned char hd64465_inb_p(unsigned long port)
156{
157 unsigned long v;
158 unsigned long addr = PORT2ADDR(port);
159
160 v = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
161 delay();
162 DIPRINTK(0, "inb_p(%08lx) = %02x\n", addr, (unsigned)v);
163 return v;
164}
165
166unsigned short hd64465_inw(unsigned long port)
167{
168 unsigned long addr = PORT2ADDR(port);
169 unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr);
170 DIPRINTK(0, "inw(%08lx) = %04lx\n", addr, b);
171 return b;
172}
173
174unsigned int hd64465_inl(unsigned long port)
175{
176 unsigned long addr = PORT2ADDR(port);
177 unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr);
178 DIPRINTK(0, "inl(%08lx) = %08x\n", addr, b);
179 return b;
180}
181
182void hd64465_outb(unsigned char b, unsigned long port)
183{
184 unsigned long addr = PORT2ADDR(port);
185
186 DIPRINTK(0, "outb(%02x, %08lx)\n", (unsigned)b, addr);
187 if (addr != 0)
188 *(volatile unsigned char*)addr = b;
189}
190
191void hd64465_outb_p(unsigned char b, unsigned long port)
192{
193 unsigned long addr = PORT2ADDR(port);
194
195 DIPRINTK(0, "outb_p(%02x, %08lx)\n", (unsigned)b, addr);
196 if (addr != 0)
197 *(volatile unsigned char*)addr = b;
198 delay();
199}
200
201void hd64465_outw(unsigned short b, unsigned long port)
202{
203 unsigned long addr = PORT2ADDR(port);
204 DIPRINTK(0, "outw(%04x, %08lx)\n", (unsigned)b, addr);
205 if (addr != 0)
206 *(volatile unsigned short*)addr = b;
207}
208
209void hd64465_outl(unsigned int b, unsigned long port)
210{
211 unsigned long addr = PORT2ADDR(port);
212 DIPRINTK(0, "outl(%08x, %08lx)\n", b, addr);
213 if (addr != 0)
214 *(volatile unsigned long*)addr = b;
215}
216
diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c
new file mode 100644
index 000000000000..68e4c4e4283d
--- /dev/null
+++ b/arch/sh/cchips/hd6446x/hd64465/setup.c
@@ -0,0 +1,202 @@
1/*
2 * $Id: setup.c,v 1.4 2003/08/03 03:05:10 lethal Exp $
3 *
4 * Setup and IRQ handling code for the HD64465 companion chip.
5 * by Greg Banks <gbanks@pocketpenguins.com>
6 * Copyright (c) 2000 PocketPenguins Inc
7 *
8 * Derived from setup_hd64461.c which bore the message:
9 * Copyright (C) 2000 YAEGASHI Takeshi
10 */
11
12#include <linux/config.h>
13#include <linux/sched.h>
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/param.h>
17#include <linux/ioport.h>
18#include <linux/interrupt.h>
19#include <linux/init.h>
20#include <linux/irq.h>
21
22#include <asm/io.h>
23#include <asm/irq.h>
24
25#include <asm/hd64465/hd64465.h>
26
27static void disable_hd64465_irq(unsigned int irq)
28{
29 unsigned long flags;
30 unsigned short nimr;
31 unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
32
33 pr_debug("disable_hd64465_irq(%d): mask=%x\n", irq, mask);
34 local_irq_save(flags);
35 nimr = inw(HD64465_REG_NIMR);
36 nimr |= mask;
37 outw(nimr, HD64465_REG_NIMR);
38 local_irq_restore(flags);
39}
40
41
42static void enable_hd64465_irq(unsigned int irq)
43{
44 unsigned long flags;
45 unsigned short nimr;
46 unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
47
48 pr_debug("enable_hd64465_irq(%d): mask=%x\n", irq, mask);
49 local_irq_save(flags);
50 nimr = inw(HD64465_REG_NIMR);
51 nimr &= ~mask;
52 outw(nimr, HD64465_REG_NIMR);
53 local_irq_restore(flags);
54}
55
56
57static void mask_and_ack_hd64465(unsigned int irq)
58{
59 disable_hd64465_irq(irq);
60}
61
62
63static void end_hd64465_irq(unsigned int irq)
64{
65 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
66 enable_hd64465_irq(irq);
67}
68
69
70static unsigned int startup_hd64465_irq(unsigned int irq)
71{
72 enable_hd64465_irq(irq);
73 return 0;
74}
75
76
77static void shutdown_hd64465_irq(unsigned int irq)
78{
79 disable_hd64465_irq(irq);
80}
81
82
83static struct hw_interrupt_type hd64465_irq_type = {
84 .typename = "HD64465-IRQ",
85 .startup = startup_hd64465_irq,
86 .shutdown = shutdown_hd64465_irq,
87 .enable = enable_hd64465_irq,
88 .disable = disable_hd64465_irq,
89 .ack = mask_and_ack_hd64465,
90 .end = end_hd64465_irq,
91};
92
93
94static irqreturn_t hd64465_interrupt(int irq, void *dev_id, struct pt_regs *regs)
95{
96 printk(KERN_INFO
97 "HD64465: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
98 inw(HD64465_REG_NIRR), inw(HD64465_REG_NIMR));
99
100 return IRQ_NONE;
101}
102
103
104/*====================================================*/
105
106/*
107 * Support for a secondary IRQ demux step. This is necessary
108 * because the HD64465 presents a very thin interface to the
109 * PCMCIA bus; a lot of features (such as remapping interrupts)
110 * normally done in hardware by other PCMCIA host bridges is
111 * instead done in software.
112 */
113static struct
114{
115 int (*func)(int, void *);
116 void *dev;
117} hd64465_demux[HD64465_IRQ_NUM];
118
119void hd64465_register_irq_demux(int irq,
120 int (*demux)(int irq, void *dev), void *dev)
121{
122 hd64465_demux[irq - HD64465_IRQ_BASE].func = demux;
123 hd64465_demux[irq - HD64465_IRQ_BASE].dev = dev;
124}
125EXPORT_SYMBOL(hd64465_register_irq_demux);
126
127void hd64465_unregister_irq_demux(int irq)
128{
129 hd64465_demux[irq - HD64465_IRQ_BASE].func = 0;
130}
131EXPORT_SYMBOL(hd64465_unregister_irq_demux);
132
133
134
135int hd64465_irq_demux(int irq)
136{
137 if (irq == CONFIG_HD64465_IRQ) {
138 unsigned short i, bit;
139 unsigned short nirr = inw(HD64465_REG_NIRR);
140 unsigned short nimr = inw(HD64465_REG_NIMR);
141
142 pr_debug("hd64465_irq_demux, nirr=%04x, nimr=%04x\n", nirr, nimr);
143 nirr &= ~nimr;
144 for (bit = 1, i = 0 ; i < HD64465_IRQ_NUM ; bit <<= 1, i++)
145 if (nirr & bit)
146 break;
147
148 if (i < HD64465_IRQ_NUM) {
149 irq = HD64465_IRQ_BASE + i;
150 if (hd64465_demux[i].func != 0)
151 irq = hd64465_demux[i].func(irq, hd64465_demux[i].dev);
152 }
153 }
154 return irq;
155}
156
157static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64465", NULL, NULL};
158
159
160static int __init setup_hd64465(void)
161{
162 int i;
163 unsigned short rev;
164 unsigned short smscr;
165
166 if (!MACH_HD64465)
167 return 0;
168
169 printk(KERN_INFO "HD64465 configured at 0x%x on irq %d(mapped into %d to %d)\n",
170 CONFIG_HD64465_IOBASE,
171 CONFIG_HD64465_IRQ,
172 HD64465_IRQ_BASE,
173 HD64465_IRQ_BASE+HD64465_IRQ_NUM-1);
174
175 if (inw(HD64465_REG_SDID) != HD64465_SDID) {
176 printk(KERN_ERR "HD64465 device ID not found, check base address\n");
177 }
178
179 rev = inw(HD64465_REG_SRR);
180 printk(KERN_INFO "HD64465 hardware revision %d.%d\n", (rev >> 8) & 0xff, rev & 0xff);
181
182 outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */
183
184 for (i = 0; i < HD64465_IRQ_NUM ; i++) {
185 irq_desc[HD64465_IRQ_BASE + i].handler = &hd64465_irq_type;
186 }
187
188 setup_irq(CONFIG_HD64465_IRQ, &irq0);
189
190#ifdef CONFIG_SERIAL
191 /* wake up the UART from STANDBY at this point */
192 smscr = inw(HD64465_REG_SMSCR);
193 outw(smscr & (~HD64465_SMSCR_UARTST), HD64465_REG_SMSCR);
194
195 /* remap IO ports for first ISA serial port to HD64465 UART */
196 hd64465_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
197#endif
198
199 return 0;
200}
201
202module_init(setup_hd64465);
diff --git a/arch/sh/cchips/voyagergx/Makefile b/arch/sh/cchips/voyagergx/Makefile
new file mode 100644
index 000000000000..085de72fd327
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for VoyagerGX
3#
4
5obj-y := irq.o setup.o
6
7obj-$(CONFIG_USB_OHCI_HCD) += consistent.o
8
diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c
new file mode 100644
index 000000000000..5b92585a38d2
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/consistent.c
@@ -0,0 +1,126 @@
1/*
2 * arch/sh/cchips/voyagergx/consistent.c
3 *
4 * Copyright (C) 2004 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/mm.h>
11#include <linux/dma-mapping.h>
12#include <linux/slab.h>
13#include <linux/list.h>
14#include <linux/types.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <asm/io.h>
18#include <asm/bus-sh.h>
19
20struct voya_alloc_entry {
21 struct list_head list;
22 unsigned long ofs;
23 unsigned long len;
24};
25
26static DEFINE_SPINLOCK(voya_list_lock);
27static LIST_HEAD(voya_alloc_list);
28
29#define OHCI_SRAM_START 0xb0000000
30#define OHCI_HCCA_SIZE 0x100
31#define OHCI_SRAM_SIZE 0x10000
32
33void *voyagergx_consistent_alloc(struct device *dev, size_t size,
34 dma_addr_t *handle, int flag)
35{
36 struct list_head *list = &voya_alloc_list;
37 struct voya_alloc_entry *entry;
38 struct sh_dev *shdev = to_sh_dev(dev);
39 unsigned long start, end;
40 unsigned long flags;
41
42 /*
43 * The SM501 contains an integrated 8051 with its own SRAM.
44 * Devices within the cchip can all hook into the 8051 SRAM.
45 * We presently use this for the OHCI.
46 *
47 * Everything else goes through consistent_alloc().
48 */
49 if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
50 (dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
51 shdev->dev_id != SH_DEV_ID_USB_OHCI))
52 return NULL;
53
54 start = OHCI_SRAM_START + OHCI_HCCA_SIZE;
55
56 entry = kmalloc(sizeof(struct voya_alloc_entry), GFP_ATOMIC);
57 if (!entry)
58 return ERR_PTR(-ENOMEM);
59
60 entry->len = (size + 15) & ~15;
61
62 /*
63 * The basis for this allocator is dwmw2's malloc.. the
64 * Matrox allocator :-)
65 */
66 spin_lock_irqsave(&voya_list_lock, flags);
67 list_for_each(list, &voya_alloc_list) {
68 struct voya_alloc_entry *p;
69
70 p = list_entry(list, struct voya_alloc_entry, list);
71
72 if (p->ofs - start >= size)
73 goto out;
74
75 start = p->ofs + p->len;
76 }
77
78 end = start + (OHCI_SRAM_SIZE - OHCI_HCCA_SIZE);
79 list = &voya_alloc_list;
80
81 if (end - start >= size) {
82out:
83 entry->ofs = start;
84 list_add_tail(&entry->list, list);
85 spin_unlock_irqrestore(&voya_list_lock, flags);
86
87 *handle = start;
88 return (void *)start;
89 }
90
91 kfree(entry);
92 spin_unlock_irqrestore(&voya_list_lock, flags);
93
94 return ERR_PTR(-EINVAL);
95}
96
97int voyagergx_consistent_free(struct device *dev, size_t size,
98 void *vaddr, dma_addr_t handle)
99{
100 struct voya_alloc_entry *entry;
101 struct sh_dev *shdev = to_sh_dev(dev);
102 unsigned long flags;
103
104 if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
105 (dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
106 shdev->dev_id != SH_DEV_ID_USB_OHCI))
107 return -EINVAL;
108
109 spin_lock_irqsave(&voya_list_lock, flags);
110 list_for_each_entry(entry, &voya_alloc_list, list) {
111 if (entry->ofs != handle)
112 continue;
113
114 list_del(&entry->list);
115 kfree(entry);
116
117 break;
118 }
119 spin_unlock_irqrestore(&voya_list_lock, flags);
120
121 return 0;
122}
123
124EXPORT_SYMBOL(voyagergx_consistent_alloc);
125EXPORT_SYMBOL(voyagergx_consistent_free);
126
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
new file mode 100644
index 000000000000..3079234cb65b
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -0,0 +1,194 @@
1/* -------------------------------------------------------------------- */
2/* setup_voyagergx.c: */
3/* -------------------------------------------------------------------- */
4/* This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 Copyright 2003 (c) Lineo uSolutions,Inc.
19*/
20/* -------------------------------------------------------------------- */
21
22#undef DEBUG
23
24#include <linux/config.h>
25#include <linux/sched.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/param.h>
29#include <linux/ioport.h>
30#include <linux/interrupt.h>
31#include <linux/init.h>
32#include <linux/irq.h>
33
34#include <asm/io.h>
35#include <asm/irq.h>
36#include <asm/rts7751r2d/rts7751r2d.h>
37#include <asm/rts7751r2d/voyagergx_reg.h>
38
39static void disable_voyagergx_irq(unsigned int irq)
40{
41 unsigned long flags, val;
42 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
43
44 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
45 local_irq_save(flags);
46 val = inl(VOYAGER_INT_MASK);
47 val &= ~mask;
48 outl(val, VOYAGER_INT_MASK);
49 local_irq_restore(flags);
50}
51
52
53static void enable_voyagergx_irq(unsigned int irq)
54{
55 unsigned long flags, val;
56 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
57
58 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
59 local_irq_save(flags);
60 val = inl(VOYAGER_INT_MASK);
61 val |= mask;
62 outl(val, VOYAGER_INT_MASK);
63 local_irq_restore(flags);
64}
65
66
67static void mask_and_ack_voyagergx(unsigned int irq)
68{
69 disable_voyagergx_irq(irq);
70}
71
72static void end_voyagergx_irq(unsigned int irq)
73{
74 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
75 enable_voyagergx_irq(irq);
76}
77
78static unsigned int startup_voyagergx_irq(unsigned int irq)
79{
80 enable_voyagergx_irq(irq);
81 return 0;
82}
83
84static void shutdown_voyagergx_irq(unsigned int irq)
85{
86 disable_voyagergx_irq(irq);
87}
88
89static struct hw_interrupt_type voyagergx_irq_type = {
90 "VOYAGERGX-IRQ",
91 startup_voyagergx_irq,
92 shutdown_voyagergx_irq,
93 enable_voyagergx_irq,
94 disable_voyagergx_irq,
95 mask_and_ack_voyagergx,
96 end_voyagergx_irq,
97};
98
99static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
100{
101 printk(KERN_INFO
102 "VoyagerGX: spurious interrupt, status: 0x%x\n",
103 inl(INT_STATUS));
104 return IRQ_HANDLED;
105}
106
107
108/*====================================================*/
109
110static struct {
111 int (*func)(int, void *);
112 void *dev;
113} voyagergx_demux[VOYAGER_IRQ_NUM];
114
115void voyagergx_register_irq_demux(int irq,
116 int (*demux)(int irq, void *dev), void *dev)
117{
118 voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux;
119 voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev;
120}
121
122void voyagergx_unregister_irq_demux(int irq)
123{
124 voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0;
125}
126
127int voyagergx_irq_demux(int irq)
128{
129
130 if (irq == IRQ_VOYAGER ) {
131 unsigned long i = 0, bit __attribute__ ((unused));
132 unsigned long val = inl(INT_STATUS);
133#if 1
134 if ( val & ( 1 << 1 )){
135 i = 1;
136 } else if ( val & ( 1 << 2 )){
137 i = 2;
138 } else if ( val & ( 1 << 6 )){
139 i = 6;
140 } else if( val & ( 1 << 10 )){
141 i = 10;
142 } else if( val & ( 1 << 11 )){
143 i = 11;
144 } else if( val & ( 1 << 12 )){
145 i = 12;
146 } else if( val & ( 1 << 17 )){
147 i = 17;
148 } else {
149 printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
150 }
151 pr_debug("voyagergx_irq_demux %d \n", i);
152#else
153 for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++)
154 if (val & bit)
155 break;
156#endif
157 if (i < VOYAGER_IRQ_NUM) {
158 irq = VOYAGER_IRQ_BASE + i;
159 if (voyagergx_demux[i].func != 0)
160 irq = voyagergx_demux[i].func(irq, voyagergx_demux[i].dev);
161 }
162 }
163 return irq;
164}
165
166static struct irqaction irq0 = { voyagergx_interrupt, SA_INTERRUPT, 0, "VOYAGERGX", NULL, NULL};
167
168void __init setup_voyagergx_irq(void)
169{
170 int i, flag;
171
172 printk(KERN_INFO "VoyagerGX configured at 0x%x on irq %d(mapped into %d to %d)\n",
173 VOYAGER_BASE,
174 IRQ_VOYAGER,
175 VOYAGER_IRQ_BASE,
176 VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1);
177
178 for (i=0; i<VOYAGER_IRQ_NUM; i++) {
179 flag = 0;
180 switch (VOYAGER_IRQ_BASE + i) {
181 case VOYAGER_USBH_IRQ:
182 case VOYAGER_8051_IRQ:
183 case VOYAGER_UART0_IRQ:
184 case VOYAGER_UART1_IRQ:
185 case VOYAGER_AC97_IRQ:
186 flag = 1;
187 }
188 if (flag == 1)
189 irq_desc[VOYAGER_IRQ_BASE + i].handler = &voyagergx_irq_type;
190 }
191
192 setup_irq(IRQ_VOYAGER, &irq0);
193}
194
diff --git a/arch/sh/cchips/voyagergx/setup.c b/arch/sh/cchips/voyagergx/setup.c
new file mode 100644
index 000000000000..139ca88ac9e6
--- /dev/null
+++ b/arch/sh/cchips/voyagergx/setup.c
@@ -0,0 +1,37 @@
1/*
2 * arch/sh/cchips/voyagergx/setup.c
3 *
4 * Setup routines for VoyagerGX cchip.
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/init.h>
14#include <linux/module.h>
15#include <asm/io.h>
16#include <asm/rts7751r2d/voyagergx_reg.h>
17
18static int __init setup_voyagergx(void)
19{
20 unsigned long val;
21
22 val = inl(DRAM_CTRL);
23 val |= (DRAM_CTRL_CPU_COLUMN_SIZE_256 |
24 DRAM_CTRL_CPU_ACTIVE_PRECHARGE |
25 DRAM_CTRL_CPU_RESET |
26 DRAM_CTRL_REFRESH_COMMAND |
27 DRAM_CTRL_BLOCK_WRITE_TIME |
28 DRAM_CTRL_BLOCK_WRITE_PRECHARGE |
29 DRAM_CTRL_ACTIVE_PRECHARGE |
30 DRAM_CTRL_RESET |
31 DRAM_CTRL_REMAIN_ACTIVE);
32 outl(val, DRAM_CTRL);
33
34 return 0;
35}
36
37module_init(setup_voyagergx);
diff --git a/arch/sh/configs/adx_defconfig b/arch/sh/configs/adx_defconfig
new file mode 100644
index 000000000000..353bfdc457d4
--- /dev/null
+++ b/arch/sh/configs/adx_defconfig
@@ -0,0 +1,539 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:26 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25# CONFIG_SYSVIPC is not set
26# CONFIG_BSD_PROCESS_ACCT is not set
27# CONFIG_SYSCTL is not set
28# CONFIG_AUDIT is not set
29CONFIG_LOG_BUF_SHIFT=14
30# CONFIG_HOTPLUG is not set
31# CONFIG_IKCONFIG is not set
32# CONFIG_EMBEDDED is not set
33CONFIG_KALLSYMS=y
34# CONFIG_KALLSYMS_EXTRA_PASS is not set
35CONFIG_FUTEX=y
36CONFIG_EPOLL=y
37# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
38CONFIG_SHMEM=y
39CONFIG_CC_ALIGN_FUNCTIONS=0
40CONFIG_CC_ALIGN_LABELS=0
41CONFIG_CC_ALIGN_LOOPS=0
42CONFIG_CC_ALIGN_JUMPS=0
43# CONFIG_TINY_SHMEM is not set
44
45#
46# Loadable module support
47#
48# CONFIG_MODULES is not set
49
50#
51# System type
52#
53# CONFIG_SH_SOLUTION_ENGINE is not set
54# CONFIG_SH_7751_SOLUTION_ENGINE is not set
55# CONFIG_SH_7300_SOLUTION_ENGINE is not set
56# CONFIG_SH_73180_SOLUTION_ENGINE is not set
57# CONFIG_SH_7751_SYSTEMH is not set
58# CONFIG_SH_STB1_HARP is not set
59# CONFIG_SH_STB1_OVERDRIVE is not set
60# CONFIG_SH_HP620 is not set
61# CONFIG_SH_HP680 is not set
62# CONFIG_SH_HP690 is not set
63# CONFIG_SH_CQREEK is not set
64# CONFIG_SH_DMIDA is not set
65# CONFIG_SH_EC3104 is not set
66# CONFIG_SH_SATURN is not set
67# CONFIG_SH_DREAMCAST is not set
68# CONFIG_SH_CAT68701 is not set
69# CONFIG_SH_BIGSUR is not set
70# CONFIG_SH_SH2000 is not set
71CONFIG_SH_ADX=y
72# CONFIG_SH_MPC1211 is not set
73# CONFIG_SH_SH03 is not set
74# CONFIG_SH_SECUREEDGE5410 is not set
75# CONFIG_SH_HS7751RVOIP is not set
76# CONFIG_SH_RTS7751R2D is not set
77# CONFIG_SH_EDOSK7705 is not set
78# CONFIG_SH_SH4202_MICRODEV is not set
79# CONFIG_SH_UNKNOWN is not set
80# CONFIG_CPU_SH2 is not set
81# CONFIG_CPU_SH3 is not set
82CONFIG_CPU_SH4=y
83# CONFIG_CPU_SUBTYPE_SH7604 is not set
84# CONFIG_CPU_SUBTYPE_SH7300 is not set
85# CONFIG_CPU_SUBTYPE_SH7705 is not set
86# CONFIG_CPU_SUBTYPE_SH7707 is not set
87# CONFIG_CPU_SUBTYPE_SH7708 is not set
88# CONFIG_CPU_SUBTYPE_SH7709 is not set
89CONFIG_CPU_SUBTYPE_SH7750=y
90# CONFIG_CPU_SUBTYPE_SH7751 is not set
91# CONFIG_CPU_SUBTYPE_SH7760 is not set
92# CONFIG_CPU_SUBTYPE_SH73180 is not set
93# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
94# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
95# CONFIG_CPU_SUBTYPE_SH4_202 is not set
96CONFIG_MMU=y
97# CONFIG_CMDLINE_BOOL is not set
98CONFIG_MEMORY_START=0x08000000
99CONFIG_MEMORY_SIZE=0x00400000
100CONFIG_MEMORY_SET=y
101# CONFIG_MEMORY_OVERRIDE is not set
102CONFIG_CF_ENABLER=y
103# CONFIG_CF_AREA5 is not set
104CONFIG_CF_AREA6=y
105CONFIG_CF_BASE_ADDR=0xb8000000
106CONFIG_SH_RTC=y
107CONFIG_SH_FPU=y
108CONFIG_ZERO_PAGE_OFFSET=0x00001000
109CONFIG_BOOT_LINK_OFFSET=0x00800000
110CONFIG_CPU_LITTLE_ENDIAN=y
111# CONFIG_PREEMPT is not set
112# CONFIG_UBC_WAKEUP is not set
113# CONFIG_SH_WRITETHROUGH is not set
114# CONFIG_SH_OCRAM is not set
115# CONFIG_SH_STORE_QUEUES is not set
116# CONFIG_SMP is not set
117CONFIG_SH_PCLK_CALC=y
118CONFIG_SH_PCLK_FREQ=50000000
119
120#
121# CPU Frequency scaling
122#
123# CONFIG_CPU_FREQ is not set
124
125#
126# DMA support
127#
128# CONFIG_SH_DMA is not set
129
130#
131# Companion Chips
132#
133# CONFIG_HD6446X_SERIES is not set
134
135#
136# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
137#
138# CONFIG_PCI is not set
139
140#
141# PCCARD (PCMCIA/CardBus) support
142#
143# CONFIG_PCCARD is not set
144
145#
146# PC-card bridges
147#
148
149#
150# PCI Hotplug Support
151#
152
153#
154# Executable file formats
155#
156CONFIG_BINFMT_ELF=y
157# CONFIG_BINFMT_FLAT is not set
158# CONFIG_BINFMT_MISC is not set
159
160#
161# SH initrd options
162#
163# CONFIG_EMBEDDED_RAMDISK is not set
164
165#
166# Device Drivers
167#
168
169#
170# Generic Driver Options
171#
172CONFIG_STANDALONE=y
173CONFIG_PREVENT_FIRMWARE_BUILD=y
174# CONFIG_FW_LOADER is not set
175
176#
177# Memory Technology Devices (MTD)
178#
179# CONFIG_MTD is not set
180
181#
182# Parallel port support
183#
184# CONFIG_PARPORT is not set
185
186#
187# Plug and Play support
188#
189
190#
191# Block devices
192#
193# CONFIG_BLK_DEV_FD is not set
194# CONFIG_BLK_DEV_COW_COMMON is not set
195# CONFIG_BLK_DEV_LOOP is not set
196CONFIG_BLK_DEV_RAM=y
197CONFIG_BLK_DEV_RAM_COUNT=16
198CONFIG_BLK_DEV_RAM_SIZE=4096
199CONFIG_BLK_DEV_INITRD=y
200CONFIG_INITRAMFS_SOURCE=""
201# CONFIG_LBD is not set
202# CONFIG_CDROM_PKTCDVD is not set
203
204#
205# IO Schedulers
206#
207CONFIG_IOSCHED_NOOP=y
208CONFIG_IOSCHED_AS=y
209CONFIG_IOSCHED_DEADLINE=y
210CONFIG_IOSCHED_CFQ=y
211
212#
213# ATA/ATAPI/MFM/RLL support
214#
215CONFIG_IDE=y
216CONFIG_IDE_MAX_HWIFS=4
217CONFIG_BLK_DEV_IDE=y
218
219#
220# Please see Documentation/ide.txt for help/info on IDE drives
221#
222# CONFIG_BLK_DEV_IDE_SATA is not set
223CONFIG_BLK_DEV_IDEDISK=y
224# CONFIG_IDEDISK_MULTI_MODE is not set
225# CONFIG_BLK_DEV_IDECD is not set
226# CONFIG_BLK_DEV_IDETAPE is not set
227# CONFIG_BLK_DEV_IDEFLOPPY is not set
228# CONFIG_IDE_TASK_IOCTL is not set
229
230#
231# IDE chipset support/bugfixes
232#
233CONFIG_IDE_GENERIC=y
234CONFIG_IDE_SH=y
235# CONFIG_IDE_ARM is not set
236# CONFIG_BLK_DEV_IDEDMA is not set
237# CONFIG_IDEDMA_AUTO is not set
238# CONFIG_BLK_DEV_HD is not set
239
240#
241# SCSI device support
242#
243# CONFIG_SCSI is not set
244
245#
246# Multi-device support (RAID and LVM)
247#
248# CONFIG_MD is not set
249
250#
251# Fusion MPT device support
252#
253
254#
255# IEEE 1394 (FireWire) support
256#
257
258#
259# I2O device support
260#
261
262#
263# Networking support
264#
265# CONFIG_NET is not set
266# CONFIG_NETPOLL is not set
267# CONFIG_NET_POLL_CONTROLLER is not set
268
269#
270# ISDN subsystem
271#
272
273#
274# Telephony Support
275#
276# CONFIG_PHONE is not set
277
278#
279# Input device support
280#
281CONFIG_INPUT=y
282
283#
284# Userland interfaces
285#
286CONFIG_INPUT_MOUSEDEV=y
287CONFIG_INPUT_MOUSEDEV_PSAUX=y
288CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
289CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
290# CONFIG_INPUT_JOYDEV is not set
291# CONFIG_INPUT_TSDEV is not set
292# CONFIG_INPUT_EVDEV is not set
293# CONFIG_INPUT_EVBUG is not set
294
295#
296# Input I/O drivers
297#
298# CONFIG_GAMEPORT is not set
299CONFIG_SOUND_GAMEPORT=y
300CONFIG_SERIO=y
301CONFIG_SERIO_I8042=y
302CONFIG_SERIO_SERPORT=y
303# CONFIG_SERIO_CT82C710 is not set
304CONFIG_SERIO_LIBPS2=y
305# CONFIG_SERIO_RAW is not set
306
307#
308# Input Device Drivers
309#
310CONFIG_INPUT_KEYBOARD=y
311CONFIG_KEYBOARD_ATKBD=y
312# CONFIG_KEYBOARD_SUNKBD is not set
313# CONFIG_KEYBOARD_LKKBD is not set
314# CONFIG_KEYBOARD_XTKBD is not set
315# CONFIG_KEYBOARD_NEWTON is not set
316CONFIG_INPUT_MOUSE=y
317CONFIG_MOUSE_PS2=y
318# CONFIG_MOUSE_SERIAL is not set
319# CONFIG_MOUSE_VSXXXAA is not set
320# CONFIG_INPUT_JOYSTICK is not set
321# CONFIG_INPUT_TOUCHSCREEN is not set
322# CONFIG_INPUT_MISC is not set
323
324#
325# Character devices
326#
327CONFIG_VT=y
328CONFIG_VT_CONSOLE=y
329CONFIG_HW_CONSOLE=y
330# CONFIG_SERIAL_NONSTANDARD is not set
331
332#
333# Serial drivers
334#
335# CONFIG_SERIAL_8250 is not set
336
337#
338# Non-8250 serial port support
339#
340# CONFIG_SERIAL_SH_SCI is not set
341CONFIG_UNIX98_PTYS=y
342CONFIG_LEGACY_PTYS=y
343CONFIG_LEGACY_PTY_COUNT=256
344
345#
346# IPMI
347#
348# CONFIG_IPMI_HANDLER is not set
349
350#
351# Watchdog Cards
352#
353# CONFIG_WATCHDOG is not set
354# CONFIG_RTC is not set
355# CONFIG_GEN_RTC is not set
356# CONFIG_DTLK is not set
357# CONFIG_R3964 is not set
358
359#
360# Ftape, the floppy tape device driver
361#
362# CONFIG_DRM is not set
363# CONFIG_RAW_DRIVER is not set
364
365#
366# I2C support
367#
368# CONFIG_I2C is not set
369
370#
371# Dallas's 1-wire bus
372#
373# CONFIG_W1 is not set
374
375#
376# Misc devices
377#
378
379#
380# Multimedia devices
381#
382# CONFIG_VIDEO_DEV is not set
383
384#
385# Digital Video Broadcasting Devices
386#
387
388#
389# Graphics support
390#
391# CONFIG_FB is not set
392
393#
394# Console display driver support
395#
396CONFIG_VGA_CONSOLE=y
397CONFIG_DUMMY_CONSOLE=y
398
399#
400# Sound
401#
402# CONFIG_SOUND is not set
403
404#
405# USB support
406#
407# CONFIG_USB_ARCH_HAS_HCD is not set
408# CONFIG_USB_ARCH_HAS_OHCI is not set
409
410#
411# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
412#
413
414#
415# USB Gadget Support
416#
417# CONFIG_USB_GADGET is not set
418
419#
420# MMC/SD Card support
421#
422# CONFIG_MMC is not set
423
424#
425# InfiniBand support
426#
427# CONFIG_INFINIBAND is not set
428
429#
430# File systems
431#
432CONFIG_EXT2_FS=y
433# CONFIG_EXT2_FS_XATTR is not set
434# CONFIG_EXT3_FS is not set
435# CONFIG_JBD is not set
436# CONFIG_REISERFS_FS is not set
437# CONFIG_JFS_FS is not set
438
439#
440# XFS support
441#
442# CONFIG_XFS_FS is not set
443# CONFIG_MINIX_FS is not set
444# CONFIG_ROMFS_FS is not set
445# CONFIG_QUOTA is not set
446CONFIG_DNOTIFY=y
447# CONFIG_AUTOFS_FS is not set
448# CONFIG_AUTOFS4_FS is not set
449
450#
451# CD-ROM/DVD Filesystems
452#
453# CONFIG_ISO9660_FS is not set
454# CONFIG_UDF_FS is not set
455
456#
457# DOS/FAT/NT Filesystems
458#
459# CONFIG_MSDOS_FS is not set
460# CONFIG_VFAT_FS is not set
461# CONFIG_NTFS_FS is not set
462
463#
464# Pseudo filesystems
465#
466CONFIG_PROC_FS=y
467# CONFIG_PROC_KCORE is not set
468CONFIG_SYSFS=y
469# CONFIG_DEVFS_FS is not set
470# CONFIG_DEVPTS_FS_XATTR is not set
471# CONFIG_TMPFS is not set
472# CONFIG_HUGETLBFS is not set
473# CONFIG_HUGETLB_PAGE is not set
474CONFIG_RAMFS=y
475
476#
477# Miscellaneous filesystems
478#
479# CONFIG_ADFS_FS is not set
480# CONFIG_AFFS_FS is not set
481# CONFIG_HFS_FS is not set
482# CONFIG_HFSPLUS_FS is not set
483# CONFIG_BEFS_FS is not set
484# CONFIG_BFS_FS is not set
485# CONFIG_EFS_FS is not set
486# CONFIG_CRAMFS is not set
487# CONFIG_VXFS_FS is not set
488# CONFIG_HPFS_FS is not set
489# CONFIG_QNX4FS_FS is not set
490# CONFIG_SYSV_FS is not set
491# CONFIG_UFS_FS is not set
492
493#
494# Partition Types
495#
496# CONFIG_PARTITION_ADVANCED is not set
497CONFIG_MSDOS_PARTITION=y
498
499#
500# Native Language Support
501#
502# CONFIG_NLS is not set
503
504#
505# Profiling support
506#
507# CONFIG_PROFILING is not set
508
509#
510# Kernel hacking
511#
512# CONFIG_DEBUG_KERNEL is not set
513# CONFIG_FRAME_POINTER is not set
514CONFIG_SH_STANDARD_BIOS=y
515# CONFIG_EARLY_SCIF_CONSOLE is not set
516# CONFIG_EARLY_PRINTK is not set
517# CONFIG_KGDB is not set
518
519#
520# Security options
521#
522# CONFIG_KEYS is not set
523# CONFIG_SECURITY is not set
524
525#
526# Cryptographic options
527#
528# CONFIG_CRYPTO is not set
529
530#
531# Hardware crypto devices
532#
533
534#
535# Library routines
536#
537# CONFIG_CRC_CCITT is not set
538# CONFIG_CRC32 is not set
539# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/cqreek_defconfig b/arch/sh/configs/cqreek_defconfig
new file mode 100644
index 000000000000..614662ae5789
--- /dev/null
+++ b/arch/sh/configs/cqreek_defconfig
@@ -0,0 +1,533 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:38 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25# CONFIG_SYSVIPC is not set
26# CONFIG_BSD_PROCESS_ACCT is not set
27# CONFIG_SYSCTL is not set
28# CONFIG_AUDIT is not set
29CONFIG_LOG_BUF_SHIFT=14
30# CONFIG_HOTPLUG is not set
31# CONFIG_IKCONFIG is not set
32# CONFIG_EMBEDDED is not set
33CONFIG_KALLSYMS=y
34# CONFIG_KALLSYMS_EXTRA_PASS is not set
35CONFIG_FUTEX=y
36CONFIG_EPOLL=y
37# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
38CONFIG_SHMEM=y
39CONFIG_CC_ALIGN_FUNCTIONS=0
40CONFIG_CC_ALIGN_LABELS=0
41CONFIG_CC_ALIGN_LOOPS=0
42CONFIG_CC_ALIGN_JUMPS=0
43# CONFIG_TINY_SHMEM is not set
44
45#
46# Loadable module support
47#
48# CONFIG_MODULES is not set
49
50#
51# System type
52#
53# CONFIG_SH_SOLUTION_ENGINE is not set
54# CONFIG_SH_7751_SOLUTION_ENGINE is not set
55# CONFIG_SH_7300_SOLUTION_ENGINE is not set
56# CONFIG_SH_73180_SOLUTION_ENGINE is not set
57# CONFIG_SH_7751_SYSTEMH is not set
58# CONFIG_SH_STB1_HARP is not set
59# CONFIG_SH_STB1_OVERDRIVE is not set
60# CONFIG_SH_HP620 is not set
61# CONFIG_SH_HP680 is not set
62# CONFIG_SH_HP690 is not set
63CONFIG_SH_CQREEK=y
64# CONFIG_SH_DMIDA is not set
65# CONFIG_SH_EC3104 is not set
66# CONFIG_SH_SATURN is not set
67# CONFIG_SH_DREAMCAST is not set
68# CONFIG_SH_CAT68701 is not set
69# CONFIG_SH_BIGSUR is not set
70# CONFIG_SH_SH2000 is not set
71# CONFIG_SH_ADX is not set
72# CONFIG_SH_MPC1211 is not set
73# CONFIG_SH_SH03 is not set
74# CONFIG_SH_SECUREEDGE5410 is not set
75# CONFIG_SH_HS7751RVOIP is not set
76# CONFIG_SH_RTS7751R2D is not set
77# CONFIG_SH_EDOSK7705 is not set
78# CONFIG_SH_SH4202_MICRODEV is not set
79# CONFIG_SH_UNKNOWN is not set
80# CONFIG_CPU_SH2 is not set
81CONFIG_CPU_SH3=y
82# CONFIG_CPU_SH4 is not set
83# CONFIG_CPU_SUBTYPE_SH7604 is not set
84# CONFIG_CPU_SUBTYPE_SH7300 is not set
85# CONFIG_CPU_SUBTYPE_SH7705 is not set
86# CONFIG_CPU_SUBTYPE_SH7707 is not set
87CONFIG_CPU_SUBTYPE_SH7708=y
88# CONFIG_CPU_SUBTYPE_SH7709 is not set
89# CONFIG_CPU_SUBTYPE_SH7750 is not set
90# CONFIG_CPU_SUBTYPE_SH7751 is not set
91# CONFIG_CPU_SUBTYPE_SH7760 is not set
92# CONFIG_CPU_SUBTYPE_SH73180 is not set
93# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
94# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
95# CONFIG_CPU_SUBTYPE_SH4_202 is not set
96CONFIG_MMU=y
97# CONFIG_CMDLINE_BOOL is not set
98CONFIG_MEMORY_START=0x0c000000
99CONFIG_MEMORY_SIZE=0x00400000
100# CONFIG_MEMORY_OVERRIDE is not set
101CONFIG_SH_RTC=y
102CONFIG_SH_DSP=y
103CONFIG_SH_ADC=y
104CONFIG_ZERO_PAGE_OFFSET=0x00001000
105CONFIG_BOOT_LINK_OFFSET=0x00800000
106CONFIG_CPU_LITTLE_ENDIAN=y
107# CONFIG_PREEMPT is not set
108# CONFIG_UBC_WAKEUP is not set
109# CONFIG_SH_WRITETHROUGH is not set
110# CONFIG_SH_OCRAM is not set
111# CONFIG_SMP is not set
112CONFIG_SH_PCLK_CALC=y
113CONFIG_SH_PCLK_FREQ=1193182
114
115#
116# CPU Frequency scaling
117#
118# CONFIG_CPU_FREQ is not set
119
120#
121# DMA support
122#
123# CONFIG_SH_DMA is not set
124
125#
126# Companion Chips
127#
128# CONFIG_HD6446X_SERIES is not set
129
130#
131# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
132#
133# CONFIG_PCI is not set
134
135#
136# PCCARD (PCMCIA/CardBus) support
137#
138# CONFIG_PCCARD is not set
139
140#
141# PC-card bridges
142#
143
144#
145# PCI Hotplug Support
146#
147
148#
149# Executable file formats
150#
151CONFIG_BINFMT_ELF=y
152# CONFIG_BINFMT_FLAT is not set
153# CONFIG_BINFMT_MISC is not set
154
155#
156# SH initrd options
157#
158# CONFIG_EMBEDDED_RAMDISK is not set
159
160#
161# Device Drivers
162#
163
164#
165# Generic Driver Options
166#
167CONFIG_STANDALONE=y
168CONFIG_PREVENT_FIRMWARE_BUILD=y
169# CONFIG_FW_LOADER is not set
170
171#
172# Memory Technology Devices (MTD)
173#
174# CONFIG_MTD is not set
175
176#
177# Parallel port support
178#
179# CONFIG_PARPORT is not set
180
181#
182# Plug and Play support
183#
184
185#
186# Block devices
187#
188# CONFIG_BLK_DEV_FD is not set
189# CONFIG_BLK_DEV_COW_COMMON is not set
190# CONFIG_BLK_DEV_LOOP is not set
191CONFIG_BLK_DEV_RAM=y
192CONFIG_BLK_DEV_RAM_COUNT=16
193CONFIG_BLK_DEV_RAM_SIZE=4096
194CONFIG_BLK_DEV_INITRD=y
195CONFIG_INITRAMFS_SOURCE=""
196# CONFIG_LBD is not set
197# CONFIG_CDROM_PKTCDVD is not set
198
199#
200# IO Schedulers
201#
202CONFIG_IOSCHED_NOOP=y
203CONFIG_IOSCHED_AS=y
204CONFIG_IOSCHED_DEADLINE=y
205CONFIG_IOSCHED_CFQ=y
206
207#
208# ATA/ATAPI/MFM/RLL support
209#
210CONFIG_IDE=y
211CONFIG_IDE_MAX_HWIFS=4
212CONFIG_BLK_DEV_IDE=y
213
214#
215# Please see Documentation/ide.txt for help/info on IDE drives
216#
217# CONFIG_BLK_DEV_IDE_SATA is not set
218CONFIG_BLK_DEV_IDEDISK=y
219# CONFIG_IDEDISK_MULTI_MODE is not set
220# CONFIG_BLK_DEV_IDECD is not set
221# CONFIG_BLK_DEV_IDETAPE is not set
222# CONFIG_BLK_DEV_IDEFLOPPY is not set
223# CONFIG_IDE_TASK_IOCTL is not set
224
225#
226# IDE chipset support/bugfixes
227#
228CONFIG_IDE_GENERIC=y
229CONFIG_IDE_SH=y
230# CONFIG_IDE_ARM is not set
231# CONFIG_BLK_DEV_IDEDMA is not set
232# CONFIG_IDEDMA_AUTO is not set
233# CONFIG_BLK_DEV_HD is not set
234
235#
236# SCSI device support
237#
238# CONFIG_SCSI is not set
239
240#
241# Multi-device support (RAID and LVM)
242#
243# CONFIG_MD is not set
244
245#
246# Fusion MPT device support
247#
248
249#
250# IEEE 1394 (FireWire) support
251#
252
253#
254# I2O device support
255#
256
257#
258# Networking support
259#
260# CONFIG_NET is not set
261# CONFIG_NETPOLL is not set
262# CONFIG_NET_POLL_CONTROLLER is not set
263
264#
265# ISDN subsystem
266#
267
268#
269# Telephony Support
270#
271# CONFIG_PHONE is not set
272
273#
274# Input device support
275#
276CONFIG_INPUT=y
277
278#
279# Userland interfaces
280#
281CONFIG_INPUT_MOUSEDEV=y
282CONFIG_INPUT_MOUSEDEV_PSAUX=y
283CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
284CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
285# CONFIG_INPUT_JOYDEV is not set
286# CONFIG_INPUT_TSDEV is not set
287# CONFIG_INPUT_EVDEV is not set
288# CONFIG_INPUT_EVBUG is not set
289
290#
291# Input I/O drivers
292#
293# CONFIG_GAMEPORT is not set
294CONFIG_SOUND_GAMEPORT=y
295CONFIG_SERIO=y
296CONFIG_SERIO_I8042=y
297CONFIG_SERIO_SERPORT=y
298# CONFIG_SERIO_CT82C710 is not set
299CONFIG_SERIO_LIBPS2=y
300# CONFIG_SERIO_RAW is not set
301
302#
303# Input Device Drivers
304#
305CONFIG_INPUT_KEYBOARD=y
306CONFIG_KEYBOARD_ATKBD=y
307# CONFIG_KEYBOARD_SUNKBD is not set
308# CONFIG_KEYBOARD_LKKBD is not set
309# CONFIG_KEYBOARD_XTKBD is not set
310# CONFIG_KEYBOARD_NEWTON is not set
311CONFIG_INPUT_MOUSE=y
312CONFIG_MOUSE_PS2=y
313# CONFIG_MOUSE_SERIAL is not set
314# CONFIG_MOUSE_VSXXXAA is not set
315# CONFIG_INPUT_JOYSTICK is not set
316# CONFIG_INPUT_TOUCHSCREEN is not set
317# CONFIG_INPUT_MISC is not set
318
319#
320# Character devices
321#
322CONFIG_VT=y
323CONFIG_VT_CONSOLE=y
324CONFIG_HW_CONSOLE=y
325# CONFIG_SERIAL_NONSTANDARD is not set
326
327#
328# Serial drivers
329#
330# CONFIG_SERIAL_8250 is not set
331
332#
333# Non-8250 serial port support
334#
335# CONFIG_SERIAL_SH_SCI is not set
336CONFIG_UNIX98_PTYS=y
337CONFIG_LEGACY_PTYS=y
338CONFIG_LEGACY_PTY_COUNT=256
339
340#
341# IPMI
342#
343# CONFIG_IPMI_HANDLER is not set
344
345#
346# Watchdog Cards
347#
348# CONFIG_WATCHDOG is not set
349# CONFIG_RTC is not set
350# CONFIG_GEN_RTC is not set
351# CONFIG_DTLK is not set
352# CONFIG_R3964 is not set
353
354#
355# Ftape, the floppy tape device driver
356#
357# CONFIG_DRM is not set
358# CONFIG_RAW_DRIVER is not set
359
360#
361# I2C support
362#
363# CONFIG_I2C is not set
364
365#
366# Dallas's 1-wire bus
367#
368# CONFIG_W1 is not set
369
370#
371# Misc devices
372#
373
374#
375# Multimedia devices
376#
377# CONFIG_VIDEO_DEV is not set
378
379#
380# Digital Video Broadcasting Devices
381#
382
383#
384# Graphics support
385#
386# CONFIG_FB is not set
387
388#
389# Console display driver support
390#
391CONFIG_VGA_CONSOLE=y
392CONFIG_DUMMY_CONSOLE=y
393
394#
395# Sound
396#
397# CONFIG_SOUND is not set
398
399#
400# USB support
401#
402# CONFIG_USB_ARCH_HAS_HCD is not set
403# CONFIG_USB_ARCH_HAS_OHCI is not set
404
405#
406# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
407#
408
409#
410# USB Gadget Support
411#
412# CONFIG_USB_GADGET is not set
413
414#
415# MMC/SD Card support
416#
417# CONFIG_MMC is not set
418
419#
420# InfiniBand support
421#
422# CONFIG_INFINIBAND is not set
423
424#
425# File systems
426#
427CONFIG_EXT2_FS=y
428# CONFIG_EXT2_FS_XATTR is not set
429# CONFIG_EXT3_FS is not set
430# CONFIG_JBD is not set
431# CONFIG_REISERFS_FS is not set
432# CONFIG_JFS_FS is not set
433
434#
435# XFS support
436#
437# CONFIG_XFS_FS is not set
438# CONFIG_MINIX_FS is not set
439# CONFIG_ROMFS_FS is not set
440# CONFIG_QUOTA is not set
441CONFIG_DNOTIFY=y
442# CONFIG_AUTOFS_FS is not set
443# CONFIG_AUTOFS4_FS is not set
444
445#
446# CD-ROM/DVD Filesystems
447#
448# CONFIG_ISO9660_FS is not set
449# CONFIG_UDF_FS is not set
450
451#
452# DOS/FAT/NT Filesystems
453#
454# CONFIG_MSDOS_FS is not set
455# CONFIG_VFAT_FS is not set
456# CONFIG_NTFS_FS is not set
457
458#
459# Pseudo filesystems
460#
461CONFIG_PROC_FS=y
462# CONFIG_PROC_KCORE is not set
463CONFIG_SYSFS=y
464# CONFIG_DEVFS_FS is not set
465# CONFIG_DEVPTS_FS_XATTR is not set
466# CONFIG_TMPFS is not set
467# CONFIG_HUGETLBFS is not set
468# CONFIG_HUGETLB_PAGE is not set
469CONFIG_RAMFS=y
470
471#
472# Miscellaneous filesystems
473#
474# CONFIG_ADFS_FS is not set
475# CONFIG_AFFS_FS is not set
476# CONFIG_HFS_FS is not set
477# CONFIG_HFSPLUS_FS is not set
478# CONFIG_BEFS_FS is not set
479# CONFIG_BFS_FS is not set
480# CONFIG_EFS_FS is not set
481# CONFIG_CRAMFS is not set
482# CONFIG_VXFS_FS is not set
483# CONFIG_HPFS_FS is not set
484# CONFIG_QNX4FS_FS is not set
485# CONFIG_SYSV_FS is not set
486# CONFIG_UFS_FS is not set
487
488#
489# Partition Types
490#
491# CONFIG_PARTITION_ADVANCED is not set
492CONFIG_MSDOS_PARTITION=y
493
494#
495# Native Language Support
496#
497# CONFIG_NLS is not set
498
499#
500# Profiling support
501#
502# CONFIG_PROFILING is not set
503
504#
505# Kernel hacking
506#
507# CONFIG_DEBUG_KERNEL is not set
508# CONFIG_FRAME_POINTER is not set
509CONFIG_SH_STANDARD_BIOS=y
510# CONFIG_EARLY_PRINTK is not set
511# CONFIG_KGDB is not set
512
513#
514# Security options
515#
516# CONFIG_KEYS is not set
517# CONFIG_SECURITY is not set
518
519#
520# Cryptographic options
521#
522# CONFIG_CRYPTO is not set
523
524#
525# Hardware crypto devices
526#
527
528#
529# Library routines
530#
531# CONFIG_CRC_CCITT is not set
532# CONFIG_CRC32 is not set
533# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
new file mode 100644
index 000000000000..776c1909bee3
--- /dev/null
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -0,0 +1,794 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:40 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19CONFIG_LOCK_KERNEL=y
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25CONFIG_SWAP=y
26CONFIG_SYSVIPC=y
27# CONFIG_POSIX_MQUEUE is not set
28CONFIG_BSD_PROCESS_ACCT=y
29# CONFIG_BSD_PROCESS_ACCT_V3 is not set
30CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set
32CONFIG_LOG_BUF_SHIFT=14
33CONFIG_HOTPLUG=y
34CONFIG_KOBJECT_UEVENT=y
35# CONFIG_IKCONFIG is not set
36CONFIG_EMBEDDED=y
37CONFIG_KALLSYMS=y
38# CONFIG_KALLSYMS_EXTRA_PASS is not set
39CONFIG_FUTEX=y
40CONFIG_EPOLL=y
41CONFIG_CC_OPTIMIZE_FOR_SIZE=y
42CONFIG_SHMEM=y
43CONFIG_CC_ALIGN_FUNCTIONS=0
44CONFIG_CC_ALIGN_LABELS=0
45CONFIG_CC_ALIGN_LOOPS=0
46CONFIG_CC_ALIGN_JUMPS=0
47# CONFIG_TINY_SHMEM is not set
48
49#
50# Loadable module support
51#
52CONFIG_MODULES=y
53CONFIG_MODULE_UNLOAD=y
54# CONFIG_MODULE_FORCE_UNLOAD is not set
55CONFIG_OBSOLETE_MODPARM=y
56# CONFIG_MODVERSIONS is not set
57# CONFIG_MODULE_SRCVERSION_ALL is not set
58CONFIG_KMOD=y
59
60#
61# System type
62#
63# CONFIG_SH_SOLUTION_ENGINE is not set
64# CONFIG_SH_7751_SOLUTION_ENGINE is not set
65# CONFIG_SH_7300_SOLUTION_ENGINE is not set
66# CONFIG_SH_73180_SOLUTION_ENGINE is not set
67# CONFIG_SH_7751_SYSTEMH is not set
68# CONFIG_SH_STB1_HARP is not set
69# CONFIG_SH_STB1_OVERDRIVE is not set
70# CONFIG_SH_HP620 is not set
71# CONFIG_SH_HP680 is not set
72# CONFIG_SH_HP690 is not set
73# CONFIG_SH_CQREEK is not set
74# CONFIG_SH_DMIDA is not set
75# CONFIG_SH_EC3104 is not set
76# CONFIG_SH_SATURN is not set
77CONFIG_SH_DREAMCAST=y
78# CONFIG_SH_CAT68701 is not set
79# CONFIG_SH_BIGSUR is not set
80# CONFIG_SH_SH2000 is not set
81# CONFIG_SH_ADX is not set
82# CONFIG_SH_MPC1211 is not set
83# CONFIG_SH_SH03 is not set
84# CONFIG_SH_SECUREEDGE5410 is not set
85# CONFIG_SH_HS7751RVOIP is not set
86# CONFIG_SH_RTS7751R2D is not set
87# CONFIG_SH_EDOSK7705 is not set
88# CONFIG_SH_SH4202_MICRODEV is not set
89# CONFIG_SH_UNKNOWN is not set
90# CONFIG_CPU_SH2 is not set
91# CONFIG_CPU_SH3 is not set
92CONFIG_CPU_SH4=y
93# CONFIG_CPU_SUBTYPE_SH7604 is not set
94# CONFIG_CPU_SUBTYPE_SH7300 is not set
95# CONFIG_CPU_SUBTYPE_SH7705 is not set
96# CONFIG_CPU_SUBTYPE_SH7707 is not set
97# CONFIG_CPU_SUBTYPE_SH7708 is not set
98# CONFIG_CPU_SUBTYPE_SH7709 is not set
99CONFIG_CPU_SUBTYPE_SH7750=y
100# CONFIG_CPU_SUBTYPE_SH7751 is not set
101# CONFIG_CPU_SUBTYPE_SH7760 is not set
102# CONFIG_CPU_SUBTYPE_SH73180 is not set
103# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
104# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
105# CONFIG_CPU_SUBTYPE_SH4_202 is not set
106CONFIG_MMU=y
107CONFIG_HUGETLB_PAGE_SIZE_64K=y
108# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
109# CONFIG_CMDLINE_BOOL is not set
110CONFIG_MEMORY_START=0x0c000000
111CONFIG_MEMORY_SIZE=0x01000000
112CONFIG_MEMORY_SET=y
113# CONFIG_MEMORY_OVERRIDE is not set
114CONFIG_SH_FPU=y
115CONFIG_ZERO_PAGE_OFFSET=0x00001000
116CONFIG_BOOT_LINK_OFFSET=0x00800000
117CONFIG_CPU_LITTLE_ENDIAN=y
118CONFIG_PREEMPT=y
119# CONFIG_UBC_WAKEUP is not set
120# CONFIG_SH_WRITETHROUGH is not set
121CONFIG_SH_OCRAM=y
122CONFIG_SH_STORE_QUEUES=y
123# CONFIG_SMP is not set
124CONFIG_SH_PCLK_CALC=y
125CONFIG_SH_PCLK_FREQ=49876504
126
127#
128# CPU Frequency scaling
129#
130CONFIG_CPU_FREQ=y
131# CONFIG_CPU_FREQ_DEBUG is not set
132CONFIG_CPU_FREQ_STAT=y
133# CONFIG_CPU_FREQ_STAT_DETAILS is not set
134CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
135# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
136CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
137CONFIG_CPU_FREQ_GOV_POWERSAVE=y
138CONFIG_CPU_FREQ_GOV_USERSPACE=y
139# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
140CONFIG_CPU_FREQ_TABLE=y
141CONFIG_SH_CPU_FREQ=y
142
143#
144# DMA support
145#
146CONFIG_SH_DMA=y
147CONFIG_NR_ONCHIP_DMA_CHANNELS=4
148CONFIG_NR_DMA_CHANNELS_BOOL=y
149CONFIG_NR_DMA_CHANNELS=9
150
151#
152# Companion Chips
153#
154# CONFIG_HD6446X_SERIES is not set
155
156#
157# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
158#
159CONFIG_MAPLE=y
160CONFIG_PCI=y
161# CONFIG_SH_PCIDMA_NONCOHERENT is not set
162CONFIG_PCI_AUTO=y
163CONFIG_PCI_LEGACY_PROC=y
164CONFIG_PCI_NAMES=y
165
166#
167# PCCARD (PCMCIA/CardBus) support
168#
169# CONFIG_PCCARD is not set
170
171#
172# PC-card bridges
173#
174
175#
176# PCI Hotplug Support
177#
178# CONFIG_HOTPLUG_PCI is not set
179
180#
181# Executable file formats
182#
183CONFIG_BINFMT_ELF=y
184# CONFIG_BINFMT_FLAT is not set
185# CONFIG_BINFMT_MISC is not set
186
187#
188# SH initrd options
189#
190# CONFIG_EMBEDDED_RAMDISK is not set
191
192#
193# Device Drivers
194#
195
196#
197# Generic Driver Options
198#
199# CONFIG_STANDALONE is not set
200CONFIG_PREVENT_FIRMWARE_BUILD=y
201# CONFIG_FW_LOADER is not set
202
203#
204# Memory Technology Devices (MTD)
205#
206# CONFIG_MTD is not set
207
208#
209# Parallel port support
210#
211# CONFIG_PARPORT is not set
212
213#
214# Plug and Play support
215#
216
217#
218# Block devices
219#
220# CONFIG_BLK_DEV_FD is not set
221# CONFIG_BLK_CPQ_DA is not set
222# CONFIG_BLK_CPQ_CISS_DA is not set
223# CONFIG_BLK_DEV_DAC960 is not set
224# CONFIG_BLK_DEV_UMEM is not set
225# CONFIG_BLK_DEV_COW_COMMON is not set
226# CONFIG_BLK_DEV_LOOP is not set
227# CONFIG_BLK_DEV_NBD is not set
228# CONFIG_BLK_DEV_SX8 is not set
229CONFIG_BLK_DEV_RAM=y
230CONFIG_BLK_DEV_RAM_COUNT=16
231CONFIG_BLK_DEV_RAM_SIZE=1024
232CONFIG_BLK_DEV_INITRD=y
233CONFIG_INITRAMFS_SOURCE=""
234# CONFIG_LBD is not set
235# CONFIG_CDROM_PKTCDVD is not set
236
237#
238# IO Schedulers
239#
240CONFIG_IOSCHED_NOOP=y
241CONFIG_IOSCHED_AS=y
242CONFIG_IOSCHED_DEADLINE=y
243CONFIG_IOSCHED_CFQ=y
244# CONFIG_ATA_OVER_ETH is not set
245
246#
247# ATA/ATAPI/MFM/RLL support
248#
249# CONFIG_IDE is not set
250
251#
252# SCSI device support
253#
254# CONFIG_SCSI is not set
255
256#
257# Multi-device support (RAID and LVM)
258#
259# CONFIG_MD is not set
260
261#
262# Fusion MPT device support
263#
264
265#
266# IEEE 1394 (FireWire) support
267#
268# CONFIG_IEEE1394 is not set
269
270#
271# I2O device support
272#
273# CONFIG_I2O is not set
274
275#
276# Networking support
277#
278CONFIG_NET=y
279
280#
281# Networking options
282#
283CONFIG_PACKET=y
284# CONFIG_PACKET_MMAP is not set
285# CONFIG_NETLINK_DEV is not set
286CONFIG_UNIX=y
287# CONFIG_NET_KEY is not set
288CONFIG_INET=y
289# CONFIG_IP_MULTICAST is not set
290# CONFIG_IP_ADVANCED_ROUTER is not set
291CONFIG_IP_PNP=y
292CONFIG_IP_PNP_DHCP=y
293# CONFIG_IP_PNP_BOOTP is not set
294# CONFIG_IP_PNP_RARP is not set
295# CONFIG_NET_IPIP is not set
296# CONFIG_NET_IPGRE is not set
297# CONFIG_ARPD is not set
298# CONFIG_SYN_COOKIES is not set
299# CONFIG_INET_AH is not set
300# CONFIG_INET_ESP is not set
301# CONFIG_INET_IPCOMP is not set
302# CONFIG_INET_TUNNEL is not set
303CONFIG_IP_TCPDIAG=y
304# CONFIG_IP_TCPDIAG_IPV6 is not set
305# CONFIG_IPV6 is not set
306# CONFIG_NETFILTER is not set
307
308#
309# SCTP Configuration (EXPERIMENTAL)
310#
311# CONFIG_IP_SCTP is not set
312# CONFIG_ATM is not set
313# CONFIG_BRIDGE is not set
314# CONFIG_VLAN_8021Q is not set
315# CONFIG_DECNET is not set
316# CONFIG_LLC2 is not set
317# CONFIG_IPX is not set
318# CONFIG_ATALK is not set
319# CONFIG_X25 is not set
320# CONFIG_LAPB is not set
321# CONFIG_NET_DIVERT is not set
322# CONFIG_ECONET is not set
323# CONFIG_WAN_ROUTER is not set
324
325#
326# QoS and/or fair queueing
327#
328# CONFIG_NET_SCHED is not set
329# CONFIG_NET_CLS_ROUTE is not set
330
331#
332# Network testing
333#
334# CONFIG_NET_PKTGEN is not set
335# CONFIG_NETPOLL is not set
336# CONFIG_NET_POLL_CONTROLLER is not set
337# CONFIG_HAMRADIO is not set
338# CONFIG_IRDA is not set
339# CONFIG_BT is not set
340CONFIG_NETDEVICES=y
341# CONFIG_DUMMY is not set
342# CONFIG_BONDING is not set
343# CONFIG_EQUALIZER is not set
344# CONFIG_TUN is not set
345
346#
347# ARCnet devices
348#
349# CONFIG_ARCNET is not set
350
351#
352# Ethernet (10 or 100Mbit)
353#
354CONFIG_NET_ETHERNET=y
355CONFIG_MII=y
356# CONFIG_STNIC is not set
357# CONFIG_HAPPYMEAL is not set
358# CONFIG_SUNGEM is not set
359# CONFIG_NET_VENDOR_3COM is not set
360# CONFIG_SMC91X is not set
361
362#
363# Tulip family network device support
364#
365# CONFIG_NET_TULIP is not set
366# CONFIG_HP100 is not set
367CONFIG_NET_PCI=y
368# CONFIG_PCNET32 is not set
369# CONFIG_AMD8111_ETH is not set
370# CONFIG_ADAPTEC_STARFIRE is not set
371# CONFIG_B44 is not set
372# CONFIG_FORCEDETH is not set
373# CONFIG_DGRS is not set
374# CONFIG_EEPRO100 is not set
375# CONFIG_E100 is not set
376# CONFIG_FEALNX is not set
377# CONFIG_NATSEMI is not set
378# CONFIG_NE2K_PCI is not set
379# CONFIG_8139CP is not set
380CONFIG_8139TOO=y
381# CONFIG_8139TOO_PIO is not set
382# CONFIG_8139TOO_TUNE_TWISTER is not set
383# CONFIG_8139TOO_8129 is not set
384# CONFIG_8139_OLD_RX_RESET is not set
385# CONFIG_SIS900 is not set
386# CONFIG_EPIC100 is not set
387# CONFIG_SUNDANCE is not set
388# CONFIG_TLAN is not set
389# CONFIG_VIA_RHINE is not set
390
391#
392# Ethernet (1000 Mbit)
393#
394# CONFIG_ACENIC is not set
395# CONFIG_DL2K is not set
396# CONFIG_E1000 is not set
397# CONFIG_NS83820 is not set
398# CONFIG_HAMACHI is not set
399# CONFIG_YELLOWFIN is not set
400# CONFIG_R8169 is not set
401# CONFIG_SK98LIN is not set
402# CONFIG_VIA_VELOCITY is not set
403# CONFIG_TIGON3 is not set
404
405#
406# Ethernet (10000 Mbit)
407#
408# CONFIG_IXGB is not set
409# CONFIG_S2IO is not set
410
411#
412# Token Ring devices
413#
414# CONFIG_TR is not set
415
416#
417# Wireless LAN (non-hamradio)
418#
419# CONFIG_NET_RADIO is not set
420
421#
422# Wan interfaces
423#
424# CONFIG_WAN is not set
425# CONFIG_FDDI is not set
426# CONFIG_HIPPI is not set
427# CONFIG_PPP is not set
428# CONFIG_SLIP is not set
429# CONFIG_SHAPER is not set
430# CONFIG_NETCONSOLE is not set
431
432#
433# ISDN subsystem
434#
435# CONFIG_ISDN is not set
436
437#
438# Telephony Support
439#
440# CONFIG_PHONE is not set
441
442#
443# Input device support
444#
445CONFIG_INPUT=y
446
447#
448# Userland interfaces
449#
450CONFIG_INPUT_MOUSEDEV=y
451CONFIG_INPUT_MOUSEDEV_PSAUX=y
452CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
453CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
454# CONFIG_INPUT_JOYDEV is not set
455# CONFIG_INPUT_TSDEV is not set
456# CONFIG_INPUT_EVDEV is not set
457# CONFIG_INPUT_EVBUG is not set
458
459#
460# Input I/O drivers
461#
462# CONFIG_GAMEPORT is not set
463CONFIG_SOUND_GAMEPORT=y
464CONFIG_SERIO=y
465# CONFIG_SERIO_I8042 is not set
466# CONFIG_SERIO_SERPORT is not set
467# CONFIG_SERIO_CT82C710 is not set
468# CONFIG_SERIO_PCIPS2 is not set
469CONFIG_SERIO_LIBPS2=y
470# CONFIG_SERIO_RAW is not set
471
472#
473# Input Device Drivers
474#
475CONFIG_INPUT_KEYBOARD=y
476CONFIG_KEYBOARD_ATKBD=y
477# CONFIG_KEYBOARD_SUNKBD is not set
478# CONFIG_KEYBOARD_LKKBD is not set
479# CONFIG_KEYBOARD_XTKBD is not set
480# CONFIG_KEYBOARD_NEWTON is not set
481# CONFIG_KEYBOARD_MAPLE is not set
482CONFIG_INPUT_MOUSE=y
483CONFIG_MOUSE_PS2=y
484# CONFIG_MOUSE_SERIAL is not set
485# CONFIG_MOUSE_MAPLE is not set
486# CONFIG_MOUSE_VSXXXAA is not set
487# CONFIG_INPUT_JOYSTICK is not set
488# CONFIG_INPUT_TOUCHSCREEN is not set
489# CONFIG_INPUT_MISC is not set
490
491#
492# Character devices
493#
494CONFIG_VT=y
495CONFIG_VT_CONSOLE=y
496CONFIG_HW_CONSOLE=y
497# CONFIG_SERIAL_NONSTANDARD is not set
498
499#
500# Serial drivers
501#
502# CONFIG_SERIAL_8250 is not set
503
504#
505# Non-8250 serial port support
506#
507CONFIG_SERIAL_SH_SCI=y
508CONFIG_SERIAL_SH_SCI_CONSOLE=y
509CONFIG_SERIAL_CORE=y
510CONFIG_SERIAL_CORE_CONSOLE=y
511CONFIG_UNIX98_PTYS=y
512CONFIG_LEGACY_PTYS=y
513CONFIG_LEGACY_PTY_COUNT=256
514
515#
516# IPMI
517#
518# CONFIG_IPMI_HANDLER is not set
519
520#
521# Watchdog Cards
522#
523CONFIG_WATCHDOG=y
524# CONFIG_WATCHDOG_NOWAYOUT is not set
525
526#
527# Watchdog Device Drivers
528#
529# CONFIG_SOFT_WATCHDOG is not set
530CONFIG_SH_WDT=y
531
532#
533# PCI-based Watchdog Cards
534#
535# CONFIG_PCIPCWATCHDOG is not set
536# CONFIG_WDTPCI is not set
537# CONFIG_RTC is not set
538# CONFIG_GEN_RTC is not set
539# CONFIG_DTLK is not set
540# CONFIG_R3964 is not set
541# CONFIG_APPLICOM is not set
542
543#
544# Ftape, the floppy tape device driver
545#
546# CONFIG_DRM is not set
547# CONFIG_RAW_DRIVER is not set
548
549#
550# I2C support
551#
552# CONFIG_I2C is not set
553
554#
555# Dallas's 1-wire bus
556#
557# CONFIG_W1 is not set
558
559#
560# Misc devices
561#
562
563#
564# Multimedia devices
565#
566# CONFIG_VIDEO_DEV is not set
567
568#
569# Digital Video Broadcasting Devices
570#
571# CONFIG_DVB is not set
572
573#
574# Graphics support
575#
576CONFIG_FB=y
577# CONFIG_FB_MODE_HELPERS is not set
578# CONFIG_FB_TILEBLITTING is not set
579# CONFIG_FB_CIRRUS is not set
580# CONFIG_FB_PM2 is not set
581# CONFIG_FB_CYBER2000 is not set
582# CONFIG_FB_ASILIANT is not set
583# CONFIG_FB_IMSTT is not set
584CONFIG_FB_PVR2=y
585# CONFIG_FB_EPSON1355 is not set
586# CONFIG_FB_RIVA is not set
587# CONFIG_FB_MATROX is not set
588# CONFIG_FB_RADEON_OLD is not set
589# CONFIG_FB_RADEON is not set
590# CONFIG_FB_ATY128 is not set
591# CONFIG_FB_ATY is not set
592# CONFIG_FB_SAVAGE is not set
593# CONFIG_FB_SIS is not set
594# CONFIG_FB_NEOMAGIC is not set
595# CONFIG_FB_KYRO is not set
596# CONFIG_FB_3DFX is not set
597# CONFIG_FB_VOODOO1 is not set
598# CONFIG_FB_TRIDENT is not set
599# CONFIG_FB_VIRTUAL is not set
600
601#
602# Console display driver support
603#
604# CONFIG_VGA_CONSOLE is not set
605CONFIG_DUMMY_CONSOLE=y
606CONFIG_FRAMEBUFFER_CONSOLE=y
607CONFIG_FONTS=y
608CONFIG_FONT_8x8=y
609CONFIG_FONT_8x16=y
610# CONFIG_FONT_6x11 is not set
611# CONFIG_FONT_PEARL_8x8 is not set
612# CONFIG_FONT_ACORN_8x8 is not set
613# CONFIG_FONT_MINI_4x6 is not set
614# CONFIG_FONT_SUN8x16 is not set
615# CONFIG_FONT_SUN12x22 is not set
616
617#
618# Logo configuration
619#
620CONFIG_LOGO=y
621# CONFIG_LOGO_LINUX_MONO is not set
622# CONFIG_LOGO_LINUX_VGA16 is not set
623# CONFIG_LOGO_LINUX_CLUT224 is not set
624# CONFIG_LOGO_SUPERH_MONO is not set
625# CONFIG_LOGO_SUPERH_VGA16 is not set
626CONFIG_LOGO_SUPERH_CLUT224=y
627# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
628
629#
630# Sound
631#
632# CONFIG_SOUND is not set
633
634#
635# USB support
636#
637# CONFIG_USB is not set
638CONFIG_USB_ARCH_HAS_HCD=y
639CONFIG_USB_ARCH_HAS_OHCI=y
640
641#
642# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
643#
644
645#
646# USB Gadget Support
647#
648# CONFIG_USB_GADGET is not set
649
650#
651# MMC/SD Card support
652#
653# CONFIG_MMC is not set
654
655#
656# InfiniBand support
657#
658# CONFIG_INFINIBAND is not set
659
660#
661# File systems
662#
663# CONFIG_EXT2_FS is not set
664# CONFIG_EXT3_FS is not set
665# CONFIG_JBD is not set
666# CONFIG_REISERFS_FS is not set
667# CONFIG_JFS_FS is not set
668
669#
670# XFS support
671#
672# CONFIG_XFS_FS is not set
673# CONFIG_MINIX_FS is not set
674CONFIG_ROMFS_FS=y
675# CONFIG_QUOTA is not set
676CONFIG_DNOTIFY=y
677# CONFIG_AUTOFS_FS is not set
678# CONFIG_AUTOFS4_FS is not set
679
680#
681# CD-ROM/DVD Filesystems
682#
683# CONFIG_ISO9660_FS is not set
684# CONFIG_UDF_FS is not set
685
686#
687# DOS/FAT/NT Filesystems
688#
689# CONFIG_MSDOS_FS is not set
690# CONFIG_VFAT_FS is not set
691# CONFIG_NTFS_FS is not set
692
693#
694# Pseudo filesystems
695#
696CONFIG_PROC_FS=y
697CONFIG_PROC_KCORE=y
698CONFIG_SYSFS=y
699CONFIG_DEVFS_FS=y
700CONFIG_DEVFS_MOUNT=y
701# CONFIG_DEVFS_DEBUG is not set
702# CONFIG_DEVPTS_FS_XATTR is not set
703CONFIG_TMPFS=y
704# CONFIG_TMPFS_XATTR is not set
705CONFIG_HUGETLBFS=y
706CONFIG_HUGETLB_PAGE=y
707CONFIG_RAMFS=y
708
709#
710# Miscellaneous filesystems
711#
712# CONFIG_ADFS_FS is not set
713# CONFIG_AFFS_FS is not set
714# CONFIG_HFS_FS is not set
715# CONFIG_HFSPLUS_FS is not set
716# CONFIG_BEFS_FS is not set
717# CONFIG_BFS_FS is not set
718# CONFIG_EFS_FS is not set
719CONFIG_CRAMFS=y
720# CONFIG_VXFS_FS is not set
721# CONFIG_HPFS_FS is not set
722# CONFIG_QNX4FS_FS is not set
723# CONFIG_SYSV_FS is not set
724# CONFIG_UFS_FS is not set
725
726#
727# Network File Systems
728#
729CONFIG_NFS_FS=y
730CONFIG_NFS_V3=y
731# CONFIG_NFS_V4 is not set
732# CONFIG_NFS_DIRECTIO is not set
733# CONFIG_NFSD is not set
734CONFIG_ROOT_NFS=y
735CONFIG_LOCKD=y
736CONFIG_LOCKD_V4=y
737CONFIG_SUNRPC=y
738# CONFIG_RPCSEC_GSS_KRB5 is not set
739# CONFIG_RPCSEC_GSS_SPKM3 is not set
740# CONFIG_SMB_FS is not set
741# CONFIG_CIFS is not set
742# CONFIG_NCP_FS is not set
743# CONFIG_CODA_FS is not set
744# CONFIG_AFS_FS is not set
745
746#
747# Partition Types
748#
749# CONFIG_PARTITION_ADVANCED is not set
750CONFIG_MSDOS_PARTITION=y
751
752#
753# Native Language Support
754#
755# CONFIG_NLS is not set
756
757#
758# Profiling support
759#
760CONFIG_PROFILING=y
761CONFIG_OPROFILE=y
762
763#
764# Kernel hacking
765#
766# CONFIG_DEBUG_KERNEL is not set
767CONFIG_DEBUG_PREEMPT=y
768# CONFIG_FRAME_POINTER is not set
769# CONFIG_SH_STANDARD_BIOS is not set
770# CONFIG_EARLY_SCIF_CONSOLE is not set
771# CONFIG_KGDB is not set
772
773#
774# Security options
775#
776# CONFIG_KEYS is not set
777# CONFIG_SECURITY is not set
778
779#
780# Cryptographic options
781#
782# CONFIG_CRYPTO is not set
783
784#
785# Hardware crypto devices
786#
787
788#
789# Library routines
790#
791# CONFIG_CRC_CCITT is not set
792CONFIG_CRC32=y
793# CONFIG_LIBCRC32C is not set
794CONFIG_ZLIB_INFLATE=y
diff --git a/arch/sh/configs/hp680_defconfig b/arch/sh/configs/hp680_defconfig
new file mode 100644
index 000000000000..c85d3655b53c
--- /dev/null
+++ b/arch/sh/configs/hp680_defconfig
@@ -0,0 +1,554 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:41 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17# CONFIG_CLEAN_COMPILE is not set
18CONFIG_BROKEN=y
19CONFIG_BROKEN_ON_SMP=y
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25CONFIG_SWAP=y
26# CONFIG_SYSVIPC is not set
27# CONFIG_BSD_PROCESS_ACCT is not set
28# CONFIG_SYSCTL is not set
29# CONFIG_AUDIT is not set
30CONFIG_LOG_BUF_SHIFT=14
31# CONFIG_HOTPLUG is not set
32# CONFIG_IKCONFIG is not set
33# CONFIG_EMBEDDED is not set
34CONFIG_KALLSYMS=y
35# CONFIG_KALLSYMS_EXTRA_PASS is not set
36CONFIG_FUTEX=y
37CONFIG_EPOLL=y
38# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
39CONFIG_SHMEM=y
40CONFIG_CC_ALIGN_FUNCTIONS=0
41CONFIG_CC_ALIGN_LABELS=0
42CONFIG_CC_ALIGN_LOOPS=0
43CONFIG_CC_ALIGN_JUMPS=0
44# CONFIG_TINY_SHMEM is not set
45
46#
47# Loadable module support
48#
49# CONFIG_MODULES is not set
50
51#
52# System type
53#
54# CONFIG_SH_SOLUTION_ENGINE is not set
55# CONFIG_SH_7751_SOLUTION_ENGINE is not set
56# CONFIG_SH_7300_SOLUTION_ENGINE is not set
57# CONFIG_SH_73180_SOLUTION_ENGINE is not set
58# CONFIG_SH_7751_SYSTEMH is not set
59# CONFIG_SH_STB1_HARP is not set
60# CONFIG_SH_STB1_OVERDRIVE is not set
61# CONFIG_SH_HP620 is not set
62CONFIG_SH_HP680=y
63# CONFIG_SH_HP690 is not set
64# CONFIG_SH_CQREEK is not set
65# CONFIG_SH_DMIDA is not set
66# CONFIG_SH_EC3104 is not set
67# CONFIG_SH_SATURN is not set
68# CONFIG_SH_DREAMCAST is not set
69# CONFIG_SH_CAT68701 is not set
70# CONFIG_SH_BIGSUR is not set
71# CONFIG_SH_SH2000 is not set
72# CONFIG_SH_ADX is not set
73# CONFIG_SH_MPC1211 is not set
74# CONFIG_SH_SH03 is not set
75# CONFIG_SH_SECUREEDGE5410 is not set
76# CONFIG_SH_HS7751RVOIP is not set
77# CONFIG_SH_RTS7751R2D is not set
78# CONFIG_SH_EDOSK7705 is not set
79# CONFIG_SH_SH4202_MICRODEV is not set
80# CONFIG_SH_UNKNOWN is not set
81# CONFIG_CPU_SH2 is not set
82CONFIG_CPU_SH3=y
83# CONFIG_CPU_SH4 is not set
84# CONFIG_CPU_SUBTYPE_SH7604 is not set
85# CONFIG_CPU_SUBTYPE_SH7300 is not set
86# CONFIG_CPU_SUBTYPE_SH7705 is not set
87# CONFIG_CPU_SUBTYPE_SH7707 is not set
88# CONFIG_CPU_SUBTYPE_SH7708 is not set
89CONFIG_CPU_SUBTYPE_SH7709=y
90# CONFIG_CPU_SUBTYPE_SH7750 is not set
91# CONFIG_CPU_SUBTYPE_SH7751 is not set
92# CONFIG_CPU_SUBTYPE_SH7760 is not set
93# CONFIG_CPU_SUBTYPE_SH73180 is not set
94# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
95# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
96# CONFIG_CPU_SUBTYPE_SH4_202 is not set
97CONFIG_MMU=y
98# CONFIG_CMDLINE_BOOL is not set
99CONFIG_MEMORY_START=0x0c000000
100CONFIG_MEMORY_SIZE=0x00400000
101CONFIG_MEMORY_SET=y
102# CONFIG_MEMORY_OVERRIDE is not set
103CONFIG_SH_RTC=y
104# CONFIG_SH_DSP is not set
105CONFIG_SH_ADC=y
106CONFIG_SH_HP600=y
107CONFIG_ZERO_PAGE_OFFSET=0x00001000
108CONFIG_BOOT_LINK_OFFSET=0x00800000
109CONFIG_CPU_LITTLE_ENDIAN=y
110# CONFIG_PREEMPT is not set
111# CONFIG_UBC_WAKEUP is not set
112# CONFIG_SH_WRITETHROUGH is not set
113# CONFIG_SH_OCRAM is not set
114# CONFIG_SMP is not set
115CONFIG_SH_PCLK_CALC=y
116CONFIG_SH_PCLK_FREQ=1193182
117
118#
119# CPU Frequency scaling
120#
121# CONFIG_CPU_FREQ is not set
122
123#
124# DMA support
125#
126# CONFIG_SH_DMA is not set
127
128#
129# Companion Chips
130#
131CONFIG_HD6446X_SERIES=y
132CONFIG_HD64461=y
133# CONFIG_HD64465 is not set
134CONFIG_HD64461_IRQ=36
135# CONFIG_HD64461_ENABLER is not set
136
137#
138# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
139#
140# CONFIG_PCI is not set
141
142#
143# PCCARD (PCMCIA/CardBus) support
144#
145# CONFIG_PCCARD is not set
146
147#
148# PC-card bridges
149#
150
151#
152# PCI Hotplug Support
153#
154
155#
156# Executable file formats
157#
158CONFIG_BINFMT_ELF=y
159# CONFIG_BINFMT_FLAT is not set
160# CONFIG_BINFMT_MISC is not set
161
162#
163# SH initrd options
164#
165# CONFIG_EMBEDDED_RAMDISK is not set
166
167#
168# Device Drivers
169#
170
171#
172# Generic Driver Options
173#
174# CONFIG_STANDALONE is not set
175CONFIG_PREVENT_FIRMWARE_BUILD=y
176# CONFIG_FW_LOADER is not set
177
178#
179# Memory Technology Devices (MTD)
180#
181# CONFIG_MTD is not set
182
183#
184# Parallel port support
185#
186# CONFIG_PARPORT is not set
187
188#
189# Plug and Play support
190#
191
192#
193# Block devices
194#
195# CONFIG_BLK_DEV_FD is not set
196# CONFIG_BLK_DEV_COW_COMMON is not set
197# CONFIG_BLK_DEV_LOOP is not set
198CONFIG_BLK_DEV_RAM=y
199CONFIG_BLK_DEV_RAM_COUNT=16
200CONFIG_BLK_DEV_RAM_SIZE=4096
201CONFIG_BLK_DEV_INITRD=y
202CONFIG_INITRAMFS_SOURCE=""
203# CONFIG_LBD is not set
204# CONFIG_CDROM_PKTCDVD is not set
205
206#
207# IO Schedulers
208#
209CONFIG_IOSCHED_NOOP=y
210CONFIG_IOSCHED_AS=y
211CONFIG_IOSCHED_DEADLINE=y
212CONFIG_IOSCHED_CFQ=y
213
214#
215# ATA/ATAPI/MFM/RLL support
216#
217CONFIG_IDE=y
218CONFIG_IDE_MAX_HWIFS=4
219CONFIG_BLK_DEV_IDE=y
220
221#
222# Please see Documentation/ide.txt for help/info on IDE drives
223#
224# CONFIG_BLK_DEV_IDE_SATA is not set
225CONFIG_BLK_DEV_IDEDISK=y
226# CONFIG_IDEDISK_MULTI_MODE is not set
227# CONFIG_BLK_DEV_IDECD is not set
228# CONFIG_BLK_DEV_IDETAPE is not set
229# CONFIG_BLK_DEV_IDEFLOPPY is not set
230# CONFIG_IDE_TASK_IOCTL is not set
231
232#
233# IDE chipset support/bugfixes
234#
235CONFIG_IDE_GENERIC=y
236CONFIG_IDE_SH=y
237# CONFIG_IDE_ARM is not set
238# CONFIG_BLK_DEV_IDEDMA is not set
239# CONFIG_IDEDMA_AUTO is not set
240# CONFIG_BLK_DEV_HD is not set
241
242#
243# SCSI device support
244#
245# CONFIG_SCSI is not set
246
247#
248# Multi-device support (RAID and LVM)
249#
250# CONFIG_MD is not set
251
252#
253# Fusion MPT device support
254#
255
256#
257# IEEE 1394 (FireWire) support
258#
259# CONFIG_IEEE1394 is not set
260
261#
262# I2O device support
263#
264
265#
266# Networking support
267#
268# CONFIG_NET is not set
269# CONFIG_NETPOLL is not set
270# CONFIG_NET_POLL_CONTROLLER is not set
271
272#
273# ISDN subsystem
274#
275
276#
277# Telephony Support
278#
279# CONFIG_PHONE is not set
280
281#
282# Input device support
283#
284CONFIG_INPUT=y
285
286#
287# Userland interfaces
288#
289CONFIG_INPUT_MOUSEDEV=y
290CONFIG_INPUT_MOUSEDEV_PSAUX=y
291CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
292CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
293# CONFIG_INPUT_JOYDEV is not set
294# CONFIG_INPUT_TSDEV is not set
295# CONFIG_INPUT_EVDEV is not set
296# CONFIG_INPUT_EVBUG is not set
297
298#
299# Input I/O drivers
300#
301# CONFIG_GAMEPORT is not set
302CONFIG_SOUND_GAMEPORT=y
303CONFIG_SERIO=y
304# CONFIG_SERIO_I8042 is not set
305# CONFIG_SERIO_SERPORT is not set
306# CONFIG_SERIO_CT82C710 is not set
307# CONFIG_SERIO_RAW is not set
308
309#
310# Input Device Drivers
311#
312# CONFIG_INPUT_KEYBOARD is not set
313# CONFIG_INPUT_MOUSE is not set
314# CONFIG_INPUT_JOYSTICK is not set
315# CONFIG_INPUT_TOUCHSCREEN is not set
316# CONFIG_INPUT_MISC is not set
317
318#
319# Character devices
320#
321CONFIG_VT=y
322CONFIG_VT_CONSOLE=y
323CONFIG_HW_CONSOLE=y
324# CONFIG_SERIAL_NONSTANDARD is not set
325
326#
327# Serial drivers
328#
329# CONFIG_SERIAL_8250 is not set
330
331#
332# Non-8250 serial port support
333#
334# CONFIG_SERIAL_SH_SCI is not set
335CONFIG_UNIX98_PTYS=y
336CONFIG_LEGACY_PTYS=y
337CONFIG_LEGACY_PTY_COUNT=256
338
339#
340# IPMI
341#
342# CONFIG_IPMI_HANDLER is not set
343
344#
345# Watchdog Cards
346#
347# CONFIG_WATCHDOG is not set
348# CONFIG_RTC is not set
349# CONFIG_GEN_RTC is not set
350# CONFIG_DTLK is not set
351# CONFIG_R3964 is not set
352
353#
354# Ftape, the floppy tape device driver
355#
356# CONFIG_DRM is not set
357# CONFIG_RAW_DRIVER is not set
358
359#
360# I2C support
361#
362# CONFIG_I2C is not set
363
364#
365# Dallas's 1-wire bus
366#
367# CONFIG_W1 is not set
368
369#
370# Misc devices
371#
372
373#
374# Multimedia devices
375#
376# CONFIG_VIDEO_DEV is not set
377
378#
379# Digital Video Broadcasting Devices
380#
381
382#
383# Graphics support
384#
385CONFIG_FB=y
386# CONFIG_FB_MODE_HELPERS is not set
387# CONFIG_FB_TILEBLITTING is not set
388# CONFIG_FB_EPSON1355 is not set
389CONFIG_FB_HIT=y
390# CONFIG_FB_VIRTUAL is not set
391
392#
393# Console display driver support
394#
395# CONFIG_VGA_CONSOLE is not set
396CONFIG_DUMMY_CONSOLE=y
397CONFIG_FRAMEBUFFER_CONSOLE=y
398CONFIG_FONTS=y
399# CONFIG_FONT_8x8 is not set
400# CONFIG_FONT_8x16 is not set
401# CONFIG_FONT_6x11 is not set
402CONFIG_FONT_PEARL_8x8=y
403# CONFIG_FONT_ACORN_8x8 is not set
404# CONFIG_FONT_MINI_4x6 is not set
405# CONFIG_FONT_SUN8x16 is not set
406# CONFIG_FONT_SUN12x22 is not set
407
408#
409# Logo configuration
410#
411# CONFIG_LOGO is not set
412# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
413
414#
415# Sound
416#
417# CONFIG_SOUND is not set
418
419#
420# USB support
421#
422# CONFIG_USB_ARCH_HAS_HCD is not set
423# CONFIG_USB_ARCH_HAS_OHCI is not set
424
425#
426# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
427#
428
429#
430# USB Gadget Support
431#
432# CONFIG_USB_GADGET is not set
433
434#
435# MMC/SD Card support
436#
437# CONFIG_MMC is not set
438
439#
440# InfiniBand support
441#
442# CONFIG_INFINIBAND is not set
443
444#
445# File systems
446#
447CONFIG_EXT2_FS=y
448# CONFIG_EXT2_FS_XATTR is not set
449# CONFIG_EXT3_FS is not set
450# CONFIG_JBD is not set
451# CONFIG_REISERFS_FS is not set
452# CONFIG_JFS_FS is not set
453
454#
455# XFS support
456#
457# CONFIG_XFS_FS is not set
458# CONFIG_MINIX_FS is not set
459# CONFIG_ROMFS_FS is not set
460# CONFIG_QUOTA is not set
461CONFIG_DNOTIFY=y
462# CONFIG_AUTOFS_FS is not set
463# CONFIG_AUTOFS4_FS is not set
464
465#
466# CD-ROM/DVD Filesystems
467#
468# CONFIG_ISO9660_FS is not set
469# CONFIG_UDF_FS is not set
470
471#
472# DOS/FAT/NT Filesystems
473#
474# CONFIG_MSDOS_FS is not set
475# CONFIG_VFAT_FS is not set
476# CONFIG_NTFS_FS is not set
477
478#
479# Pseudo filesystems
480#
481CONFIG_PROC_FS=y
482CONFIG_PROC_KCORE=y
483CONFIG_SYSFS=y
484CONFIG_DEVFS_FS=y
485CONFIG_DEVFS_MOUNT=y
486# CONFIG_DEVFS_DEBUG is not set
487# CONFIG_DEVPTS_FS_XATTR is not set
488# CONFIG_TMPFS is not set
489# CONFIG_HUGETLBFS is not set
490# CONFIG_HUGETLB_PAGE is not set
491CONFIG_RAMFS=y
492
493#
494# Miscellaneous filesystems
495#
496# CONFIG_ADFS_FS is not set
497# CONFIG_AFFS_FS is not set
498# CONFIG_HFS_FS is not set
499# CONFIG_HFSPLUS_FS is not set
500# CONFIG_BEFS_FS is not set
501# CONFIG_BFS_FS is not set
502# CONFIG_EFS_FS is not set
503# CONFIG_CRAMFS is not set
504# CONFIG_VXFS_FS is not set
505# CONFIG_HPFS_FS is not set
506# CONFIG_QNX4FS_FS is not set
507# CONFIG_SYSV_FS is not set
508# CONFIG_UFS_FS is not set
509
510#
511# Partition Types
512#
513# CONFIG_PARTITION_ADVANCED is not set
514CONFIG_MSDOS_PARTITION=y
515
516#
517# Native Language Support
518#
519# CONFIG_NLS is not set
520
521#
522# Profiling support
523#
524# CONFIG_PROFILING is not set
525
526#
527# Kernel hacking
528#
529# CONFIG_DEBUG_KERNEL is not set
530# CONFIG_FRAME_POINTER is not set
531# CONFIG_SH_STANDARD_BIOS is not set
532# CONFIG_KGDB is not set
533
534#
535# Security options
536#
537# CONFIG_KEYS is not set
538# CONFIG_SECURITY is not set
539
540#
541# Cryptographic options
542#
543# CONFIG_CRYPTO is not set
544
545#
546# Hardware crypto devices
547#
548
549#
550# Library routines
551#
552# CONFIG_CRC_CCITT is not set
553CONFIG_CRC32=y
554# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
new file mode 100644
index 000000000000..a3bd280b53d6
--- /dev/null
+++ b/arch/sh/configs/microdev_defconfig
@@ -0,0 +1,734 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:41 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19CONFIG_LOCK_KERNEL=y
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25CONFIG_SWAP=y
26# CONFIG_SYSVIPC is not set
27# CONFIG_POSIX_MQUEUE is not set
28CONFIG_BSD_PROCESS_ACCT=y
29# CONFIG_BSD_PROCESS_ACCT_V3 is not set
30CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set
32CONFIG_LOG_BUF_SHIFT=14
33CONFIG_HOTPLUG=y
34CONFIG_KOBJECT_UEVENT=y
35# CONFIG_IKCONFIG is not set
36CONFIG_EMBEDDED=y
37CONFIG_KALLSYMS=y
38# CONFIG_KALLSYMS_EXTRA_PASS is not set
39CONFIG_FUTEX=y
40CONFIG_EPOLL=y
41# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
42CONFIG_SHMEM=y
43CONFIG_CC_ALIGN_FUNCTIONS=0
44CONFIG_CC_ALIGN_LABELS=0
45CONFIG_CC_ALIGN_LOOPS=0
46CONFIG_CC_ALIGN_JUMPS=0
47# CONFIG_TINY_SHMEM is not set
48
49#
50# Loadable module support
51#
52# CONFIG_MODULES is not set
53
54#
55# System type
56#
57# CONFIG_SH_SOLUTION_ENGINE is not set
58# CONFIG_SH_7751_SOLUTION_ENGINE is not set
59# CONFIG_SH_7300_SOLUTION_ENGINE is not set
60# CONFIG_SH_73180_SOLUTION_ENGINE is not set
61# CONFIG_SH_7751_SYSTEMH is not set
62# CONFIG_SH_STB1_HARP is not set
63# CONFIG_SH_STB1_OVERDRIVE is not set
64# CONFIG_SH_HP620 is not set
65# CONFIG_SH_HP680 is not set
66# CONFIG_SH_HP690 is not set
67# CONFIG_SH_CQREEK is not set
68# CONFIG_SH_DMIDA is not set
69# CONFIG_SH_EC3104 is not set
70# CONFIG_SH_SATURN is not set
71# CONFIG_SH_DREAMCAST is not set
72# CONFIG_SH_CAT68701 is not set
73# CONFIG_SH_BIGSUR is not set
74# CONFIG_SH_SH2000 is not set
75# CONFIG_SH_ADX is not set
76# CONFIG_SH_MPC1211 is not set
77# CONFIG_SH_SH03 is not set
78# CONFIG_SH_SECUREEDGE5410 is not set
79# CONFIG_SH_HS7751RVOIP is not set
80# CONFIG_SH_RTS7751R2D is not set
81# CONFIG_SH_EDOSK7705 is not set
82CONFIG_SH_SH4202_MICRODEV=y
83# CONFIG_SH_UNKNOWN is not set
84# CONFIG_CPU_SH2 is not set
85# CONFIG_CPU_SH3 is not set
86CONFIG_CPU_SH4=y
87# CONFIG_CPU_SUBTYPE_SH7604 is not set
88# CONFIG_CPU_SUBTYPE_SH7300 is not set
89# CONFIG_CPU_SUBTYPE_SH7705 is not set
90# CONFIG_CPU_SUBTYPE_SH7707 is not set
91# CONFIG_CPU_SUBTYPE_SH7708 is not set
92# CONFIG_CPU_SUBTYPE_SH7709 is not set
93# CONFIG_CPU_SUBTYPE_SH7750 is not set
94# CONFIG_CPU_SUBTYPE_SH7751 is not set
95# CONFIG_CPU_SUBTYPE_SH7760 is not set
96# CONFIG_CPU_SUBTYPE_SH73180 is not set
97# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
98# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
99CONFIG_CPU_SUBTYPE_SH4_202=y
100CONFIG_MMU=y
101CONFIG_CMDLINE_BOOL=y
102CONFIG_CMDLINE="console=ttySC0,115200"
103CONFIG_MEMORY_START=0x08000000
104CONFIG_MEMORY_SIZE=0x04000000
105CONFIG_MEMORY_SET=y
106# CONFIG_MEMORY_OVERRIDE is not set
107CONFIG_SH_RTC=y
108CONFIG_SH_FPU=y
109CONFIG_ZERO_PAGE_OFFSET=0x00001000
110CONFIG_BOOT_LINK_OFFSET=0x00800000
111CONFIG_CPU_LITTLE_ENDIAN=y
112CONFIG_PREEMPT=y
113# CONFIG_UBC_WAKEUP is not set
114# CONFIG_SH_WRITETHROUGH is not set
115# CONFIG_SH_OCRAM is not set
116# CONFIG_SH_STORE_QUEUES is not set
117# CONFIG_SMP is not set
118CONFIG_SH_PCLK_CALC=y
119CONFIG_SH_PCLK_FREQ=65986048
120
121#
122# CPU Frequency scaling
123#
124# CONFIG_CPU_FREQ is not set
125
126#
127# DMA support
128#
129CONFIG_SH_DMA=y
130CONFIG_NR_ONCHIP_DMA_CHANNELS=4
131# CONFIG_NR_DMA_CHANNELS_BOOL is not set
132
133#
134# Companion Chips
135#
136# CONFIG_HD6446X_SERIES is not set
137CONFIG_HEARTBEAT=y
138
139#
140# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
141#
142CONFIG_ISA=y
143# CONFIG_PCI is not set
144
145#
146# PCCARD (PCMCIA/CardBus) support
147#
148# CONFIG_PCCARD is not set
149
150#
151# PC-card bridges
152#
153CONFIG_PCMCIA_PROBE=y
154
155#
156# PCI Hotplug Support
157#
158
159#
160# Executable file formats
161#
162CONFIG_BINFMT_ELF=y
163# CONFIG_BINFMT_FLAT is not set
164# CONFIG_BINFMT_MISC is not set
165
166#
167# SH initrd options
168#
169# CONFIG_EMBEDDED_RAMDISK is not set
170
171#
172# Device Drivers
173#
174
175#
176# Generic Driver Options
177#
178CONFIG_STANDALONE=y
179CONFIG_PREVENT_FIRMWARE_BUILD=y
180# CONFIG_FW_LOADER is not set
181
182#
183# Memory Technology Devices (MTD)
184#
185# CONFIG_MTD is not set
186
187#
188# Parallel port support
189#
190# CONFIG_PARPORT is not set
191
192#
193# Plug and Play support
194#
195# CONFIG_PNP is not set
196
197#
198# Block devices
199#
200# CONFIG_BLK_DEV_FD is not set
201# CONFIG_BLK_DEV_XD is not set
202# CONFIG_BLK_DEV_COW_COMMON is not set
203# CONFIG_BLK_DEV_LOOP is not set
204# CONFIG_BLK_DEV_NBD is not set
205CONFIG_BLK_DEV_RAM=y
206CONFIG_BLK_DEV_RAM_COUNT=16
207CONFIG_BLK_DEV_RAM_SIZE=4096
208CONFIG_BLK_DEV_INITRD=y
209CONFIG_INITRAMFS_SOURCE=""
210# CONFIG_LBD is not set
211# CONFIG_CDROM_PKTCDVD is not set
212
213#
214# IO Schedulers
215#
216CONFIG_IOSCHED_NOOP=y
217CONFIG_IOSCHED_AS=y
218CONFIG_IOSCHED_DEADLINE=y
219CONFIG_IOSCHED_CFQ=y
220# CONFIG_ATA_OVER_ETH is not set
221
222#
223# ATA/ATAPI/MFM/RLL support
224#
225CONFIG_IDE=y
226CONFIG_IDE_MAX_HWIFS=1
227CONFIG_BLK_DEV_IDE=y
228
229#
230# Please see Documentation/ide.txt for help/info on IDE drives
231#
232# CONFIG_BLK_DEV_IDE_SATA is not set
233CONFIG_BLK_DEV_IDEDISK=y
234# CONFIG_IDEDISK_MULTI_MODE is not set
235CONFIG_BLK_DEV_IDECD=y
236# CONFIG_BLK_DEV_IDETAPE is not set
237# CONFIG_BLK_DEV_IDEFLOPPY is not set
238# CONFIG_IDE_TASK_IOCTL is not set
239
240#
241# IDE chipset support/bugfixes
242#
243CONFIG_IDE_GENERIC=y
244CONFIG_IDE_SH=y
245# CONFIG_IDE_ARM is not set
246# CONFIG_IDE_CHIPSETS is not set
247# CONFIG_BLK_DEV_IDEDMA is not set
248# CONFIG_IDEDMA_AUTO is not set
249# CONFIG_BLK_DEV_HD is not set
250
251#
252# SCSI device support
253#
254# CONFIG_SCSI is not set
255
256#
257# Old CD-ROM drivers (not SCSI, not IDE)
258#
259# CONFIG_CD_NO_IDESCSI is not set
260
261#
262# Multi-device support (RAID and LVM)
263#
264# CONFIG_MD is not set
265
266#
267# Fusion MPT device support
268#
269
270#
271# IEEE 1394 (FireWire) support
272#
273
274#
275# I2O device support
276#
277
278#
279# Networking support
280#
281CONFIG_NET=y
282
283#
284# Networking options
285#
286# CONFIG_PACKET is not set
287# CONFIG_NETLINK_DEV is not set
288# CONFIG_UNIX is not set
289# CONFIG_NET_KEY is not set
290CONFIG_INET=y
291# CONFIG_IP_MULTICAST is not set
292# CONFIG_IP_ADVANCED_ROUTER is not set
293CONFIG_IP_PNP=y
294CONFIG_IP_PNP_DHCP=y
295# CONFIG_IP_PNP_BOOTP is not set
296# CONFIG_IP_PNP_RARP is not set
297# CONFIG_NET_IPIP is not set
298# CONFIG_NET_IPGRE is not set
299# CONFIG_ARPD is not set
300# CONFIG_SYN_COOKIES is not set
301# CONFIG_INET_AH is not set
302# CONFIG_INET_ESP is not set
303# CONFIG_INET_IPCOMP is not set
304# CONFIG_INET_TUNNEL is not set
305CONFIG_IP_TCPDIAG=y
306# CONFIG_IP_TCPDIAG_IPV6 is not set
307# CONFIG_IPV6 is not set
308# CONFIG_NETFILTER is not set
309
310#
311# SCTP Configuration (EXPERIMENTAL)
312#
313# CONFIG_IP_SCTP is not set
314# CONFIG_ATM is not set
315# CONFIG_BRIDGE is not set
316# CONFIG_VLAN_8021Q is not set
317# CONFIG_DECNET is not set
318# CONFIG_LLC2 is not set
319# CONFIG_IPX is not set
320# CONFIG_ATALK is not set
321# CONFIG_X25 is not set
322# CONFIG_LAPB is not set
323# CONFIG_NET_DIVERT is not set
324# CONFIG_ECONET is not set
325# CONFIG_WAN_ROUTER is not set
326
327#
328# QoS and/or fair queueing
329#
330# CONFIG_NET_SCHED is not set
331# CONFIG_NET_CLS_ROUTE is not set
332
333#
334# Network testing
335#
336# CONFIG_NET_PKTGEN is not set
337# CONFIG_NETPOLL is not set
338# CONFIG_NET_POLL_CONTROLLER is not set
339# CONFIG_HAMRADIO is not set
340# CONFIG_IRDA is not set
341# CONFIG_BT is not set
342CONFIG_NETDEVICES=y
343# CONFIG_DUMMY is not set
344# CONFIG_BONDING is not set
345# CONFIG_EQUALIZER is not set
346# CONFIG_TUN is not set
347
348#
349# ARCnet devices
350#
351# CONFIG_ARCNET is not set
352
353#
354# Ethernet (10 or 100Mbit)
355#
356CONFIG_NET_ETHERNET=y
357CONFIG_MII=y
358# CONFIG_STNIC is not set
359# CONFIG_NET_VENDOR_3COM is not set
360# CONFIG_LANCE is not set
361# CONFIG_NET_VENDOR_SMC is not set
362CONFIG_SMC91X=y
363# CONFIG_NET_VENDOR_RACAL is not set
364# CONFIG_AT1700 is not set
365# CONFIG_DEPCA is not set
366# CONFIG_HP100 is not set
367# CONFIG_NET_ISA is not set
368# CONFIG_NET_PCI is not set
369# CONFIG_NET_POCKET is not set
370
371#
372# Ethernet (1000 Mbit)
373#
374
375#
376# Ethernet (10000 Mbit)
377#
378
379#
380# Token Ring devices
381#
382# CONFIG_TR is not set
383
384#
385# Wireless LAN (non-hamradio)
386#
387# CONFIG_NET_RADIO is not set
388
389#
390# Wan interfaces
391#
392# CONFIG_WAN is not set
393# CONFIG_PPP is not set
394# CONFIG_SLIP is not set
395# CONFIG_SHAPER is not set
396# CONFIG_NETCONSOLE is not set
397
398#
399# ISDN subsystem
400#
401# CONFIG_ISDN is not set
402
403#
404# Telephony Support
405#
406# CONFIG_PHONE is not set
407
408#
409# Input device support
410#
411# CONFIG_INPUT is not set
412
413#
414# Userland interfaces
415#
416
417#
418# Input I/O drivers
419#
420# CONFIG_GAMEPORT is not set
421CONFIG_SOUND_GAMEPORT=y
422# CONFIG_SERIO is not set
423# CONFIG_SERIO_I8042 is not set
424
425#
426# Input Device Drivers
427#
428
429#
430# Character devices
431#
432# CONFIG_VT is not set
433# CONFIG_SERIAL_NONSTANDARD is not set
434
435#
436# Serial drivers
437#
438# CONFIG_SERIAL_8250 is not set
439
440#
441# Non-8250 serial port support
442#
443CONFIG_SERIAL_SH_SCI=y
444CONFIG_SERIAL_SH_SCI_CONSOLE=y
445CONFIG_SERIAL_CORE=y
446CONFIG_SERIAL_CORE_CONSOLE=y
447CONFIG_UNIX98_PTYS=y
448CONFIG_LEGACY_PTYS=y
449CONFIG_LEGACY_PTY_COUNT=256
450
451#
452# IPMI
453#
454# CONFIG_IPMI_HANDLER is not set
455
456#
457# Watchdog Cards
458#
459# CONFIG_WATCHDOG is not set
460CONFIG_RTC=y
461# CONFIG_DTLK is not set
462# CONFIG_R3964 is not set
463
464#
465# Ftape, the floppy tape device driver
466#
467# CONFIG_DRM is not set
468# CONFIG_RAW_DRIVER is not set
469
470#
471# I2C support
472#
473# CONFIG_I2C is not set
474
475#
476# Dallas's 1-wire bus
477#
478# CONFIG_W1 is not set
479
480#
481# Misc devices
482#
483
484#
485# Multimedia devices
486#
487# CONFIG_VIDEO_DEV is not set
488
489#
490# Digital Video Broadcasting Devices
491#
492# CONFIG_DVB is not set
493
494#
495# Graphics support
496#
497# CONFIG_FB is not set
498
499#
500# Sound
501#
502# CONFIG_SOUND is not set
503
504#
505# USB support
506#
507# CONFIG_USB_ARCH_HAS_HCD is not set
508# CONFIG_USB_ARCH_HAS_OHCI is not set
509
510#
511# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
512#
513
514#
515# USB Gadget Support
516#
517# CONFIG_USB_GADGET is not set
518
519#
520# MMC/SD Card support
521#
522# CONFIG_MMC is not set
523
524#
525# InfiniBand support
526#
527# CONFIG_INFINIBAND is not set
528
529#
530# File systems
531#
532CONFIG_EXT2_FS=y
533# CONFIG_EXT2_FS_XATTR is not set
534CONFIG_EXT3_FS=y
535CONFIG_EXT3_FS_XATTR=y
536# CONFIG_EXT3_FS_POSIX_ACL is not set
537# CONFIG_EXT3_FS_SECURITY is not set
538CONFIG_JBD=y
539# CONFIG_JBD_DEBUG is not set
540CONFIG_FS_MBCACHE=y
541# CONFIG_REISERFS_FS is not set
542# CONFIG_JFS_FS is not set
543
544#
545# XFS support
546#
547# CONFIG_XFS_FS is not set
548# CONFIG_MINIX_FS is not set
549# CONFIG_ROMFS_FS is not set
550# CONFIG_QUOTA is not set
551CONFIG_DNOTIFY=y
552# CONFIG_AUTOFS_FS is not set
553# CONFIG_AUTOFS4_FS is not set
554
555#
556# CD-ROM/DVD Filesystems
557#
558# CONFIG_ISO9660_FS is not set
559# CONFIG_UDF_FS is not set
560
561#
562# DOS/FAT/NT Filesystems
563#
564CONFIG_FAT_FS=y
565# CONFIG_MSDOS_FS is not set
566CONFIG_VFAT_FS=y
567CONFIG_FAT_DEFAULT_CODEPAGE=437
568CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
569# CONFIG_NTFS_FS is not set
570
571#
572# Pseudo filesystems
573#
574CONFIG_PROC_FS=y
575CONFIG_PROC_KCORE=y
576CONFIG_SYSFS=y
577CONFIG_DEVFS_FS=y
578CONFIG_DEVFS_MOUNT=y
579# CONFIG_DEVFS_DEBUG is not set
580CONFIG_DEVPTS_FS_XATTR=y
581# CONFIG_DEVPTS_FS_SECURITY is not set
582CONFIG_TMPFS=y
583# CONFIG_TMPFS_XATTR is not set
584# CONFIG_HUGETLBFS is not set
585# CONFIG_HUGETLB_PAGE is not set
586CONFIG_RAMFS=y
587
588#
589# Miscellaneous filesystems
590#
591# CONFIG_ADFS_FS is not set
592# CONFIG_AFFS_FS is not set
593# CONFIG_HFS_FS is not set
594# CONFIG_HFSPLUS_FS is not set
595# CONFIG_BEFS_FS is not set
596# CONFIG_BFS_FS is not set
597# CONFIG_EFS_FS is not set
598# CONFIG_CRAMFS is not set
599# CONFIG_VXFS_FS is not set
600# CONFIG_HPFS_FS is not set
601# CONFIG_QNX4FS_FS is not set
602# CONFIG_SYSV_FS is not set
603# CONFIG_UFS_FS is not set
604
605#
606# Network File Systems
607#
608CONFIG_NFS_FS=y
609CONFIG_NFS_V3=y
610CONFIG_NFS_V4=y
611# CONFIG_NFS_DIRECTIO is not set
612# CONFIG_NFSD is not set
613CONFIG_ROOT_NFS=y
614CONFIG_LOCKD=y
615CONFIG_LOCKD_V4=y
616CONFIG_SUNRPC=y
617CONFIG_SUNRPC_GSS=y
618CONFIG_RPCSEC_GSS_KRB5=y
619# CONFIG_RPCSEC_GSS_SPKM3 is not set
620# CONFIG_SMB_FS is not set
621# CONFIG_CIFS is not set
622# CONFIG_NCP_FS is not set
623# CONFIG_CODA_FS is not set
624# CONFIG_AFS_FS is not set
625
626#
627# Partition Types
628#
629# CONFIG_PARTITION_ADVANCED is not set
630CONFIG_MSDOS_PARTITION=y
631
632#
633# Native Language Support
634#
635CONFIG_NLS=y
636CONFIG_NLS_DEFAULT="iso8859-1"
637# CONFIG_NLS_CODEPAGE_437 is not set
638# CONFIG_NLS_CODEPAGE_737 is not set
639# CONFIG_NLS_CODEPAGE_775 is not set
640# CONFIG_NLS_CODEPAGE_850 is not set
641# CONFIG_NLS_CODEPAGE_852 is not set
642# CONFIG_NLS_CODEPAGE_855 is not set
643# CONFIG_NLS_CODEPAGE_857 is not set
644# CONFIG_NLS_CODEPAGE_860 is not set
645# CONFIG_NLS_CODEPAGE_861 is not set
646# CONFIG_NLS_CODEPAGE_862 is not set
647# CONFIG_NLS_CODEPAGE_863 is not set
648# CONFIG_NLS_CODEPAGE_864 is not set
649# CONFIG_NLS_CODEPAGE_865 is not set
650# CONFIG_NLS_CODEPAGE_866 is not set
651# CONFIG_NLS_CODEPAGE_869 is not set
652# CONFIG_NLS_CODEPAGE_936 is not set
653# CONFIG_NLS_CODEPAGE_950 is not set
654# CONFIG_NLS_CODEPAGE_932 is not set
655# CONFIG_NLS_CODEPAGE_949 is not set
656# CONFIG_NLS_CODEPAGE_874 is not set
657# CONFIG_NLS_ISO8859_8 is not set
658# CONFIG_NLS_CODEPAGE_1250 is not set
659# CONFIG_NLS_CODEPAGE_1251 is not set
660# CONFIG_NLS_ASCII is not set
661# CONFIG_NLS_ISO8859_1 is not set
662# CONFIG_NLS_ISO8859_2 is not set
663# CONFIG_NLS_ISO8859_3 is not set
664# CONFIG_NLS_ISO8859_4 is not set
665# CONFIG_NLS_ISO8859_5 is not set
666# CONFIG_NLS_ISO8859_6 is not set
667# CONFIG_NLS_ISO8859_7 is not set
668# CONFIG_NLS_ISO8859_9 is not set
669# CONFIG_NLS_ISO8859_13 is not set
670# CONFIG_NLS_ISO8859_14 is not set
671# CONFIG_NLS_ISO8859_15 is not set
672# CONFIG_NLS_KOI8_R is not set
673# CONFIG_NLS_KOI8_U is not set
674# CONFIG_NLS_UTF8 is not set
675
676#
677# Profiling support
678#
679# CONFIG_PROFILING is not set
680
681#
682# Kernel hacking
683#
684# CONFIG_DEBUG_KERNEL is not set
685CONFIG_DEBUG_PREEMPT=y
686# CONFIG_FRAME_POINTER is not set
687# CONFIG_SH_STANDARD_BIOS is not set
688# CONFIG_EARLY_SCIF_CONSOLE is not set
689# CONFIG_KGDB is not set
690
691#
692# Security options
693#
694# CONFIG_KEYS is not set
695# CONFIG_SECURITY is not set
696
697#
698# Cryptographic options
699#
700CONFIG_CRYPTO=y
701# CONFIG_CRYPTO_HMAC is not set
702# CONFIG_CRYPTO_NULL is not set
703# CONFIG_CRYPTO_MD4 is not set
704CONFIG_CRYPTO_MD5=y
705# CONFIG_CRYPTO_SHA1 is not set
706# CONFIG_CRYPTO_SHA256 is not set
707# CONFIG_CRYPTO_SHA512 is not set
708# CONFIG_CRYPTO_WP512 is not set
709CONFIG_CRYPTO_DES=y
710# CONFIG_CRYPTO_BLOWFISH is not set
711# CONFIG_CRYPTO_TWOFISH is not set
712# CONFIG_CRYPTO_SERPENT is not set
713# CONFIG_CRYPTO_AES is not set
714# CONFIG_CRYPTO_CAST5 is not set
715# CONFIG_CRYPTO_CAST6 is not set
716# CONFIG_CRYPTO_TEA is not set
717# CONFIG_CRYPTO_ARC4 is not set
718# CONFIG_CRYPTO_KHAZAD is not set
719# CONFIG_CRYPTO_ANUBIS is not set
720# CONFIG_CRYPTO_DEFLATE is not set
721# CONFIG_CRYPTO_MICHAEL_MIC is not set
722# CONFIG_CRYPTO_CRC32C is not set
723# CONFIG_CRYPTO_TEST is not set
724
725#
726# Hardware crypto devices
727#
728
729#
730# Library routines
731#
732# CONFIG_CRC_CCITT is not set
733CONFIG_CRC32=y
734# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig
new file mode 100644
index 000000000000..e43cf57326bd
--- /dev/null
+++ b/arch/sh/configs/rts7751r2d_defconfig
@@ -0,0 +1,847 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:42 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25CONFIG_SYSVIPC=y
26# CONFIG_POSIX_MQUEUE is not set
27# CONFIG_BSD_PROCESS_ACCT is not set
28CONFIG_SYSCTL=y
29# CONFIG_AUDIT is not set
30CONFIG_LOG_BUF_SHIFT=14
31CONFIG_HOTPLUG=y
32CONFIG_KOBJECT_UEVENT=y
33# CONFIG_IKCONFIG is not set
34CONFIG_EMBEDDED=y
35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_EXTRA_PASS is not set
37CONFIG_FUTEX=y
38CONFIG_EPOLL=y
39# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
40CONFIG_SHMEM=y
41CONFIG_CC_ALIGN_FUNCTIONS=0
42CONFIG_CC_ALIGN_LABELS=0
43CONFIG_CC_ALIGN_LOOPS=0
44CONFIG_CC_ALIGN_JUMPS=0
45# CONFIG_TINY_SHMEM is not set
46
47#
48# Loadable module support
49#
50CONFIG_MODULES=y
51# CONFIG_MODULE_UNLOAD is not set
52CONFIG_OBSOLETE_MODPARM=y
53# CONFIG_MODVERSIONS is not set
54# CONFIG_MODULE_SRCVERSION_ALL is not set
55# CONFIG_KMOD is not set
56
57#
58# System type
59#
60# CONFIG_SH_SOLUTION_ENGINE is not set
61# CONFIG_SH_7751_SOLUTION_ENGINE is not set
62# CONFIG_SH_7300_SOLUTION_ENGINE is not set
63# CONFIG_SH_73180_SOLUTION_ENGINE is not set
64# CONFIG_SH_7751_SYSTEMH is not set
65# CONFIG_SH_STB1_HARP is not set
66# CONFIG_SH_STB1_OVERDRIVE is not set
67# CONFIG_SH_HP620 is not set
68# CONFIG_SH_HP680 is not set
69# CONFIG_SH_HP690 is not set
70# CONFIG_SH_CQREEK is not set
71# CONFIG_SH_DMIDA is not set
72# CONFIG_SH_EC3104 is not set
73# CONFIG_SH_SATURN is not set
74# CONFIG_SH_DREAMCAST is not set
75# CONFIG_SH_CAT68701 is not set
76# CONFIG_SH_BIGSUR is not set
77# CONFIG_SH_SH2000 is not set
78# CONFIG_SH_ADX is not set
79# CONFIG_SH_MPC1211 is not set
80# CONFIG_SH_SH03 is not set
81# CONFIG_SH_SECUREEDGE5410 is not set
82# CONFIG_SH_HS7751RVOIP is not set
83CONFIG_SH_RTS7751R2D=y
84# CONFIG_SH_EDOSK7705 is not set
85# CONFIG_SH_SH4202_MICRODEV is not set
86# CONFIG_SH_UNKNOWN is not set
87# CONFIG_CPU_SH2 is not set
88# CONFIG_CPU_SH3 is not set
89CONFIG_CPU_SH4=y
90# CONFIG_CPU_SUBTYPE_SH7604 is not set
91# CONFIG_CPU_SUBTYPE_SH7300 is not set
92# CONFIG_CPU_SUBTYPE_SH7705 is not set
93# CONFIG_CPU_SUBTYPE_SH7707 is not set
94# CONFIG_CPU_SUBTYPE_SH7708 is not set
95# CONFIG_CPU_SUBTYPE_SH7709 is not set
96# CONFIG_CPU_SUBTYPE_SH7750 is not set
97CONFIG_CPU_SUBTYPE_SH7751=y
98# CONFIG_CPU_SUBTYPE_SH7760 is not set
99# CONFIG_CPU_SUBTYPE_SH73180 is not set
100# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
101# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
102# CONFIG_CPU_SUBTYPE_SH4_202 is not set
103CONFIG_MMU=y
104CONFIG_CMDLINE_BOOL=y
105CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
106CONFIG_MEMORY_START=0x0c000000
107CONFIG_MEMORY_SIZE=0x04000000
108CONFIG_MEMORY_SET=y
109# CONFIG_MEMORY_OVERRIDE is not set
110CONFIG_SH_RTC=y
111CONFIG_SH_FPU=y
112CONFIG_ZERO_PAGE_OFFSET=0x00010000
113CONFIG_BOOT_LINK_OFFSET=0x00800000
114CONFIG_CPU_LITTLE_ENDIAN=y
115# CONFIG_PREEMPT is not set
116# CONFIG_UBC_WAKEUP is not set
117# CONFIG_SH_WRITETHROUGH is not set
118# CONFIG_SH_OCRAM is not set
119# CONFIG_SH_STORE_QUEUES is not set
120# CONFIG_SMP is not set
121CONFIG_RTS7751R2D_REV11=y
122CONFIG_SH_PCLK_CALC=y
123CONFIG_SH_PCLK_FREQ=60000000
124
125#
126# CPU Frequency scaling
127#
128# CONFIG_CPU_FREQ is not set
129
130#
131# DMA support
132#
133CONFIG_SH_DMA=y
134CONFIG_NR_ONCHIP_DMA_CHANNELS=8
135# CONFIG_NR_DMA_CHANNELS_BOOL is not set
136
137#
138# Companion Chips
139#
140CONFIG_VOYAGERGX=y
141# CONFIG_HD6446X_SERIES is not set
142CONFIG_HEARTBEAT=y
143CONFIG_RTC_9701JE=y
144
145#
146# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
147#
148CONFIG_PCI=y
149CONFIG_SH_PCIDMA_NONCOHERENT=y
150CONFIG_PCI_AUTO=y
151CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
152# CONFIG_PCI_LEGACY_PROC is not set
153CONFIG_PCI_NAMES=y
154
155#
156# PCCARD (PCMCIA/CardBus) support
157#
158# CONFIG_PCCARD is not set
159
160#
161# PC-card bridges
162#
163
164#
165# PCI Hotplug Support
166#
167CONFIG_HOTPLUG_PCI=y
168# CONFIG_HOTPLUG_PCI_FAKE is not set
169# CONFIG_HOTPLUG_PCI_CPCI is not set
170# CONFIG_HOTPLUG_PCI_SHPC is not set
171
172#
173# Executable file formats
174#
175CONFIG_BINFMT_ELF=y
176# CONFIG_BINFMT_FLAT is not set
177# CONFIG_BINFMT_MISC is not set
178
179#
180# Device Drivers
181#
182
183#
184# Generic Driver Options
185#
186CONFIG_STANDALONE=y
187CONFIG_PREVENT_FIRMWARE_BUILD=y
188# CONFIG_FW_LOADER is not set
189
190#
191# Memory Technology Devices (MTD)
192#
193# CONFIG_MTD is not set
194
195#
196# Parallel port support
197#
198# CONFIG_PARPORT is not set
199
200#
201# Plug and Play support
202#
203
204#
205# Block devices
206#
207# CONFIG_BLK_DEV_FD is not set
208# CONFIG_BLK_CPQ_DA is not set
209# CONFIG_BLK_CPQ_CISS_DA is not set
210# CONFIG_BLK_DEV_DAC960 is not set
211# CONFIG_BLK_DEV_UMEM is not set
212# CONFIG_BLK_DEV_COW_COMMON is not set
213# CONFIG_BLK_DEV_LOOP is not set
214# CONFIG_BLK_DEV_NBD is not set
215# CONFIG_BLK_DEV_SX8 is not set
216CONFIG_BLK_DEV_RAM=y
217CONFIG_BLK_DEV_RAM_COUNT=16
218CONFIG_BLK_DEV_RAM_SIZE=4096
219# CONFIG_BLK_DEV_INITRD is not set
220CONFIG_INITRAMFS_SOURCE=""
221# CONFIG_LBD is not set
222# CONFIG_CDROM_PKTCDVD is not set
223
224#
225# IO Schedulers
226#
227CONFIG_IOSCHED_NOOP=y
228CONFIG_IOSCHED_AS=y
229CONFIG_IOSCHED_DEADLINE=y
230CONFIG_IOSCHED_CFQ=y
231# CONFIG_ATA_OVER_ETH is not set
232
233#
234# ATA/ATAPI/MFM/RLL support
235#
236CONFIG_IDE=y
237CONFIG_IDE_MAX_HWIFS=4
238CONFIG_BLK_DEV_IDE=y
239
240#
241# Please see Documentation/ide.txt for help/info on IDE drives
242#
243# CONFIG_BLK_DEV_IDE_SATA is not set
244CONFIG_BLK_DEV_IDEDISK=y
245# CONFIG_IDEDISK_MULTI_MODE is not set
246# CONFIG_BLK_DEV_IDECD is not set
247# CONFIG_BLK_DEV_IDETAPE is not set
248# CONFIG_BLK_DEV_IDEFLOPPY is not set
249# CONFIG_IDE_TASK_IOCTL is not set
250
251#
252# IDE chipset support/bugfixes
253#
254CONFIG_IDE_GENERIC=y
255# CONFIG_BLK_DEV_IDEPCI is not set
256CONFIG_IDE_SH=y
257# CONFIG_IDE_ARM is not set
258# CONFIG_BLK_DEV_IDEDMA is not set
259# CONFIG_IDEDMA_AUTO is not set
260# CONFIG_BLK_DEV_HD is not set
261
262#
263# SCSI device support
264#
265# CONFIG_SCSI is not set
266
267#
268# Multi-device support (RAID and LVM)
269#
270# CONFIG_MD is not set
271
272#
273# Fusion MPT device support
274#
275
276#
277# IEEE 1394 (FireWire) support
278#
279# CONFIG_IEEE1394 is not set
280
281#
282# I2O device support
283#
284# CONFIG_I2O is not set
285
286#
287# Networking support
288#
289CONFIG_NET=y
290
291#
292# Networking options
293#
294CONFIG_PACKET=y
295# CONFIG_PACKET_MMAP is not set
296# CONFIG_NETLINK_DEV is not set
297CONFIG_UNIX=y
298# CONFIG_NET_KEY is not set
299CONFIG_INET=y
300# CONFIG_IP_MULTICAST is not set
301# CONFIG_IP_ADVANCED_ROUTER is not set
302# CONFIG_IP_PNP is not set
303# CONFIG_NET_IPIP is not set
304# CONFIG_NET_IPGRE is not set
305# CONFIG_ARPD is not set
306# CONFIG_SYN_COOKIES is not set
307# CONFIG_INET_AH is not set
308# CONFIG_INET_ESP is not set
309# CONFIG_INET_IPCOMP is not set
310# CONFIG_INET_TUNNEL is not set
311CONFIG_IP_TCPDIAG=y
312# CONFIG_IP_TCPDIAG_IPV6 is not set
313# CONFIG_IPV6 is not set
314# CONFIG_NETFILTER is not set
315
316#
317# SCTP Configuration (EXPERIMENTAL)
318#
319# CONFIG_IP_SCTP is not set
320# CONFIG_ATM is not set
321# CONFIG_BRIDGE is not set
322# CONFIG_VLAN_8021Q is not set
323# CONFIG_DECNET is not set
324# CONFIG_LLC2 is not set
325# CONFIG_IPX is not set
326# CONFIG_ATALK is not set
327# CONFIG_X25 is not set
328# CONFIG_LAPB is not set
329# CONFIG_NET_DIVERT is not set
330# CONFIG_ECONET is not set
331# CONFIG_WAN_ROUTER is not set
332
333#
334# QoS and/or fair queueing
335#
336# CONFIG_NET_SCHED is not set
337# CONFIG_NET_CLS_ROUTE is not set
338
339#
340# Network testing
341#
342# CONFIG_NET_PKTGEN is not set
343# CONFIG_NETPOLL is not set
344# CONFIG_NET_POLL_CONTROLLER is not set
345# CONFIG_HAMRADIO is not set
346# CONFIG_IRDA is not set
347# CONFIG_BT is not set
348CONFIG_NETDEVICES=y
349# CONFIG_DUMMY is not set
350# CONFIG_BONDING is not set
351# CONFIG_EQUALIZER is not set
352# CONFIG_TUN is not set
353
354#
355# ARCnet devices
356#
357# CONFIG_ARCNET is not set
358
359#
360# Ethernet (10 or 100Mbit)
361#
362CONFIG_NET_ETHERNET=y
363CONFIG_MII=y
364# CONFIG_STNIC is not set
365# CONFIG_HAPPYMEAL is not set
366# CONFIG_SUNGEM is not set
367# CONFIG_NET_VENDOR_3COM is not set
368# CONFIG_SMC91X is not set
369
370#
371# Tulip family network device support
372#
373# CONFIG_NET_TULIP is not set
374# CONFIG_HP100 is not set
375CONFIG_NET_PCI=y
376# CONFIG_PCNET32 is not set
377# CONFIG_AMD8111_ETH is not set
378# CONFIG_ADAPTEC_STARFIRE is not set
379# CONFIG_B44 is not set
380# CONFIG_FORCEDETH is not set
381# CONFIG_DGRS is not set
382# CONFIG_EEPRO100 is not set
383# CONFIG_E100 is not set
384# CONFIG_FEALNX is not set
385# CONFIG_NATSEMI is not set
386# CONFIG_NE2K_PCI is not set
387# CONFIG_8139CP is not set
388CONFIG_8139TOO=y
389# CONFIG_8139TOO_PIO is not set
390# CONFIG_8139TOO_TUNE_TWISTER is not set
391# CONFIG_8139TOO_8129 is not set
392# CONFIG_8139_OLD_RX_RESET is not set
393# CONFIG_SIS900 is not set
394# CONFIG_EPIC100 is not set
395# CONFIG_SUNDANCE is not set
396# CONFIG_TLAN is not set
397# CONFIG_VIA_RHINE is not set
398
399#
400# Ethernet (1000 Mbit)
401#
402# CONFIG_ACENIC is not set
403# CONFIG_DL2K is not set
404# CONFIG_E1000 is not set
405# CONFIG_NS83820 is not set
406# CONFIG_HAMACHI is not set
407# CONFIG_YELLOWFIN is not set
408# CONFIG_R8169 is not set
409# CONFIG_SK98LIN is not set
410# CONFIG_VIA_VELOCITY is not set
411# CONFIG_TIGON3 is not set
412
413#
414# Ethernet (10000 Mbit)
415#
416# CONFIG_IXGB is not set
417# CONFIG_S2IO is not set
418
419#
420# Token Ring devices
421#
422# CONFIG_TR is not set
423
424#
425# Wireless LAN (non-hamradio)
426#
427CONFIG_NET_RADIO=y
428
429#
430# Obsolete Wireless cards support (pre-802.11)
431#
432# CONFIG_STRIP is not set
433
434#
435# Wireless 802.11b ISA/PCI cards support
436#
437CONFIG_HERMES=m
438# CONFIG_PLX_HERMES is not set
439# CONFIG_TMD_HERMES is not set
440# CONFIG_PCI_HERMES is not set
441# CONFIG_ATMEL is not set
442
443#
444# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
445#
446# CONFIG_PRISM54 is not set
447CONFIG_NET_WIRELESS=y
448
449#
450# Wan interfaces
451#
452# CONFIG_WAN is not set
453# CONFIG_FDDI is not set
454# CONFIG_HIPPI is not set
455# CONFIG_PPP is not set
456# CONFIG_SLIP is not set
457# CONFIG_SHAPER is not set
458# CONFIG_NETCONSOLE is not set
459
460#
461# ISDN subsystem
462#
463# CONFIG_ISDN is not set
464
465#
466# Telephony Support
467#
468# CONFIG_PHONE is not set
469
470#
471# Input device support
472#
473# CONFIG_INPUT is not set
474
475#
476# Userland interfaces
477#
478
479#
480# Input I/O drivers
481#
482# CONFIG_GAMEPORT is not set
483CONFIG_SOUND_GAMEPORT=y
484# CONFIG_SERIO is not set
485# CONFIG_SERIO_I8042 is not set
486
487#
488# Input Device Drivers
489#
490
491#
492# Character devices
493#
494# CONFIG_VT is not set
495# CONFIG_SERIAL_NONSTANDARD is not set
496
497#
498# Serial drivers
499#
500# CONFIG_SERIAL_8250 is not set
501
502#
503# Non-8250 serial port support
504#
505# CONFIG_SERIAL_SH_SCI is not set
506# CONFIG_UNIX98_PTYS is not set
507CONFIG_LEGACY_PTYS=y
508CONFIG_LEGACY_PTY_COUNT=256
509
510#
511# IPMI
512#
513# CONFIG_IPMI_HANDLER is not set
514
515#
516# Watchdog Cards
517#
518# CONFIG_WATCHDOG is not set
519# CONFIG_RTC is not set
520# CONFIG_GEN_RTC is not set
521# CONFIG_DTLK is not set
522# CONFIG_R3964 is not set
523# CONFIG_APPLICOM is not set
524
525#
526# Ftape, the floppy tape device driver
527#
528# CONFIG_DRM is not set
529# CONFIG_RAW_DRIVER is not set
530
531#
532# I2C support
533#
534# CONFIG_I2C is not set
535
536#
537# Dallas's 1-wire bus
538#
539# CONFIG_W1 is not set
540
541#
542# Misc devices
543#
544
545#
546# Multimedia devices
547#
548# CONFIG_VIDEO_DEV is not set
549
550#
551# Digital Video Broadcasting Devices
552#
553# CONFIG_DVB is not set
554
555#
556# Graphics support
557#
558# CONFIG_FB is not set
559
560#
561# Sound
562#
563CONFIG_SOUND=y
564
565#
566# Advanced Linux Sound Architecture
567#
568CONFIG_SND=m
569CONFIG_SND_TIMER=m
570CONFIG_SND_PCM=m
571CONFIG_SND_HWDEP=m
572CONFIG_SND_RAWMIDI=m
573# CONFIG_SND_SEQUENCER is not set
574# CONFIG_SND_MIXER_OSS is not set
575# CONFIG_SND_PCM_OSS is not set
576# CONFIG_SND_VERBOSE_PRINTK is not set
577# CONFIG_SND_DEBUG is not set
578
579#
580# Generic devices
581#
582CONFIG_SND_MPU401_UART=m
583CONFIG_SND_OPL3_LIB=m
584# CONFIG_SND_DUMMY is not set
585# CONFIG_SND_MTPAV is not set
586# CONFIG_SND_SERIAL_U16550 is not set
587# CONFIG_SND_MPU401 is not set
588
589#
590# PCI devices
591#
592CONFIG_SND_AC97_CODEC=m
593# CONFIG_SND_ALI5451 is not set
594# CONFIG_SND_ATIIXP is not set
595# CONFIG_SND_ATIIXP_MODEM is not set
596# CONFIG_SND_AU8810 is not set
597# CONFIG_SND_AU8820 is not set
598# CONFIG_SND_AU8830 is not set
599# CONFIG_SND_AZT3328 is not set
600# CONFIG_SND_BT87X is not set
601# CONFIG_SND_CS46XX is not set
602# CONFIG_SND_CS4281 is not set
603# CONFIG_SND_EMU10K1 is not set
604# CONFIG_SND_EMU10K1X is not set
605# CONFIG_SND_CA0106 is not set
606# CONFIG_SND_KORG1212 is not set
607# CONFIG_SND_MIXART is not set
608# CONFIG_SND_NM256 is not set
609# CONFIG_SND_RME32 is not set
610# CONFIG_SND_RME96 is not set
611# CONFIG_SND_RME9652 is not set
612# CONFIG_SND_HDSP is not set
613# CONFIG_SND_TRIDENT is not set
614CONFIG_SND_YMFPCI=m
615# CONFIG_SND_ALS4000 is not set
616# CONFIG_SND_CMIPCI is not set
617# CONFIG_SND_ENS1370 is not set
618# CONFIG_SND_ENS1371 is not set
619# CONFIG_SND_ES1938 is not set
620# CONFIG_SND_ES1968 is not set
621# CONFIG_SND_MAESTRO3 is not set
622# CONFIG_SND_FM801 is not set
623# CONFIG_SND_ICE1712 is not set
624# CONFIG_SND_ICE1724 is not set
625# CONFIG_SND_INTEL8X0 is not set
626# CONFIG_SND_INTEL8X0M is not set
627# CONFIG_SND_SONICVIBES is not set
628# CONFIG_SND_VIA82XX is not set
629# CONFIG_SND_VIA82XX_MODEM is not set
630# CONFIG_SND_VX222 is not set
631
632#
633# Open Sound System
634#
635CONFIG_SOUND_PRIME=m
636# CONFIG_SOUND_BT878 is not set
637CONFIG_SOUND_CMPCI=m
638# CONFIG_SOUND_EMU10K1 is not set
639# CONFIG_SOUND_FUSION is not set
640# CONFIG_SOUND_CS4281 is not set
641# CONFIG_SOUND_ES1370 is not set
642# CONFIG_SOUND_ES1371 is not set
643# CONFIG_SOUND_ESSSOLO1 is not set
644# CONFIG_SOUND_MAESTRO is not set
645# CONFIG_SOUND_MAESTRO3 is not set
646# CONFIG_SOUND_ICH is not set
647# CONFIG_SOUND_SONICVIBES is not set
648# CONFIG_SOUND_TRIDENT is not set
649# CONFIG_SOUND_MSNDCLAS is not set
650# CONFIG_SOUND_MSNDPIN is not set
651# CONFIG_SOUND_VIA82CXXX is not set
652# CONFIG_SOUND_OSS is not set
653# CONFIG_SOUND_ALI5455 is not set
654# CONFIG_SOUND_FORTE is not set
655# CONFIG_SOUND_RME96XX is not set
656# CONFIG_SOUND_AD1980 is not set
657CONFIG_SOUND_VOYAGERGX=m
658
659#
660# USB support
661#
662# CONFIG_USB is not set
663CONFIG_USB_ARCH_HAS_HCD=y
664CONFIG_USB_ARCH_HAS_OHCI=y
665
666#
667# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
668#
669
670#
671# USB Gadget Support
672#
673# CONFIG_USB_GADGET is not set
674
675#
676# MMC/SD Card support
677#
678# CONFIG_MMC is not set
679
680#
681# InfiniBand support
682#
683# CONFIG_INFINIBAND is not set
684
685#
686# File systems
687#
688CONFIG_EXT2_FS=y
689# CONFIG_EXT2_FS_XATTR is not set
690# CONFIG_EXT3_FS is not set
691# CONFIG_JBD is not set
692# CONFIG_REISERFS_FS is not set
693# CONFIG_JFS_FS is not set
694
695#
696# XFS support
697#
698# CONFIG_XFS_FS is not set
699CONFIG_MINIX_FS=y
700# CONFIG_ROMFS_FS is not set
701# CONFIG_QUOTA is not set
702CONFIG_DNOTIFY=y
703# CONFIG_AUTOFS_FS is not set
704# CONFIG_AUTOFS4_FS is not set
705
706#
707# CD-ROM/DVD Filesystems
708#
709# CONFIG_ISO9660_FS is not set
710# CONFIG_UDF_FS is not set
711
712#
713# DOS/FAT/NT Filesystems
714#
715CONFIG_FAT_FS=y
716CONFIG_MSDOS_FS=y
717CONFIG_VFAT_FS=y
718CONFIG_FAT_DEFAULT_CODEPAGE=437
719CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
720# CONFIG_NTFS_FS is not set
721
722#
723# Pseudo filesystems
724#
725CONFIG_PROC_FS=y
726CONFIG_PROC_KCORE=y
727CONFIG_SYSFS=y
728# CONFIG_DEVFS_FS is not set
729# CONFIG_TMPFS is not set
730# CONFIG_HUGETLBFS is not set
731# CONFIG_HUGETLB_PAGE is not set
732CONFIG_RAMFS=y
733
734#
735# Miscellaneous filesystems
736#
737# CONFIG_ADFS_FS is not set
738# CONFIG_AFFS_FS is not set
739# CONFIG_HFS_FS is not set
740# CONFIG_HFSPLUS_FS is not set
741# CONFIG_BEFS_FS is not set
742# CONFIG_BFS_FS is not set
743# CONFIG_EFS_FS is not set
744# CONFIG_CRAMFS is not set
745# CONFIG_VXFS_FS is not set
746# CONFIG_HPFS_FS is not set
747# CONFIG_QNX4FS_FS is not set
748# CONFIG_SYSV_FS is not set
749# CONFIG_UFS_FS is not set
750
751#
752# Network File Systems
753#
754# CONFIG_NFS_FS is not set
755# CONFIG_NFSD is not set
756# CONFIG_SMB_FS is not set
757# CONFIG_CIFS is not set
758# CONFIG_NCP_FS is not set
759# CONFIG_CODA_FS is not set
760# CONFIG_AFS_FS is not set
761
762#
763# Partition Types
764#
765# CONFIG_PARTITION_ADVANCED is not set
766CONFIG_MSDOS_PARTITION=y
767
768#
769# Native Language Support
770#
771CONFIG_NLS=y
772CONFIG_NLS_DEFAULT="iso8859-1"
773# CONFIG_NLS_CODEPAGE_437 is not set
774# CONFIG_NLS_CODEPAGE_737 is not set
775# CONFIG_NLS_CODEPAGE_775 is not set
776# CONFIG_NLS_CODEPAGE_850 is not set
777# CONFIG_NLS_CODEPAGE_852 is not set
778# CONFIG_NLS_CODEPAGE_855 is not set
779# CONFIG_NLS_CODEPAGE_857 is not set
780# CONFIG_NLS_CODEPAGE_860 is not set
781# CONFIG_NLS_CODEPAGE_861 is not set
782# CONFIG_NLS_CODEPAGE_862 is not set
783# CONFIG_NLS_CODEPAGE_863 is not set
784# CONFIG_NLS_CODEPAGE_864 is not set
785# CONFIG_NLS_CODEPAGE_865 is not set
786# CONFIG_NLS_CODEPAGE_866 is not set
787# CONFIG_NLS_CODEPAGE_869 is not set
788# CONFIG_NLS_CODEPAGE_936 is not set
789# CONFIG_NLS_CODEPAGE_950 is not set
790CONFIG_NLS_CODEPAGE_932=y
791# CONFIG_NLS_CODEPAGE_949 is not set
792# CONFIG_NLS_CODEPAGE_874 is not set
793# CONFIG_NLS_ISO8859_8 is not set
794# CONFIG_NLS_CODEPAGE_1250 is not set
795# CONFIG_NLS_CODEPAGE_1251 is not set
796# CONFIG_NLS_ASCII is not set
797# CONFIG_NLS_ISO8859_1 is not set
798# CONFIG_NLS_ISO8859_2 is not set
799# CONFIG_NLS_ISO8859_3 is not set
800# CONFIG_NLS_ISO8859_4 is not set
801# CONFIG_NLS_ISO8859_5 is not set
802# CONFIG_NLS_ISO8859_6 is not set
803# CONFIG_NLS_ISO8859_7 is not set
804# CONFIG_NLS_ISO8859_9 is not set
805# CONFIG_NLS_ISO8859_13 is not set
806# CONFIG_NLS_ISO8859_14 is not set
807# CONFIG_NLS_ISO8859_15 is not set
808# CONFIG_NLS_KOI8_R is not set
809# CONFIG_NLS_KOI8_U is not set
810# CONFIG_NLS_UTF8 is not set
811
812#
813# Profiling support
814#
815CONFIG_PROFILING=y
816CONFIG_OPROFILE=y
817
818#
819# Kernel hacking
820#
821# CONFIG_DEBUG_KERNEL is not set
822# CONFIG_FRAME_POINTER is not set
823# CONFIG_SH_STANDARD_BIOS is not set
824# CONFIG_EARLY_SCIF_CONSOLE is not set
825# CONFIG_KGDB is not set
826
827#
828# Security options
829#
830# CONFIG_KEYS is not set
831# CONFIG_SECURITY is not set
832
833#
834# Cryptographic options
835#
836# CONFIG_CRYPTO is not set
837
838#
839# Hardware crypto devices
840#
841
842#
843# Library routines
844#
845# CONFIG_CRC_CCITT is not set
846CONFIG_CRC32=y
847# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se7300_defconfig b/arch/sh/configs/se7300_defconfig
new file mode 100644
index 000000000000..4b71cd692fa5
--- /dev/null
+++ b/arch/sh/configs/se7300_defconfig
@@ -0,0 +1,531 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:43 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24# CONFIG_SWAP is not set
25# CONFIG_SYSVIPC is not set
26# CONFIG_BSD_PROCESS_ACCT is not set
27CONFIG_SYSCTL=y
28# CONFIG_AUDIT is not set
29CONFIG_LOG_BUF_SHIFT=14
30# CONFIG_HOTPLUG is not set
31# CONFIG_IKCONFIG is not set
32CONFIG_EMBEDDED=y
33# CONFIG_KALLSYMS is not set
34# CONFIG_FUTEX is not set
35# CONFIG_EPOLL is not set
36# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
37CONFIG_SHMEM=y
38CONFIG_CC_ALIGN_FUNCTIONS=0
39CONFIG_CC_ALIGN_LABELS=0
40CONFIG_CC_ALIGN_LOOPS=0
41CONFIG_CC_ALIGN_JUMPS=0
42# CONFIG_TINY_SHMEM is not set
43
44#
45# Loadable module support
46#
47# CONFIG_MODULES is not set
48
49#
50# System type
51#
52# CONFIG_SH_SOLUTION_ENGINE is not set
53# CONFIG_SH_7751_SOLUTION_ENGINE is not set
54CONFIG_SH_7300_SOLUTION_ENGINE=y
55# CONFIG_SH_73180_SOLUTION_ENGINE is not set
56# CONFIG_SH_7751_SYSTEMH is not set
57# CONFIG_SH_STB1_HARP is not set
58# CONFIG_SH_STB1_OVERDRIVE is not set
59# CONFIG_SH_HP620 is not set
60# CONFIG_SH_HP680 is not set
61# CONFIG_SH_HP690 is not set
62# CONFIG_SH_CQREEK is not set
63# CONFIG_SH_DMIDA is not set
64# CONFIG_SH_EC3104 is not set
65# CONFIG_SH_SATURN is not set
66# CONFIG_SH_DREAMCAST is not set
67# CONFIG_SH_CAT68701 is not set
68# CONFIG_SH_BIGSUR is not set
69# CONFIG_SH_SH2000 is not set
70# CONFIG_SH_ADX is not set
71# CONFIG_SH_MPC1211 is not set
72# CONFIG_SH_SH03 is not set
73# CONFIG_SH_SECUREEDGE5410 is not set
74# CONFIG_SH_HS7751RVOIP is not set
75# CONFIG_SH_RTS7751R2D is not set
76# CONFIG_SH_EDOSK7705 is not set
77# CONFIG_SH_SH4202_MICRODEV is not set
78# CONFIG_SH_UNKNOWN is not set
79# CONFIG_CPU_SH2 is not set
80CONFIG_CPU_SH3=y
81# CONFIG_CPU_SH4 is not set
82# CONFIG_CPU_SUBTYPE_SH7604 is not set
83CONFIG_CPU_SUBTYPE_SH7300=y
84# CONFIG_CPU_SUBTYPE_SH7705 is not set
85# CONFIG_CPU_SUBTYPE_SH7707 is not set
86# CONFIG_CPU_SUBTYPE_SH7708 is not set
87# CONFIG_CPU_SUBTYPE_SH7709 is not set
88# CONFIG_CPU_SUBTYPE_SH7750 is not set
89# CONFIG_CPU_SUBTYPE_SH7751 is not set
90# CONFIG_CPU_SUBTYPE_SH7760 is not set
91# CONFIG_CPU_SUBTYPE_SH73180 is not set
92# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
93# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
94# CONFIG_CPU_SUBTYPE_SH4_202 is not set
95CONFIG_MMU=y
96CONFIG_CMDLINE_BOOL=y
97CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0"
98CONFIG_MEMORY_START=0x0c000000
99CONFIG_MEMORY_SIZE=0x04000000
100# CONFIG_MEMORY_OVERRIDE is not set
101CONFIG_SH_DSP=y
102# CONFIG_SH_ADC is not set
103CONFIG_ZERO_PAGE_OFFSET=0x00001000
104CONFIG_BOOT_LINK_OFFSET=0x00210000
105CONFIG_CPU_LITTLE_ENDIAN=y
106# CONFIG_PREEMPT is not set
107# CONFIG_UBC_WAKEUP is not set
108# CONFIG_SH_WRITETHROUGH is not set
109# CONFIG_SH_OCRAM is not set
110# CONFIG_SMP is not set
111# CONFIG_SH_PCLK_CALC is not set
112CONFIG_SH_PCLK_FREQ=33333333
113
114#
115# CPU Frequency scaling
116#
117# CONFIG_CPU_FREQ is not set
118
119#
120# DMA support
121#
122# CONFIG_SH_DMA is not set
123
124#
125# Companion Chips
126#
127# CONFIG_HD6446X_SERIES is not set
128CONFIG_HEARTBEAT=y
129
130#
131# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
132#
133# CONFIG_PCI is not set
134
135#
136# PCCARD (PCMCIA/CardBus) support
137#
138# CONFIG_PCCARD is not set
139
140#
141# PC-card bridges
142#
143
144#
145# PCI Hotplug Support
146#
147
148#
149# Executable file formats
150#
151CONFIG_BINFMT_ELF=y
152# CONFIG_BINFMT_FLAT is not set
153# CONFIG_BINFMT_MISC is not set
154
155#
156# SH initrd options
157#
158CONFIG_EMBEDDED_RAMDISK=y
159CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
160
161#
162# Device Drivers
163#
164
165#
166# Generic Driver Options
167#
168CONFIG_STANDALONE=y
169CONFIG_PREVENT_FIRMWARE_BUILD=y
170# CONFIG_FW_LOADER is not set
171
172#
173# Memory Technology Devices (MTD)
174#
175# CONFIG_MTD is not set
176
177#
178# Parallel port support
179#
180# CONFIG_PARPORT is not set
181
182#
183# Plug and Play support
184#
185
186#
187# Block devices
188#
189# CONFIG_BLK_DEV_FD is not set
190# CONFIG_BLK_DEV_COW_COMMON is not set
191# CONFIG_BLK_DEV_LOOP is not set
192CONFIG_BLK_DEV_RAM=y
193CONFIG_BLK_DEV_RAM_COUNT=16
194CONFIG_BLK_DEV_RAM_SIZE=4096
195CONFIG_BLK_DEV_INITRD=y
196CONFIG_INITRAMFS_SOURCE=""
197# CONFIG_LBD is not set
198# CONFIG_CDROM_PKTCDVD is not set
199
200#
201# IO Schedulers
202#
203CONFIG_IOSCHED_NOOP=y
204# CONFIG_IOSCHED_AS is not set
205# CONFIG_IOSCHED_DEADLINE is not set
206# CONFIG_IOSCHED_CFQ is not set
207
208#
209# ATA/ATAPI/MFM/RLL support
210#
211# CONFIG_IDE is not set
212
213#
214# SCSI device support
215#
216# CONFIG_SCSI is not set
217
218#
219# Multi-device support (RAID and LVM)
220#
221# CONFIG_MD is not set
222
223#
224# Fusion MPT device support
225#
226
227#
228# IEEE 1394 (FireWire) support
229#
230
231#
232# I2O device support
233#
234
235#
236# Networking support
237#
238# CONFIG_NET is not set
239# CONFIG_NETPOLL is not set
240# CONFIG_NET_POLL_CONTROLLER is not set
241
242#
243# ISDN subsystem
244#
245
246#
247# Telephony Support
248#
249# CONFIG_PHONE is not set
250
251#
252# Input device support
253#
254CONFIG_INPUT=y
255
256#
257# Userland interfaces
258#
259CONFIG_INPUT_MOUSEDEV=y
260CONFIG_INPUT_MOUSEDEV_PSAUX=y
261CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
262CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
263# CONFIG_INPUT_JOYDEV is not set
264# CONFIG_INPUT_TSDEV is not set
265# CONFIG_INPUT_EVDEV is not set
266# CONFIG_INPUT_EVBUG is not set
267
268#
269# Input I/O drivers
270#
271# CONFIG_GAMEPORT is not set
272CONFIG_SOUND_GAMEPORT=y
273CONFIG_SERIO=y
274# CONFIG_SERIO_I8042 is not set
275# CONFIG_SERIO_SERPORT is not set
276# CONFIG_SERIO_CT82C710 is not set
277# CONFIG_SERIO_LIBPS2 is not set
278# CONFIG_SERIO_RAW is not set
279
280#
281# Input Device Drivers
282#
283# CONFIG_INPUT_KEYBOARD is not set
284# CONFIG_INPUT_MOUSE is not set
285# CONFIG_INPUT_JOYSTICK is not set
286# CONFIG_INPUT_TOUCHSCREEN is not set
287# CONFIG_INPUT_MISC is not set
288
289#
290# Character devices
291#
292# CONFIG_VT is not set
293# CONFIG_SERIAL_NONSTANDARD is not set
294
295#
296# Serial drivers
297#
298# CONFIG_SERIAL_8250 is not set
299
300#
301# Non-8250 serial port support
302#
303CONFIG_SERIAL_SH_SCI=y
304CONFIG_SERIAL_SH_SCI_CONSOLE=y
305CONFIG_SERIAL_CORE=y
306CONFIG_SERIAL_CORE_CONSOLE=y
307# CONFIG_UNIX98_PTYS is not set
308# CONFIG_LEGACY_PTYS is not set
309
310#
311# IPMI
312#
313CONFIG_IPMI_HANDLER=y
314# CONFIG_IPMI_PANIC_EVENT is not set
315CONFIG_IPMI_DEVICE_INTERFACE=y
316# CONFIG_IPMI_SI is not set
317CONFIG_IPMI_WATCHDOG=y
318# CONFIG_IPMI_POWEROFF is not set
319
320#
321# Watchdog Cards
322#
323CONFIG_WATCHDOG=y
324# CONFIG_WATCHDOG_NOWAYOUT is not set
325
326#
327# Watchdog Device Drivers
328#
329CONFIG_SOFT_WATCHDOG=y
330# CONFIG_SH_WDT is not set
331# CONFIG_RTC is not set
332# CONFIG_GEN_RTC is not set
333# CONFIG_DTLK is not set
334# CONFIG_R3964 is not set
335
336#
337# Ftape, the floppy tape device driver
338#
339# CONFIG_DRM is not set
340# CONFIG_RAW_DRIVER is not set
341
342#
343# I2C support
344#
345# CONFIG_I2C is not set
346
347#
348# Dallas's 1-wire bus
349#
350# CONFIG_W1 is not set
351
352#
353# Misc devices
354#
355
356#
357# Multimedia devices
358#
359# CONFIG_VIDEO_DEV is not set
360
361#
362# Digital Video Broadcasting Devices
363#
364
365#
366# Graphics support
367#
368# CONFIG_FB is not set
369
370#
371# Sound
372#
373# CONFIG_SOUND is not set
374
375#
376# USB support
377#
378# CONFIG_USB_ARCH_HAS_HCD is not set
379# CONFIG_USB_ARCH_HAS_OHCI is not set
380
381#
382# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
383#
384
385#
386# USB Gadget Support
387#
388# CONFIG_USB_GADGET is not set
389
390#
391# MMC/SD Card support
392#
393# CONFIG_MMC is not set
394
395#
396# InfiniBand support
397#
398# CONFIG_INFINIBAND is not set
399
400#
401# File systems
402#
403CONFIG_EXT2_FS=y
404# CONFIG_EXT2_FS_XATTR is not set
405# CONFIG_EXT3_FS is not set
406# CONFIG_JBD is not set
407# CONFIG_REISERFS_FS is not set
408# CONFIG_JFS_FS is not set
409
410#
411# XFS support
412#
413# CONFIG_XFS_FS is not set
414# CONFIG_MINIX_FS is not set
415# CONFIG_ROMFS_FS is not set
416# CONFIG_QUOTA is not set
417CONFIG_DNOTIFY=y
418# CONFIG_AUTOFS_FS is not set
419# CONFIG_AUTOFS4_FS is not set
420
421#
422# CD-ROM/DVD Filesystems
423#
424# CONFIG_ISO9660_FS is not set
425# CONFIG_UDF_FS is not set
426
427#
428# DOS/FAT/NT Filesystems
429#
430# CONFIG_MSDOS_FS is not set
431# CONFIG_VFAT_FS is not set
432# CONFIG_NTFS_FS is not set
433
434#
435# Pseudo filesystems
436#
437CONFIG_PROC_FS=y
438CONFIG_PROC_KCORE=y
439CONFIG_SYSFS=y
440CONFIG_DEVFS_FS=y
441CONFIG_DEVFS_MOUNT=y
442# CONFIG_DEVFS_DEBUG is not set
443# CONFIG_TMPFS is not set
444# CONFIG_HUGETLBFS is not set
445# CONFIG_HUGETLB_PAGE is not set
446CONFIG_RAMFS=y
447
448#
449# Miscellaneous filesystems
450#
451# CONFIG_ADFS_FS is not set
452# CONFIG_AFFS_FS is not set
453# CONFIG_HFS_FS is not set
454# CONFIG_HFSPLUS_FS is not set
455# CONFIG_BEFS_FS is not set
456# CONFIG_BFS_FS is not set
457# CONFIG_EFS_FS is not set
458# CONFIG_CRAMFS is not set
459# CONFIG_VXFS_FS is not set
460# CONFIG_HPFS_FS is not set
461# CONFIG_QNX4FS_FS is not set
462# CONFIG_SYSV_FS is not set
463# CONFIG_UFS_FS is not set
464
465#
466# Partition Types
467#
468# CONFIG_PARTITION_ADVANCED is not set
469CONFIG_MSDOS_PARTITION=y
470
471#
472# Native Language Support
473#
474# CONFIG_NLS is not set
475
476#
477# Profiling support
478#
479# CONFIG_PROFILING is not set
480
481#
482# Kernel hacking
483#
484# CONFIG_DEBUG_KERNEL is not set
485# CONFIG_FRAME_POINTER is not set
486CONFIG_SH_STANDARD_BIOS=y
487CONFIG_EARLY_PRINTK=y
488CONFIG_KGDB=y
489
490#
491# KGDB configuration options
492#
493# CONFIG_MORE_COMPILE_OPTIONS is not set
494# CONFIG_KGDB_NMI is not set
495# CONFIG_KGDB_THREAD is not set
496# CONFIG_SH_KGDB_CONSOLE is not set
497# CONFIG_KGDB_SYSRQ is not set
498# CONFIG_KGDB_KERNEL_ASSERTS is not set
499
500#
501# Serial port setup
502#
503CONFIG_KGDB_DEFPORT=1
504CONFIG_KGDB_DEFBAUD=115200
505CONFIG_KGDB_DEFPARITY_N=y
506# CONFIG_KGDB_DEFPARITY_E is not set
507# CONFIG_KGDB_DEFPARITY_O is not set
508CONFIG_KGDB_DEFBITS_8=y
509# CONFIG_KGDB_DEFBITS_7 is not set
510
511#
512# Security options
513#
514# CONFIG_KEYS is not set
515# CONFIG_SECURITY is not set
516
517#
518# Cryptographic options
519#
520# CONFIG_CRYPTO is not set
521
522#
523# Hardware crypto devices
524#
525
526#
527# Library routines
528#
529# CONFIG_CRC_CCITT is not set
530CONFIG_CRC32=y
531# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se73180_defconfig b/arch/sh/configs/se73180_defconfig
new file mode 100644
index 000000000000..d217e44c89a6
--- /dev/null
+++ b/arch/sh/configs/se73180_defconfig
@@ -0,0 +1,496 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:44 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25# CONFIG_SYSVIPC is not set
26# CONFIG_BSD_PROCESS_ACCT is not set
27# CONFIG_SYSCTL is not set
28# CONFIG_AUDIT is not set
29CONFIG_LOG_BUF_SHIFT=14
30# CONFIG_HOTPLUG is not set
31# CONFIG_IKCONFIG is not set
32CONFIG_EMBEDDED=y
33# CONFIG_KALLSYMS is not set
34# CONFIG_FUTEX is not set
35# CONFIG_EPOLL is not set
36# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
37CONFIG_SHMEM=y
38CONFIG_CC_ALIGN_FUNCTIONS=0
39CONFIG_CC_ALIGN_LABELS=0
40CONFIG_CC_ALIGN_LOOPS=0
41CONFIG_CC_ALIGN_JUMPS=0
42# CONFIG_TINY_SHMEM is not set
43
44#
45# Loadable module support
46#
47CONFIG_MODULES=y
48# CONFIG_MODULE_UNLOAD is not set
49CONFIG_OBSOLETE_MODPARM=y
50# CONFIG_MODVERSIONS is not set
51# CONFIG_MODULE_SRCVERSION_ALL is not set
52# CONFIG_KMOD is not set
53
54#
55# System type
56#
57# CONFIG_SH_SOLUTION_ENGINE is not set
58# CONFIG_SH_7751_SOLUTION_ENGINE is not set
59# CONFIG_SH_7300_SOLUTION_ENGINE is not set
60CONFIG_SH_73180_SOLUTION_ENGINE=y
61# CONFIG_SH_7751_SYSTEMH is not set
62# CONFIG_SH_STB1_HARP is not set
63# CONFIG_SH_STB1_OVERDRIVE is not set
64# CONFIG_SH_HP620 is not set
65# CONFIG_SH_HP680 is not set
66# CONFIG_SH_HP690 is not set
67# CONFIG_SH_CQREEK is not set
68# CONFIG_SH_DMIDA is not set
69# CONFIG_SH_EC3104 is not set
70# CONFIG_SH_SATURN is not set
71# CONFIG_SH_DREAMCAST is not set
72# CONFIG_SH_CAT68701 is not set
73# CONFIG_SH_BIGSUR is not set
74# CONFIG_SH_SH2000 is not set
75# CONFIG_SH_ADX is not set
76# CONFIG_SH_MPC1211 is not set
77# CONFIG_SH_SH03 is not set
78# CONFIG_SH_SECUREEDGE5410 is not set
79# CONFIG_SH_HS7751RVOIP is not set
80# CONFIG_SH_RTS7751R2D is not set
81# CONFIG_SH_EDOSK7705 is not set
82# CONFIG_SH_SH4202_MICRODEV is not set
83# CONFIG_SH_UNKNOWN is not set
84# CONFIG_CPU_SH2 is not set
85# CONFIG_CPU_SH3 is not set
86CONFIG_CPU_SH4=y
87# CONFIG_CPU_SUBTYPE_SH7604 is not set
88# CONFIG_CPU_SUBTYPE_SH7300 is not set
89# CONFIG_CPU_SUBTYPE_SH7705 is not set
90# CONFIG_CPU_SUBTYPE_SH7707 is not set
91# CONFIG_CPU_SUBTYPE_SH7708 is not set
92# CONFIG_CPU_SUBTYPE_SH7709 is not set
93# CONFIG_CPU_SUBTYPE_SH7750 is not set
94# CONFIG_CPU_SUBTYPE_SH7751 is not set
95# CONFIG_CPU_SUBTYPE_SH7760 is not set
96CONFIG_CPU_SUBTYPE_SH73180=y
97# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
98# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
99# CONFIG_CPU_SUBTYPE_SH4_202 is not set
100CONFIG_MMU=y
101CONFIG_CMDLINE_BOOL=y
102CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram"
103CONFIG_MEMORY_START=0x0c000000
104CONFIG_MEMORY_SIZE=0x02000000
105# CONFIG_MEMORY_OVERRIDE is not set
106# CONFIG_SH_FPU is not set
107CONFIG_ZERO_PAGE_OFFSET=0x00010000
108CONFIG_BOOT_LINK_OFFSET=0x00800000
109CONFIG_CPU_LITTLE_ENDIAN=y
110# CONFIG_PREEMPT is not set
111# CONFIG_UBC_WAKEUP is not set
112# CONFIG_SH_WRITETHROUGH is not set
113# CONFIG_SH_OCRAM is not set
114# CONFIG_SH_STORE_QUEUES is not set
115# CONFIG_SMP is not set
116# CONFIG_SH_PCLK_CALC is not set
117CONFIG_SH_PCLK_FREQ=27000000
118
119#
120# CPU Frequency scaling
121#
122# CONFIG_CPU_FREQ is not set
123
124#
125# DMA support
126#
127# CONFIG_SH_DMA is not set
128
129#
130# Companion Chips
131#
132# CONFIG_HD6446X_SERIES is not set
133CONFIG_HEARTBEAT=y
134
135#
136# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
137#
138# CONFIG_PCI is not set
139
140#
141# PCCARD (PCMCIA/CardBus) support
142#
143# CONFIG_PCCARD is not set
144
145#
146# PC-card bridges
147#
148
149#
150# PCI Hotplug Support
151#
152
153#
154# Executable file formats
155#
156CONFIG_BINFMT_ELF=y
157# CONFIG_BINFMT_FLAT is not set
158# CONFIG_BINFMT_MISC is not set
159
160#
161# SH initrd options
162#
163CONFIG_EMBEDDED_RAMDISK=y
164CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
165
166#
167# Device Drivers
168#
169
170#
171# Generic Driver Options
172#
173CONFIG_STANDALONE=y
174CONFIG_PREVENT_FIRMWARE_BUILD=y
175# CONFIG_FW_LOADER is not set
176
177#
178# Memory Technology Devices (MTD)
179#
180# CONFIG_MTD is not set
181
182#
183# Parallel port support
184#
185# CONFIG_PARPORT is not set
186
187#
188# Plug and Play support
189#
190
191#
192# Block devices
193#
194# CONFIG_BLK_DEV_FD is not set
195# CONFIG_BLK_DEV_COW_COMMON is not set
196CONFIG_BLK_DEV_LOOP=y
197# CONFIG_BLK_DEV_CRYPTOLOOP is not set
198CONFIG_BLK_DEV_RAM=y
199CONFIG_BLK_DEV_RAM_COUNT=16
200CONFIG_BLK_DEV_RAM_SIZE=4096
201CONFIG_BLK_DEV_INITRD=y
202CONFIG_INITRAMFS_SOURCE=""
203# CONFIG_LBD is not set
204# CONFIG_CDROM_PKTCDVD is not set
205
206#
207# IO Schedulers
208#
209CONFIG_IOSCHED_NOOP=y
210# CONFIG_IOSCHED_AS is not set
211# CONFIG_IOSCHED_DEADLINE is not set
212# CONFIG_IOSCHED_CFQ is not set
213
214#
215# ATA/ATAPI/MFM/RLL support
216#
217# CONFIG_IDE is not set
218
219#
220# SCSI device support
221#
222# CONFIG_SCSI is not set
223
224#
225# Multi-device support (RAID and LVM)
226#
227# CONFIG_MD is not set
228
229#
230# Fusion MPT device support
231#
232
233#
234# IEEE 1394 (FireWire) support
235#
236
237#
238# I2O device support
239#
240
241#
242# Networking support
243#
244# CONFIG_NET is not set
245# CONFIG_NETPOLL is not set
246# CONFIG_NET_POLL_CONTROLLER is not set
247
248#
249# ISDN subsystem
250#
251
252#
253# Telephony Support
254#
255# CONFIG_PHONE is not set
256
257#
258# Input device support
259#
260# CONFIG_INPUT is not set
261
262#
263# Userland interfaces
264#
265
266#
267# Input I/O drivers
268#
269# CONFIG_GAMEPORT is not set
270CONFIG_SOUND_GAMEPORT=y
271# CONFIG_SERIO is not set
272# CONFIG_SERIO_I8042 is not set
273
274#
275# Input Device Drivers
276#
277
278#
279# Character devices
280#
281# CONFIG_VT is not set
282# CONFIG_SERIAL_NONSTANDARD is not set
283
284#
285# Serial drivers
286#
287# CONFIG_SERIAL_8250 is not set
288
289#
290# Non-8250 serial port support
291#
292CONFIG_SERIAL_SH_SCI=y
293CONFIG_SERIAL_SH_SCI_CONSOLE=y
294CONFIG_SERIAL_CORE=y
295CONFIG_SERIAL_CORE_CONSOLE=y
296# CONFIG_UNIX98_PTYS is not set
297# CONFIG_LEGACY_PTYS is not set
298
299#
300# IPMI
301#
302# CONFIG_IPMI_HANDLER is not set
303
304#
305# Watchdog Cards
306#
307CONFIG_WATCHDOG=y
308# CONFIG_WATCHDOG_NOWAYOUT is not set
309
310#
311# Watchdog Device Drivers
312#
313# CONFIG_SOFT_WATCHDOG is not set
314# CONFIG_SH_WDT is not set
315# CONFIG_RTC is not set
316# CONFIG_GEN_RTC is not set
317# CONFIG_DTLK is not set
318# CONFIG_R3964 is not set
319
320#
321# Ftape, the floppy tape device driver
322#
323# CONFIG_DRM is not set
324# CONFIG_RAW_DRIVER is not set
325
326#
327# I2C support
328#
329# CONFIG_I2C is not set
330
331#
332# Dallas's 1-wire bus
333#
334# CONFIG_W1 is not set
335
336#
337# Misc devices
338#
339
340#
341# Multimedia devices
342#
343# CONFIG_VIDEO_DEV is not set
344
345#
346# Digital Video Broadcasting Devices
347#
348
349#
350# Graphics support
351#
352# CONFIG_FB is not set
353
354#
355# Sound
356#
357# CONFIG_SOUND is not set
358
359#
360# USB support
361#
362# CONFIG_USB_ARCH_HAS_HCD is not set
363# CONFIG_USB_ARCH_HAS_OHCI is not set
364
365#
366# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
367#
368
369#
370# USB Gadget Support
371#
372# CONFIG_USB_GADGET is not set
373
374#
375# MMC/SD Card support
376#
377# CONFIG_MMC is not set
378
379#
380# InfiniBand support
381#
382# CONFIG_INFINIBAND is not set
383
384#
385# File systems
386#
387CONFIG_EXT2_FS=y
388# CONFIG_EXT2_FS_XATTR is not set
389# CONFIG_EXT3_FS is not set
390# CONFIG_JBD is not set
391# CONFIG_REISERFS_FS is not set
392# CONFIG_JFS_FS is not set
393
394#
395# XFS support
396#
397# CONFIG_XFS_FS is not set
398# CONFIG_MINIX_FS is not set
399# CONFIG_ROMFS_FS is not set
400# CONFIG_QUOTA is not set
401CONFIG_DNOTIFY=y
402# CONFIG_AUTOFS_FS is not set
403# CONFIG_AUTOFS4_FS is not set
404
405#
406# CD-ROM/DVD Filesystems
407#
408# CONFIG_ISO9660_FS is not set
409# CONFIG_UDF_FS is not set
410
411#
412# DOS/FAT/NT Filesystems
413#
414# CONFIG_MSDOS_FS is not set
415# CONFIG_VFAT_FS is not set
416# CONFIG_NTFS_FS is not set
417
418#
419# Pseudo filesystems
420#
421CONFIG_PROC_FS=y
422CONFIG_PROC_KCORE=y
423# CONFIG_SYSFS is not set
424CONFIG_DEVFS_FS=y
425CONFIG_DEVFS_MOUNT=y
426# CONFIG_DEVFS_DEBUG is not set
427CONFIG_TMPFS=y
428# CONFIG_TMPFS_XATTR is not set
429# CONFIG_HUGETLBFS is not set
430# CONFIG_HUGETLB_PAGE is not set
431CONFIG_RAMFS=y
432
433#
434# Miscellaneous filesystems
435#
436# CONFIG_ADFS_FS is not set
437# CONFIG_AFFS_FS is not set
438# CONFIG_HFS_FS is not set
439# CONFIG_HFSPLUS_FS is not set
440# CONFIG_BEFS_FS is not set
441# CONFIG_BFS_FS is not set
442# CONFIG_EFS_FS is not set
443# CONFIG_CRAMFS is not set
444# CONFIG_VXFS_FS is not set
445# CONFIG_HPFS_FS is not set
446# CONFIG_QNX4FS_FS is not set
447# CONFIG_SYSV_FS is not set
448# CONFIG_UFS_FS is not set
449
450#
451# Partition Types
452#
453# CONFIG_PARTITION_ADVANCED is not set
454CONFIG_MSDOS_PARTITION=y
455
456#
457# Native Language Support
458#
459# CONFIG_NLS is not set
460
461#
462# Profiling support
463#
464# CONFIG_PROFILING is not set
465
466#
467# Kernel hacking
468#
469# CONFIG_DEBUG_KERNEL is not set
470# CONFIG_FRAME_POINTER is not set
471CONFIG_SH_STANDARD_BIOS=y
472# CONFIG_EARLY_SCIF_CONSOLE is not set
473# CONFIG_EARLY_PRINTK is not set
474# CONFIG_KGDB is not set
475
476#
477# Security options
478#
479# CONFIG_KEYS is not set
480# CONFIG_SECURITY is not set
481
482#
483# Cryptographic options
484#
485# CONFIG_CRYPTO is not set
486
487#
488# Hardware crypto devices
489#
490
491#
492# Library routines
493#
494# CONFIG_CRC_CCITT is not set
495CONFIG_CRC32=y
496# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
new file mode 100644
index 000000000000..e4a14602b169
--- /dev/null
+++ b/arch/sh/configs/se7705_defconfig
@@ -0,0 +1,714 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:45 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19CONFIG_LOCK_KERNEL=y
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25# CONFIG_SWAP is not set
26# CONFIG_SYSVIPC is not set
27# CONFIG_POSIX_MQUEUE is not set
28# CONFIG_BSD_PROCESS_ACCT is not set
29# CONFIG_SYSCTL is not set
30# CONFIG_AUDIT is not set
31CONFIG_LOG_BUF_SHIFT=14
32# CONFIG_HOTPLUG is not set
33CONFIG_KOBJECT_UEVENT=y
34# CONFIG_IKCONFIG is not set
35CONFIG_EMBEDDED=y
36# CONFIG_KALLSYMS is not set
37CONFIG_FUTEX=y
38CONFIG_EPOLL=y
39# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
40CONFIG_SHMEM=y
41CONFIG_CC_ALIGN_FUNCTIONS=0
42CONFIG_CC_ALIGN_LABELS=0
43CONFIG_CC_ALIGN_LOOPS=0
44CONFIG_CC_ALIGN_JUMPS=0
45# CONFIG_TINY_SHMEM is not set
46
47#
48# Loadable module support
49#
50CONFIG_MODULES=y
51# CONFIG_MODULE_UNLOAD is not set
52CONFIG_OBSOLETE_MODPARM=y
53# CONFIG_MODVERSIONS is not set
54# CONFIG_MODULE_SRCVERSION_ALL is not set
55CONFIG_KMOD=y
56
57#
58# System type
59#
60CONFIG_SH_SOLUTION_ENGINE=y
61# CONFIG_SH_7751_SOLUTION_ENGINE is not set
62# CONFIG_SH_7300_SOLUTION_ENGINE is not set
63# CONFIG_SH_73180_SOLUTION_ENGINE is not set
64# CONFIG_SH_7751_SYSTEMH is not set
65# CONFIG_SH_STB1_HARP is not set
66# CONFIG_SH_STB1_OVERDRIVE is not set
67# CONFIG_SH_HP620 is not set
68# CONFIG_SH_HP680 is not set
69# CONFIG_SH_HP690 is not set
70# CONFIG_SH_CQREEK is not set
71# CONFIG_SH_DMIDA is not set
72# CONFIG_SH_EC3104 is not set
73# CONFIG_SH_SATURN is not set
74# CONFIG_SH_DREAMCAST is not set
75# CONFIG_SH_CAT68701 is not set
76# CONFIG_SH_BIGSUR is not set
77# CONFIG_SH_SH2000 is not set
78# CONFIG_SH_ADX is not set
79# CONFIG_SH_MPC1211 is not set
80# CONFIG_SH_SH03 is not set
81# CONFIG_SH_SECUREEDGE5410 is not set
82# CONFIG_SH_HS7751RVOIP is not set
83# CONFIG_SH_RTS7751R2D is not set
84# CONFIG_SH_EDOSK7705 is not set
85# CONFIG_SH_SH4202_MICRODEV is not set
86# CONFIG_SH_UNKNOWN is not set
87# CONFIG_CPU_SH2 is not set
88CONFIG_CPU_SH3=y
89# CONFIG_CPU_SH4 is not set
90# CONFIG_CPU_SUBTYPE_SH7604 is not set
91# CONFIG_CPU_SUBTYPE_SH7300 is not set
92CONFIG_CPU_SUBTYPE_SH7705=y
93# CONFIG_CPU_SUBTYPE_SH7707 is not set
94# CONFIG_CPU_SUBTYPE_SH7708 is not set
95# CONFIG_CPU_SUBTYPE_SH7709 is not set
96# CONFIG_CPU_SUBTYPE_SH7750 is not set
97# CONFIG_CPU_SUBTYPE_SH7751 is not set
98# CONFIG_CPU_SUBTYPE_SH7760 is not set
99# CONFIG_CPU_SUBTYPE_SH73180 is not set
100# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
101# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
102# CONFIG_CPU_SUBTYPE_SH4_202 is not set
103CONFIG_SH7705_CACHE_32KB=y
104CONFIG_MMU=y
105# CONFIG_CMDLINE_BOOL is not set
106CONFIG_MEMORY_START=0x0c000000
107CONFIG_MEMORY_SIZE=0x02000000
108CONFIG_MEMORY_SET=y
109# CONFIG_MEMORY_OVERRIDE is not set
110# CONFIG_CF_ENABLER is not set
111CONFIG_SH_RTC=y
112# CONFIG_SH_DSP is not set
113# CONFIG_SH_ADC is not set
114CONFIG_ZERO_PAGE_OFFSET=0x00001000
115CONFIG_BOOT_LINK_OFFSET=0x00800000
116CONFIG_CPU_LITTLE_ENDIAN=y
117CONFIG_PREEMPT=y
118# CONFIG_UBC_WAKEUP is not set
119# CONFIG_SH_WRITETHROUGH is not set
120# CONFIG_SH_OCRAM is not set
121# CONFIG_SMP is not set
122CONFIG_SH_PCLK_CALC=y
123CONFIG_SH_PCLK_FREQ=33333333
124
125#
126# CPU Frequency scaling
127#
128# CONFIG_CPU_FREQ is not set
129
130#
131# DMA support
132#
133# CONFIG_SH_DMA is not set
134
135#
136# Companion Chips
137#
138# CONFIG_HD6446X_SERIES is not set
139CONFIG_HEARTBEAT=y
140
141#
142# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
143#
144# CONFIG_PCI is not set
145
146#
147# PCCARD (PCMCIA/CardBus) support
148#
149# CONFIG_PCCARD is not set
150
151#
152# PC-card bridges
153#
154
155#
156# PCI Hotplug Support
157#
158
159#
160# Executable file formats
161#
162CONFIG_BINFMT_ELF=y
163# CONFIG_BINFMT_FLAT is not set
164# CONFIG_BINFMT_MISC is not set
165
166#
167# SH initrd options
168#
169# CONFIG_EMBEDDED_RAMDISK is not set
170
171#
172# Device Drivers
173#
174
175#
176# Generic Driver Options
177#
178CONFIG_STANDALONE=y
179CONFIG_PREVENT_FIRMWARE_BUILD=y
180# CONFIG_FW_LOADER is not set
181
182#
183# Memory Technology Devices (MTD)
184#
185CONFIG_MTD=y
186# CONFIG_MTD_DEBUG is not set
187CONFIG_MTD_PARTITIONS=y
188# CONFIG_MTD_CONCAT is not set
189# CONFIG_MTD_REDBOOT_PARTS is not set
190# CONFIG_MTD_CMDLINE_PARTS is not set
191
192#
193# User Modules And Translation Layers
194#
195CONFIG_MTD_CHAR=y
196CONFIG_MTD_BLOCK=y
197# CONFIG_FTL is not set
198# CONFIG_NFTL is not set
199# CONFIG_INFTL is not set
200
201#
202# RAM/ROM/Flash chip drivers
203#
204CONFIG_MTD_CFI=y
205# CONFIG_MTD_JEDECPROBE is not set
206CONFIG_MTD_GEN_PROBE=y
207# CONFIG_MTD_CFI_ADV_OPTIONS is not set
208CONFIG_MTD_MAP_BANK_WIDTH_1=y
209CONFIG_MTD_MAP_BANK_WIDTH_2=y
210CONFIG_MTD_MAP_BANK_WIDTH_4=y
211# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
212# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
213# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
214CONFIG_MTD_CFI_I1=y
215CONFIG_MTD_CFI_I2=y
216# CONFIG_MTD_CFI_I4 is not set
217# CONFIG_MTD_CFI_I8 is not set
218# CONFIG_MTD_CFI_INTELEXT is not set
219CONFIG_MTD_CFI_AMDSTD=y
220CONFIG_MTD_CFI_AMDSTD_RETRY=0
221# CONFIG_MTD_CFI_STAA is not set
222CONFIG_MTD_CFI_UTIL=y
223# CONFIG_MTD_RAM is not set
224# CONFIG_MTD_ROM is not set
225# CONFIG_MTD_ABSENT is not set
226
227#
228# Mapping drivers for chip access
229#
230# CONFIG_MTD_COMPLEX_MAPPINGS is not set
231# CONFIG_MTD_PHYSMAP is not set
232CONFIG_MTD_SOLUTIONENGINE=y
233CONFIG_MTD_SUPERH_RESERVE=0x300000
234# CONFIG_MTD_MPC1211 is not set
235# CONFIG_MTD_RTS7751R2D is not set
236
237#
238# Self-contained MTD device drivers
239#
240# CONFIG_MTD_SLRAM is not set
241# CONFIG_MTD_PHRAM is not set
242# CONFIG_MTD_MTDRAM is not set
243# CONFIG_MTD_BLKMTD is not set
244# CONFIG_MTD_BLOCK2MTD is not set
245
246#
247# Disk-On-Chip Device Drivers
248#
249# CONFIG_MTD_DOC2000 is not set
250# CONFIG_MTD_DOC2001 is not set
251# CONFIG_MTD_DOC2001PLUS is not set
252
253#
254# NAND Flash Device Drivers
255#
256# CONFIG_MTD_NAND is not set
257
258#
259# Parallel port support
260#
261# CONFIG_PARPORT is not set
262
263#
264# Plug and Play support
265#
266
267#
268# Block devices
269#
270# CONFIG_BLK_DEV_FD is not set
271# CONFIG_BLK_DEV_COW_COMMON is not set
272# CONFIG_BLK_DEV_LOOP is not set
273# CONFIG_BLK_DEV_NBD is not set
274CONFIG_BLK_DEV_RAM=y
275CONFIG_BLK_DEV_RAM_COUNT=16
276CONFIG_BLK_DEV_RAM_SIZE=8192
277CONFIG_BLK_DEV_INITRD=y
278CONFIG_INITRAMFS_SOURCE=""
279# CONFIG_LBD is not set
280# CONFIG_CDROM_PKTCDVD is not set
281
282#
283# IO Schedulers
284#
285CONFIG_IOSCHED_NOOP=y
286CONFIG_IOSCHED_AS=y
287# CONFIG_IOSCHED_DEADLINE is not set
288# CONFIG_IOSCHED_CFQ is not set
289# CONFIG_ATA_OVER_ETH is not set
290
291#
292# ATA/ATAPI/MFM/RLL support
293#
294# CONFIG_IDE is not set
295
296#
297# SCSI device support
298#
299# CONFIG_SCSI is not set
300
301#
302# Multi-device support (RAID and LVM)
303#
304# CONFIG_MD is not set
305
306#
307# Fusion MPT device support
308#
309
310#
311# IEEE 1394 (FireWire) support
312#
313
314#
315# I2O device support
316#
317
318#
319# Networking support
320#
321CONFIG_NET=y
322
323#
324# Networking options
325#
326CONFIG_PACKET=y
327# CONFIG_PACKET_MMAP is not set
328# CONFIG_NETLINK_DEV is not set
329CONFIG_UNIX=y
330# CONFIG_NET_KEY is not set
331CONFIG_INET=y
332# CONFIG_IP_MULTICAST is not set
333# CONFIG_IP_ADVANCED_ROUTER is not set
334CONFIG_IP_PNP=y
335CONFIG_IP_PNP_DHCP=y
336CONFIG_IP_PNP_BOOTP=y
337CONFIG_IP_PNP_RARP=y
338# CONFIG_NET_IPIP is not set
339# CONFIG_NET_IPGRE is not set
340# CONFIG_ARPD is not set
341# CONFIG_SYN_COOKIES is not set
342# CONFIG_INET_AH is not set
343# CONFIG_INET_ESP is not set
344# CONFIG_INET_IPCOMP is not set
345# CONFIG_INET_TUNNEL is not set
346CONFIG_IP_TCPDIAG=y
347# CONFIG_IP_TCPDIAG_IPV6 is not set
348# CONFIG_IPV6 is not set
349# CONFIG_NETFILTER is not set
350
351#
352# SCTP Configuration (EXPERIMENTAL)
353#
354# CONFIG_IP_SCTP is not set
355# CONFIG_ATM is not set
356# CONFIG_BRIDGE is not set
357# CONFIG_VLAN_8021Q is not set
358# CONFIG_DECNET is not set
359# CONFIG_LLC2 is not set
360# CONFIG_IPX is not set
361# CONFIG_ATALK is not set
362# CONFIG_X25 is not set
363# CONFIG_LAPB is not set
364# CONFIG_NET_DIVERT is not set
365# CONFIG_ECONET is not set
366# CONFIG_WAN_ROUTER is not set
367
368#
369# QoS and/or fair queueing
370#
371# CONFIG_NET_SCHED is not set
372# CONFIG_NET_CLS_ROUTE is not set
373
374#
375# Network testing
376#
377# CONFIG_NET_PKTGEN is not set
378# CONFIG_NETPOLL is not set
379# CONFIG_NET_POLL_CONTROLLER is not set
380# CONFIG_HAMRADIO is not set
381# CONFIG_IRDA is not set
382# CONFIG_BT is not set
383CONFIG_NETDEVICES=y
384# CONFIG_DUMMY is not set
385# CONFIG_BONDING is not set
386# CONFIG_EQUALIZER is not set
387# CONFIG_TUN is not set
388
389#
390# Ethernet (10 or 100Mbit)
391#
392CONFIG_NET_ETHERNET=y
393# CONFIG_MII is not set
394CONFIG_STNIC=y
395# CONFIG_SMC91X is not set
396
397#
398# Ethernet (1000 Mbit)
399#
400
401#
402# Ethernet (10000 Mbit)
403#
404
405#
406# Token Ring devices
407#
408
409#
410# Wireless LAN (non-hamradio)
411#
412# CONFIG_NET_RADIO is not set
413
414#
415# Wan interfaces
416#
417# CONFIG_WAN is not set
418CONFIG_PPP=y
419# CONFIG_PPP_MULTILINK is not set
420# CONFIG_PPP_FILTER is not set
421CONFIG_PPP_ASYNC=y
422# CONFIG_PPP_SYNC_TTY is not set
423CONFIG_PPP_DEFLATE=y
424# CONFIG_PPP_BSDCOMP is not set
425# CONFIG_PPPOE is not set
426# CONFIG_SLIP is not set
427# CONFIG_SHAPER is not set
428# CONFIG_NETCONSOLE is not set
429
430#
431# ISDN subsystem
432#
433# CONFIG_ISDN is not set
434
435#
436# Telephony Support
437#
438# CONFIG_PHONE is not set
439
440#
441# Input device support
442#
443CONFIG_INPUT=y
444
445#
446# Userland interfaces
447#
448# CONFIG_INPUT_MOUSEDEV is not set
449# CONFIG_INPUT_JOYDEV is not set
450# CONFIG_INPUT_TSDEV is not set
451# CONFIG_INPUT_EVDEV is not set
452# CONFIG_INPUT_EVBUG is not set
453
454#
455# Input I/O drivers
456#
457# CONFIG_GAMEPORT is not set
458CONFIG_SOUND_GAMEPORT=y
459CONFIG_SERIO=y
460# CONFIG_SERIO_I8042 is not set
461# CONFIG_SERIO_SERPORT is not set
462# CONFIG_SERIO_CT82C710 is not set
463# CONFIG_SERIO_LIBPS2 is not set
464# CONFIG_SERIO_RAW is not set
465
466#
467# Input Device Drivers
468#
469# CONFIG_INPUT_KEYBOARD is not set
470# CONFIG_INPUT_MOUSE is not set
471# CONFIG_INPUT_JOYSTICK is not set
472# CONFIG_INPUT_TOUCHSCREEN is not set
473# CONFIG_INPUT_MISC is not set
474
475#
476# Character devices
477#
478# CONFIG_VT is not set
479# CONFIG_SERIAL_NONSTANDARD is not set
480
481#
482# Serial drivers
483#
484# CONFIG_SERIAL_8250 is not set
485
486#
487# Non-8250 serial port support
488#
489CONFIG_SERIAL_SH_SCI=y
490CONFIG_SERIAL_SH_SCI_CONSOLE=y
491CONFIG_SERIAL_CORE=y
492CONFIG_SERIAL_CORE_CONSOLE=y
493CONFIG_UNIX98_PTYS=y
494# CONFIG_LEGACY_PTYS is not set
495
496#
497# IPMI
498#
499# CONFIG_IPMI_HANDLER is not set
500
501#
502# Watchdog Cards
503#
504# CONFIG_WATCHDOG is not set
505# CONFIG_RTC is not set
506# CONFIG_GEN_RTC is not set
507# CONFIG_DTLK is not set
508# CONFIG_R3964 is not set
509
510#
511# Ftape, the floppy tape device driver
512#
513# CONFIG_DRM is not set
514# CONFIG_RAW_DRIVER is not set
515
516#
517# I2C support
518#
519# CONFIG_I2C is not set
520
521#
522# Dallas's 1-wire bus
523#
524# CONFIG_W1 is not set
525
526#
527# Misc devices
528#
529
530#
531# Multimedia devices
532#
533# CONFIG_VIDEO_DEV is not set
534
535#
536# Digital Video Broadcasting Devices
537#
538# CONFIG_DVB is not set
539
540#
541# Graphics support
542#
543# CONFIG_FB is not set
544
545#
546# Sound
547#
548# CONFIG_SOUND is not set
549
550#
551# USB support
552#
553# CONFIG_USB_ARCH_HAS_HCD is not set
554# CONFIG_USB_ARCH_HAS_OHCI is not set
555
556#
557# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
558#
559
560#
561# USB Gadget Support
562#
563# CONFIG_USB_GADGET is not set
564
565#
566# MMC/SD Card support
567#
568# CONFIG_MMC is not set
569
570#
571# InfiniBand support
572#
573# CONFIG_INFINIBAND is not set
574
575#
576# File systems
577#
578CONFIG_EXT2_FS=y
579# CONFIG_EXT2_FS_XATTR is not set
580# CONFIG_EXT3_FS is not set
581# CONFIG_JBD is not set
582# CONFIG_REISERFS_FS is not set
583# CONFIG_JFS_FS is not set
584
585#
586# XFS support
587#
588# CONFIG_XFS_FS is not set
589# CONFIG_MINIX_FS is not set
590# CONFIG_ROMFS_FS is not set
591# CONFIG_QUOTA is not set
592CONFIG_DNOTIFY=y
593# CONFIG_AUTOFS_FS is not set
594# CONFIG_AUTOFS4_FS is not set
595
596#
597# CD-ROM/DVD Filesystems
598#
599# CONFIG_ISO9660_FS is not set
600# CONFIG_UDF_FS is not set
601
602#
603# DOS/FAT/NT Filesystems
604#
605# CONFIG_MSDOS_FS is not set
606# CONFIG_VFAT_FS is not set
607# CONFIG_NTFS_FS is not set
608
609#
610# Pseudo filesystems
611#
612CONFIG_PROC_FS=y
613CONFIG_PROC_KCORE=y
614# CONFIG_SYSFS is not set
615# CONFIG_DEVFS_FS is not set
616# CONFIG_DEVPTS_FS_XATTR is not set
617# CONFIG_TMPFS is not set
618# CONFIG_HUGETLBFS is not set
619# CONFIG_HUGETLB_PAGE is not set
620CONFIG_RAMFS=y
621
622#
623# Miscellaneous filesystems
624#
625# CONFIG_ADFS_FS is not set
626# CONFIG_AFFS_FS is not set
627# CONFIG_HFS_FS is not set
628# CONFIG_HFSPLUS_FS is not set
629# CONFIG_BEFS_FS is not set
630# CONFIG_BFS_FS is not set
631# CONFIG_EFS_FS is not set
632# CONFIG_JFFS_FS is not set
633CONFIG_JFFS2_FS=y
634CONFIG_JFFS2_FS_DEBUG=0
635# CONFIG_JFFS2_FS_NAND is not set
636# CONFIG_JFFS2_FS_NOR_ECC is not set
637# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
638CONFIG_JFFS2_ZLIB=y
639CONFIG_JFFS2_RTIME=y
640# CONFIG_JFFS2_RUBIN is not set
641# CONFIG_CRAMFS is not set
642# CONFIG_VXFS_FS is not set
643# CONFIG_HPFS_FS is not set
644# CONFIG_QNX4FS_FS is not set
645# CONFIG_SYSV_FS is not set
646# CONFIG_UFS_FS is not set
647
648#
649# Network File Systems
650#
651CONFIG_NFS_FS=y
652# CONFIG_NFS_V3 is not set
653# CONFIG_NFS_V4 is not set
654# CONFIG_NFS_DIRECTIO is not set
655# CONFIG_NFSD is not set
656CONFIG_ROOT_NFS=y
657CONFIG_LOCKD=y
658CONFIG_SUNRPC=y
659# CONFIG_RPCSEC_GSS_KRB5 is not set
660# CONFIG_RPCSEC_GSS_SPKM3 is not set
661# CONFIG_SMB_FS is not set
662# CONFIG_CIFS is not set
663# CONFIG_NCP_FS is not set
664# CONFIG_CODA_FS is not set
665# CONFIG_AFS_FS is not set
666
667#
668# Partition Types
669#
670# CONFIG_PARTITION_ADVANCED is not set
671CONFIG_MSDOS_PARTITION=y
672
673#
674# Native Language Support
675#
676# CONFIG_NLS is not set
677
678#
679# Profiling support
680#
681# CONFIG_PROFILING is not set
682
683#
684# Kernel hacking
685#
686# CONFIG_DEBUG_KERNEL is not set
687CONFIG_DEBUG_PREEMPT=y
688# CONFIG_FRAME_POINTER is not set
689# CONFIG_SH_STANDARD_BIOS is not set
690# CONFIG_KGDB is not set
691
692#
693# Security options
694#
695# CONFIG_KEYS is not set
696# CONFIG_SECURITY is not set
697
698#
699# Cryptographic options
700#
701# CONFIG_CRYPTO is not set
702
703#
704# Hardware crypto devices
705#
706
707#
708# Library routines
709#
710CONFIG_CRC_CCITT=y
711CONFIG_CRC32=y
712# CONFIG_LIBCRC32C is not set
713CONFIG_ZLIB_INFLATE=y
714CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
new file mode 100644
index 000000000000..6dc31584752a
--- /dev/null
+++ b/arch/sh/configs/se7750_defconfig
@@ -0,0 +1,713 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:46 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24# CONFIG_SWAP is not set
25CONFIG_SYSVIPC=y
26# CONFIG_POSIX_MQUEUE is not set
27CONFIG_BSD_PROCESS_ACCT=y
28# CONFIG_BSD_PROCESS_ACCT_V3 is not set
29CONFIG_SYSCTL=y
30# CONFIG_AUDIT is not set
31CONFIG_LOG_BUF_SHIFT=14
32# CONFIG_HOTPLUG is not set
33CONFIG_KOBJECT_UEVENT=y
34CONFIG_IKCONFIG=y
35CONFIG_IKCONFIG_PROC=y
36CONFIG_EMBEDDED=y
37CONFIG_KALLSYMS=y
38# CONFIG_KALLSYMS_EXTRA_PASS is not set
39CONFIG_FUTEX=y
40CONFIG_EPOLL=y
41# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
42CONFIG_SHMEM=y
43CONFIG_CC_ALIGN_FUNCTIONS=0
44CONFIG_CC_ALIGN_LABELS=0
45CONFIG_CC_ALIGN_LOOPS=0
46CONFIG_CC_ALIGN_JUMPS=0
47# CONFIG_TINY_SHMEM is not set
48
49#
50# Loadable module support
51#
52CONFIG_MODULES=y
53# CONFIG_MODULE_UNLOAD is not set
54CONFIG_OBSOLETE_MODPARM=y
55# CONFIG_MODVERSIONS is not set
56# CONFIG_MODULE_SRCVERSION_ALL is not set
57CONFIG_KMOD=y
58
59#
60# System type
61#
62CONFIG_SH_SOLUTION_ENGINE=y
63# CONFIG_SH_7751_SOLUTION_ENGINE is not set
64# CONFIG_SH_7300_SOLUTION_ENGINE is not set
65# CONFIG_SH_73180_SOLUTION_ENGINE is not set
66# CONFIG_SH_7751_SYSTEMH is not set
67# CONFIG_SH_STB1_HARP is not set
68# CONFIG_SH_STB1_OVERDRIVE is not set
69# CONFIG_SH_HP620 is not set
70# CONFIG_SH_HP680 is not set
71# CONFIG_SH_HP690 is not set
72# CONFIG_SH_CQREEK is not set
73# CONFIG_SH_DMIDA is not set
74# CONFIG_SH_EC3104 is not set
75# CONFIG_SH_SATURN is not set
76# CONFIG_SH_DREAMCAST is not set
77# CONFIG_SH_CAT68701 is not set
78# CONFIG_SH_BIGSUR is not set
79# CONFIG_SH_SH2000 is not set
80# CONFIG_SH_ADX is not set
81# CONFIG_SH_MPC1211 is not set
82# CONFIG_SH_SH03 is not set
83# CONFIG_SH_SECUREEDGE5410 is not set
84# CONFIG_SH_HS7751RVOIP is not set
85# CONFIG_SH_RTS7751R2D is not set
86# CONFIG_SH_EDOSK7705 is not set
87# CONFIG_SH_SH4202_MICRODEV is not set
88# CONFIG_SH_UNKNOWN is not set
89# CONFIG_CPU_SH2 is not set
90# CONFIG_CPU_SH3 is not set
91CONFIG_CPU_SH4=y
92# CONFIG_CPU_SUBTYPE_SH7604 is not set
93# CONFIG_CPU_SUBTYPE_SH7300 is not set
94# CONFIG_CPU_SUBTYPE_SH7705 is not set
95# CONFIG_CPU_SUBTYPE_SH7707 is not set
96# CONFIG_CPU_SUBTYPE_SH7708 is not set
97# CONFIG_CPU_SUBTYPE_SH7709 is not set
98CONFIG_CPU_SUBTYPE_SH7750=y
99# CONFIG_CPU_SUBTYPE_SH7751 is not set
100# CONFIG_CPU_SUBTYPE_SH7760 is not set
101# CONFIG_CPU_SUBTYPE_SH73180 is not set
102# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
103# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
104# CONFIG_CPU_SUBTYPE_SH4_202 is not set
105CONFIG_MMU=y
106CONFIG_CMDLINE_BOOL=y
107CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
108CONFIG_MEMORY_START=0x0c000000
109CONFIG_MEMORY_SIZE=0x02000000
110CONFIG_MEMORY_SET=y
111# CONFIG_MEMORY_OVERRIDE is not set
112CONFIG_CF_ENABLER=y
113# CONFIG_CF_AREA5 is not set
114CONFIG_CF_AREA6=y
115CONFIG_CF_BASE_ADDR=0xb8000000
116CONFIG_SH_RTC=y
117CONFIG_SH_FPU=y
118CONFIG_ZERO_PAGE_OFFSET=0x00001000
119CONFIG_BOOT_LINK_OFFSET=0x00800000
120CONFIG_CPU_LITTLE_ENDIAN=y
121# CONFIG_PREEMPT is not set
122# CONFIG_UBC_WAKEUP is not set
123# CONFIG_SH_WRITETHROUGH is not set
124# CONFIG_SH_OCRAM is not set
125# CONFIG_SH_STORE_QUEUES is not set
126# CONFIG_SMP is not set
127CONFIG_SH_PCLK_CALC=y
128CONFIG_SH_PCLK_FREQ=49876504
129
130#
131# CPU Frequency scaling
132#
133# CONFIG_CPU_FREQ is not set
134
135#
136# DMA support
137#
138# CONFIG_SH_DMA is not set
139
140#
141# Companion Chips
142#
143# CONFIG_HD6446X_SERIES is not set
144CONFIG_HEARTBEAT=y
145
146#
147# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
148#
149# CONFIG_PCI is not set
150
151#
152# PCCARD (PCMCIA/CardBus) support
153#
154# CONFIG_PCCARD is not set
155
156#
157# PC-card bridges
158#
159
160#
161# PCI Hotplug Support
162#
163
164#
165# Executable file formats
166#
167CONFIG_BINFMT_ELF=y
168# CONFIG_BINFMT_FLAT is not set
169# CONFIG_BINFMT_MISC is not set
170
171#
172# Device Drivers
173#
174
175#
176# Generic Driver Options
177#
178CONFIG_STANDALONE=y
179CONFIG_PREVENT_FIRMWARE_BUILD=y
180# CONFIG_FW_LOADER is not set
181
182#
183# Memory Technology Devices (MTD)
184#
185CONFIG_MTD=y
186# CONFIG_MTD_DEBUG is not set
187CONFIG_MTD_PARTITIONS=y
188# CONFIG_MTD_CONCAT is not set
189# CONFIG_MTD_REDBOOT_PARTS is not set
190# CONFIG_MTD_CMDLINE_PARTS is not set
191
192#
193# User Modules And Translation Layers
194#
195CONFIG_MTD_CHAR=y
196CONFIG_MTD_BLOCK=y
197# CONFIG_FTL is not set
198# CONFIG_NFTL is not set
199# CONFIG_INFTL is not set
200
201#
202# RAM/ROM/Flash chip drivers
203#
204CONFIG_MTD_CFI=y
205# CONFIG_MTD_JEDECPROBE is not set
206CONFIG_MTD_GEN_PROBE=y
207# CONFIG_MTD_CFI_ADV_OPTIONS is not set
208CONFIG_MTD_MAP_BANK_WIDTH_1=y
209CONFIG_MTD_MAP_BANK_WIDTH_2=y
210CONFIG_MTD_MAP_BANK_WIDTH_4=y
211# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
212# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
213# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
214CONFIG_MTD_CFI_I1=y
215CONFIG_MTD_CFI_I2=y
216# CONFIG_MTD_CFI_I4 is not set
217# CONFIG_MTD_CFI_I8 is not set
218# CONFIG_MTD_CFI_INTELEXT is not set
219CONFIG_MTD_CFI_AMDSTD=y
220CONFIG_MTD_CFI_AMDSTD_RETRY=0
221# CONFIG_MTD_CFI_STAA is not set
222CONFIG_MTD_CFI_UTIL=y
223# CONFIG_MTD_RAM is not set
224CONFIG_MTD_ROM=y
225# CONFIG_MTD_ABSENT is not set
226
227#
228# Mapping drivers for chip access
229#
230# CONFIG_MTD_COMPLEX_MAPPINGS is not set
231# CONFIG_MTD_PHYSMAP is not set
232CONFIG_MTD_SOLUTIONENGINE=y
233CONFIG_MTD_SUPERH_RESERVE=0x00010000
234# CONFIG_MTD_MPC1211 is not set
235# CONFIG_MTD_RTS7751R2D is not set
236
237#
238# Self-contained MTD device drivers
239#
240# CONFIG_MTD_SLRAM is not set
241# CONFIG_MTD_PHRAM is not set
242# CONFIG_MTD_MTDRAM is not set
243# CONFIG_MTD_BLKMTD is not set
244# CONFIG_MTD_BLOCK2MTD is not set
245
246#
247# Disk-On-Chip Device Drivers
248#
249# CONFIG_MTD_DOC2000 is not set
250# CONFIG_MTD_DOC2001 is not set
251# CONFIG_MTD_DOC2001PLUS is not set
252
253#
254# NAND Flash Device Drivers
255#
256# CONFIG_MTD_NAND is not set
257
258#
259# Parallel port support
260#
261# CONFIG_PARPORT is not set
262
263#
264# Plug and Play support
265#
266
267#
268# Block devices
269#
270# CONFIG_BLK_DEV_FD is not set
271# CONFIG_BLK_DEV_COW_COMMON is not set
272# CONFIG_BLK_DEV_LOOP is not set
273# CONFIG_BLK_DEV_NBD is not set
274# CONFIG_BLK_DEV_RAM is not set
275CONFIG_BLK_DEV_RAM_COUNT=16
276CONFIG_INITRAMFS_SOURCE=""
277# CONFIG_LBD is not set
278# CONFIG_CDROM_PKTCDVD is not set
279
280#
281# IO Schedulers
282#
283CONFIG_IOSCHED_NOOP=y
284CONFIG_IOSCHED_AS=y
285CONFIG_IOSCHED_DEADLINE=y
286CONFIG_IOSCHED_CFQ=y
287# CONFIG_ATA_OVER_ETH is not set
288
289#
290# ATA/ATAPI/MFM/RLL support
291#
292# CONFIG_IDE is not set
293
294#
295# SCSI device support
296#
297# CONFIG_SCSI is not set
298
299#
300# Multi-device support (RAID and LVM)
301#
302# CONFIG_MD is not set
303
304#
305# Fusion MPT device support
306#
307
308#
309# IEEE 1394 (FireWire) support
310#
311
312#
313# I2O device support
314#
315
316#
317# Networking support
318#
319CONFIG_NET=y
320
321#
322# Networking options
323#
324CONFIG_PACKET=y
325# CONFIG_PACKET_MMAP is not set
326# CONFIG_NETLINK_DEV is not set
327CONFIG_UNIX=y
328# CONFIG_NET_KEY is not set
329CONFIG_INET=y
330CONFIG_IP_MULTICAST=y
331# CONFIG_IP_ADVANCED_ROUTER is not set
332CONFIG_IP_PNP=y
333# CONFIG_IP_PNP_DHCP is not set
334CONFIG_IP_PNP_BOOTP=y
335# CONFIG_IP_PNP_RARP is not set
336# CONFIG_NET_IPIP is not set
337# CONFIG_NET_IPGRE is not set
338# CONFIG_IP_MROUTE is not set
339# CONFIG_ARPD is not set
340# CONFIG_SYN_COOKIES is not set
341# CONFIG_INET_AH is not set
342# CONFIG_INET_ESP is not set
343# CONFIG_INET_IPCOMP is not set
344# CONFIG_INET_TUNNEL is not set
345CONFIG_IP_TCPDIAG=y
346# CONFIG_IP_TCPDIAG_IPV6 is not set
347# CONFIG_IPV6 is not set
348# CONFIG_NETFILTER is not set
349
350#
351# SCTP Configuration (EXPERIMENTAL)
352#
353# CONFIG_IP_SCTP is not set
354# CONFIG_ATM is not set
355# CONFIG_BRIDGE is not set
356# CONFIG_VLAN_8021Q is not set
357# CONFIG_DECNET is not set
358# CONFIG_LLC2 is not set
359# CONFIG_IPX is not set
360# CONFIG_ATALK is not set
361# CONFIG_X25 is not set
362# CONFIG_LAPB is not set
363# CONFIG_NET_DIVERT is not set
364# CONFIG_ECONET is not set
365# CONFIG_WAN_ROUTER is not set
366
367#
368# QoS and/or fair queueing
369#
370# CONFIG_NET_SCHED is not set
371# CONFIG_NET_CLS_ROUTE is not set
372
373#
374# Network testing
375#
376# CONFIG_NET_PKTGEN is not set
377# CONFIG_NETPOLL is not set
378# CONFIG_NET_POLL_CONTROLLER is not set
379# CONFIG_HAMRADIO is not set
380# CONFIG_IRDA is not set
381# CONFIG_BT is not set
382CONFIG_NETDEVICES=y
383# CONFIG_DUMMY is not set
384# CONFIG_BONDING is not set
385# CONFIG_EQUALIZER is not set
386# CONFIG_TUN is not set
387
388#
389# Ethernet (10 or 100Mbit)
390#
391CONFIG_NET_ETHERNET=y
392# CONFIG_MII is not set
393CONFIG_STNIC=y
394# CONFIG_SMC91X is not set
395
396#
397# Ethernet (1000 Mbit)
398#
399
400#
401# Ethernet (10000 Mbit)
402#
403
404#
405# Token Ring devices
406#
407
408#
409# Wireless LAN (non-hamradio)
410#
411# CONFIG_NET_RADIO is not set
412
413#
414# Wan interfaces
415#
416# CONFIG_WAN is not set
417# CONFIG_PPP is not set
418# CONFIG_SLIP is not set
419# CONFIG_SHAPER is not set
420# CONFIG_NETCONSOLE is not set
421
422#
423# ISDN subsystem
424#
425# CONFIG_ISDN is not set
426
427#
428# Telephony Support
429#
430# CONFIG_PHONE is not set
431
432#
433# Input device support
434#
435# CONFIG_INPUT is not set
436
437#
438# Userland interfaces
439#
440
441#
442# Input I/O drivers
443#
444# CONFIG_GAMEPORT is not set
445CONFIG_SOUND_GAMEPORT=y
446# CONFIG_SERIO is not set
447# CONFIG_SERIO_I8042 is not set
448
449#
450# Input Device Drivers
451#
452
453#
454# Character devices
455#
456# CONFIG_VT is not set
457# CONFIG_SERIAL_NONSTANDARD is not set
458
459#
460# Serial drivers
461#
462CONFIG_SERIAL_8250=y
463# CONFIG_SERIAL_8250_CONSOLE is not set
464CONFIG_SERIAL_8250_NR_UARTS=2
465# CONFIG_SERIAL_8250_EXTENDED is not set
466
467#
468# Non-8250 serial port support
469#
470CONFIG_SERIAL_SH_SCI=y
471CONFIG_SERIAL_SH_SCI_CONSOLE=y
472CONFIG_SERIAL_CORE=y
473CONFIG_SERIAL_CORE_CONSOLE=y
474CONFIG_UNIX98_PTYS=y
475CONFIG_LEGACY_PTYS=y
476CONFIG_LEGACY_PTY_COUNT=256
477
478#
479# IPMI
480#
481# CONFIG_IPMI_HANDLER is not set
482
483#
484# Watchdog Cards
485#
486CONFIG_WATCHDOG=y
487# CONFIG_WATCHDOG_NOWAYOUT is not set
488
489#
490# Watchdog Device Drivers
491#
492# CONFIG_SOFT_WATCHDOG is not set
493CONFIG_SH_WDT=y
494# CONFIG_RTC is not set
495# CONFIG_GEN_RTC is not set
496# CONFIG_DTLK is not set
497# CONFIG_R3964 is not set
498
499#
500# Ftape, the floppy tape device driver
501#
502# CONFIG_DRM is not set
503# CONFIG_RAW_DRIVER is not set
504
505#
506# I2C support
507#
508# CONFIG_I2C is not set
509
510#
511# Dallas's 1-wire bus
512#
513# CONFIG_W1 is not set
514
515#
516# Misc devices
517#
518
519#
520# Multimedia devices
521#
522# CONFIG_VIDEO_DEV is not set
523
524#
525# Digital Video Broadcasting Devices
526#
527# CONFIG_DVB is not set
528
529#
530# Graphics support
531#
532# CONFIG_FB is not set
533
534#
535# Sound
536#
537# CONFIG_SOUND is not set
538
539#
540# USB support
541#
542# CONFIG_USB_ARCH_HAS_HCD is not set
543# CONFIG_USB_ARCH_HAS_OHCI is not set
544
545#
546# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
547#
548
549#
550# USB Gadget Support
551#
552# CONFIG_USB_GADGET is not set
553
554#
555# MMC/SD Card support
556#
557# CONFIG_MMC is not set
558
559#
560# InfiniBand support
561#
562# CONFIG_INFINIBAND is not set
563
564#
565# File systems
566#
567# CONFIG_EXT2_FS is not set
568# CONFIG_EXT3_FS is not set
569# CONFIG_JBD is not set
570# CONFIG_REISERFS_FS is not set
571# CONFIG_JFS_FS is not set
572
573#
574# XFS support
575#
576# CONFIG_XFS_FS is not set
577# CONFIG_MINIX_FS is not set
578# CONFIG_ROMFS_FS is not set
579# CONFIG_QUOTA is not set
580CONFIG_DNOTIFY=y
581# CONFIG_AUTOFS_FS is not set
582# CONFIG_AUTOFS4_FS is not set
583
584#
585# CD-ROM/DVD Filesystems
586#
587# CONFIG_ISO9660_FS is not set
588# CONFIG_UDF_FS is not set
589
590#
591# DOS/FAT/NT Filesystems
592#
593# CONFIG_MSDOS_FS is not set
594# CONFIG_VFAT_FS is not set
595# CONFIG_NTFS_FS is not set
596
597#
598# Pseudo filesystems
599#
600CONFIG_PROC_FS=y
601CONFIG_PROC_KCORE=y
602CONFIG_SYSFS=y
603# CONFIG_DEVFS_FS is not set
604# CONFIG_DEVPTS_FS_XATTR is not set
605CONFIG_TMPFS=y
606# CONFIG_TMPFS_XATTR is not set
607# CONFIG_HUGETLBFS is not set
608# CONFIG_HUGETLB_PAGE is not set
609CONFIG_RAMFS=y
610
611#
612# Miscellaneous filesystems
613#
614# CONFIG_ADFS_FS is not set
615# CONFIG_AFFS_FS is not set
616# CONFIG_HFS_FS is not set
617# CONFIG_HFSPLUS_FS is not set
618# CONFIG_BEFS_FS is not set
619# CONFIG_BFS_FS is not set
620# CONFIG_EFS_FS is not set
621# CONFIG_JFFS_FS is not set
622CONFIG_JFFS2_FS=y
623CONFIG_JFFS2_FS_DEBUG=0
624# CONFIG_JFFS2_FS_NAND is not set
625# CONFIG_JFFS2_FS_NOR_ECC is not set
626# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
627CONFIG_JFFS2_ZLIB=y
628CONFIG_JFFS2_RTIME=y
629# CONFIG_JFFS2_RUBIN is not set
630# CONFIG_CRAMFS is not set
631# CONFIG_VXFS_FS is not set
632# CONFIG_HPFS_FS is not set
633# CONFIG_QNX4FS_FS is not set
634# CONFIG_SYSV_FS is not set
635# CONFIG_UFS_FS is not set
636
637#
638# Network File Systems
639#
640CONFIG_NFS_FS=y
641# CONFIG_NFS_V3 is not set
642# CONFIG_NFS_V4 is not set
643# CONFIG_NFS_DIRECTIO is not set
644# CONFIG_NFSD is not set
645CONFIG_ROOT_NFS=y
646CONFIG_LOCKD=y
647CONFIG_SUNRPC=y
648# CONFIG_RPCSEC_GSS_KRB5 is not set
649# CONFIG_RPCSEC_GSS_SPKM3 is not set
650# CONFIG_SMB_FS is not set
651# CONFIG_CIFS is not set
652# CONFIG_NCP_FS is not set
653# CONFIG_CODA_FS is not set
654# CONFIG_AFS_FS is not set
655
656#
657# Partition Types
658#
659CONFIG_PARTITION_ADVANCED=y
660# CONFIG_ACORN_PARTITION is not set
661# CONFIG_OSF_PARTITION is not set
662# CONFIG_AMIGA_PARTITION is not set
663# CONFIG_ATARI_PARTITION is not set
664# CONFIG_MAC_PARTITION is not set
665# CONFIG_MSDOS_PARTITION is not set
666# CONFIG_LDM_PARTITION is not set
667# CONFIG_SGI_PARTITION is not set
668# CONFIG_ULTRIX_PARTITION is not set
669# CONFIG_SUN_PARTITION is not set
670# CONFIG_EFI_PARTITION is not set
671
672#
673# Native Language Support
674#
675# CONFIG_NLS is not set
676
677#
678# Profiling support
679#
680# CONFIG_PROFILING is not set
681
682#
683# Kernel hacking
684#
685# CONFIG_DEBUG_KERNEL is not set
686# CONFIG_FRAME_POINTER is not set
687# CONFIG_SH_STANDARD_BIOS is not set
688# CONFIG_EARLY_SCIF_CONSOLE is not set
689# CONFIG_KGDB is not set
690
691#
692# Security options
693#
694# CONFIG_KEYS is not set
695# CONFIG_SECURITY is not set
696
697#
698# Cryptographic options
699#
700# CONFIG_CRYPTO is not set
701
702#
703# Hardware crypto devices
704#
705
706#
707# Library routines
708#
709# CONFIG_CRC_CCITT is not set
710CONFIG_CRC32=y
711# CONFIG_LIBCRC32C is not set
712CONFIG_ZLIB_INFLATE=y
713CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
new file mode 100644
index 000000000000..1ce028947459
--- /dev/null
+++ b/arch/sh/configs/se7751_defconfig
@@ -0,0 +1,777 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:48 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25CONFIG_SYSVIPC=y
26# CONFIG_POSIX_MQUEUE is not set
27CONFIG_BSD_PROCESS_ACCT=y
28# CONFIG_BSD_PROCESS_ACCT_V3 is not set
29CONFIG_SYSCTL=y
30# CONFIG_AUDIT is not set
31CONFIG_LOG_BUF_SHIFT=14
32# CONFIG_HOTPLUG is not set
33CONFIG_KOBJECT_UEVENT=y
34# CONFIG_IKCONFIG is not set
35CONFIG_EMBEDDED=y
36CONFIG_KALLSYMS=y
37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_FUTEX=y
39CONFIG_EPOLL=y
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
41CONFIG_SHMEM=y
42CONFIG_CC_ALIGN_FUNCTIONS=0
43CONFIG_CC_ALIGN_LABELS=0
44CONFIG_CC_ALIGN_LOOPS=0
45CONFIG_CC_ALIGN_JUMPS=0
46# CONFIG_TINY_SHMEM is not set
47
48#
49# Loadable module support
50#
51CONFIG_MODULES=y
52# CONFIG_MODULE_UNLOAD is not set
53CONFIG_OBSOLETE_MODPARM=y
54# CONFIG_MODVERSIONS is not set
55# CONFIG_MODULE_SRCVERSION_ALL is not set
56# CONFIG_KMOD is not set
57
58#
59# System type
60#
61# CONFIG_SH_SOLUTION_ENGINE is not set
62CONFIG_SH_7751_SOLUTION_ENGINE=y
63# CONFIG_SH_7300_SOLUTION_ENGINE is not set
64# CONFIG_SH_73180_SOLUTION_ENGINE is not set
65# CONFIG_SH_7751_SYSTEMH is not set
66# CONFIG_SH_STB1_HARP is not set
67# CONFIG_SH_STB1_OVERDRIVE is not set
68# CONFIG_SH_HP620 is not set
69# CONFIG_SH_HP680 is not set
70# CONFIG_SH_HP690 is not set
71# CONFIG_SH_CQREEK is not set
72# CONFIG_SH_DMIDA is not set
73# CONFIG_SH_EC3104 is not set
74# CONFIG_SH_SATURN is not set
75# CONFIG_SH_DREAMCAST is not set
76# CONFIG_SH_CAT68701 is not set
77# CONFIG_SH_BIGSUR is not set
78# CONFIG_SH_SH2000 is not set
79# CONFIG_SH_ADX is not set
80# CONFIG_SH_MPC1211 is not set
81# CONFIG_SH_SH03 is not set
82# CONFIG_SH_SECUREEDGE5410 is not set
83# CONFIG_SH_HS7751RVOIP is not set
84# CONFIG_SH_RTS7751R2D is not set
85# CONFIG_SH_EDOSK7705 is not set
86# CONFIG_SH_SH4202_MICRODEV is not set
87# CONFIG_SH_UNKNOWN is not set
88# CONFIG_CPU_SH2 is not set
89# CONFIG_CPU_SH3 is not set
90CONFIG_CPU_SH4=y
91# CONFIG_CPU_SUBTYPE_SH7604 is not set
92# CONFIG_CPU_SUBTYPE_SH7300 is not set
93# CONFIG_CPU_SUBTYPE_SH7705 is not set
94# CONFIG_CPU_SUBTYPE_SH7707 is not set
95# CONFIG_CPU_SUBTYPE_SH7708 is not set
96# CONFIG_CPU_SUBTYPE_SH7709 is not set
97# CONFIG_CPU_SUBTYPE_SH7750 is not set
98CONFIG_CPU_SUBTYPE_SH7751=y
99# CONFIG_CPU_SUBTYPE_SH7760 is not set
100# CONFIG_CPU_SUBTYPE_SH73180 is not set
101# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
102# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
103# CONFIG_CPU_SUBTYPE_SH4_202 is not set
104CONFIG_MMU=y
105CONFIG_CMDLINE_BOOL=y
106CONFIG_CMDLINE="console=ttySC1,38400"
107CONFIG_MEMORY_START=0x0c000000
108CONFIG_MEMORY_SIZE=0x04000000
109CONFIG_MEMORY_SET=y
110# CONFIG_MEMORY_OVERRIDE is not set
111CONFIG_SH_RTC=y
112CONFIG_SH_FPU=y
113CONFIG_ZERO_PAGE_OFFSET=0x00010000
114CONFIG_BOOT_LINK_OFFSET=0x00800000
115CONFIG_CPU_LITTLE_ENDIAN=y
116# CONFIG_PREEMPT is not set
117# CONFIG_UBC_WAKEUP is not set
118# CONFIG_SH_WRITETHROUGH is not set
119# CONFIG_SH_OCRAM is not set
120# CONFIG_SH_STORE_QUEUES is not set
121# CONFIG_SMP is not set
122CONFIG_SH_PCLK_CALC=y
123CONFIG_SH_PCLK_FREQ=60013568
124
125#
126# CPU Frequency scaling
127#
128# CONFIG_CPU_FREQ is not set
129
130#
131# DMA support
132#
133# CONFIG_SH_DMA is not set
134
135#
136# Companion Chips
137#
138# CONFIG_HD6446X_SERIES is not set
139CONFIG_HEARTBEAT=y
140
141#
142# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
143#
144CONFIG_PCI=y
145# CONFIG_SH_PCIDMA_NONCOHERENT is not set
146CONFIG_PCI_AUTO=y
147CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
148# CONFIG_PCI_LEGACY_PROC is not set
149# CONFIG_PCI_NAMES is not set
150
151#
152# PCCARD (PCMCIA/CardBus) support
153#
154# CONFIG_PCCARD is not set
155
156#
157# PC-card bridges
158#
159
160#
161# PCI Hotplug Support
162#
163# CONFIG_HOTPLUG_PCI is not set
164
165#
166# Executable file formats
167#
168CONFIG_BINFMT_ELF=y
169# CONFIG_BINFMT_FLAT is not set
170# CONFIG_BINFMT_MISC is not set
171
172#
173# SH initrd options
174#
175# CONFIG_EMBEDDED_RAMDISK is not set
176
177#
178# Device Drivers
179#
180
181#
182# Generic Driver Options
183#
184CONFIG_STANDALONE=y
185CONFIG_PREVENT_FIRMWARE_BUILD=y
186# CONFIG_FW_LOADER is not set
187
188#
189# Memory Technology Devices (MTD)
190#
191CONFIG_MTD=y
192# CONFIG_MTD_DEBUG is not set
193CONFIG_MTD_PARTITIONS=y
194# CONFIG_MTD_CONCAT is not set
195# CONFIG_MTD_REDBOOT_PARTS is not set
196# CONFIG_MTD_CMDLINE_PARTS is not set
197
198#
199# User Modules And Translation Layers
200#
201# CONFIG_MTD_CHAR is not set
202CONFIG_MTD_BLOCK=y
203# CONFIG_FTL is not set
204# CONFIG_NFTL is not set
205# CONFIG_INFTL is not set
206
207#
208# RAM/ROM/Flash chip drivers
209#
210CONFIG_MTD_CFI=y
211# CONFIG_MTD_JEDECPROBE is not set
212CONFIG_MTD_GEN_PROBE=y
213# CONFIG_MTD_CFI_ADV_OPTIONS is not set
214CONFIG_MTD_MAP_BANK_WIDTH_1=y
215CONFIG_MTD_MAP_BANK_WIDTH_2=y
216CONFIG_MTD_MAP_BANK_WIDTH_4=y
217# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
218# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
219# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
220CONFIG_MTD_CFI_I1=y
221CONFIG_MTD_CFI_I2=y
222# CONFIG_MTD_CFI_I4 is not set
223# CONFIG_MTD_CFI_I8 is not set
224# CONFIG_MTD_CFI_INTELEXT is not set
225CONFIG_MTD_CFI_AMDSTD=y
226CONFIG_MTD_CFI_AMDSTD_RETRY=0
227# CONFIG_MTD_CFI_STAA is not set
228CONFIG_MTD_CFI_UTIL=y
229CONFIG_MTD_RAM=y
230# CONFIG_MTD_ROM is not set
231# CONFIG_MTD_ABSENT is not set
232
233#
234# Mapping drivers for chip access
235#
236# CONFIG_MTD_COMPLEX_MAPPINGS is not set
237# CONFIG_MTD_PHYSMAP is not set
238# CONFIG_MTD_SOLUTIONENGINE is not set
239# CONFIG_MTD_MPC1211 is not set
240# CONFIG_MTD_RTS7751R2D is not set
241
242#
243# Self-contained MTD device drivers
244#
245# CONFIG_MTD_PMC551 is not set
246# CONFIG_MTD_SLRAM is not set
247# CONFIG_MTD_PHRAM is not set
248# CONFIG_MTD_MTDRAM is not set
249# CONFIG_MTD_BLKMTD is not set
250# CONFIG_MTD_BLOCK2MTD is not set
251
252#
253# Disk-On-Chip Device Drivers
254#
255# CONFIG_MTD_DOC2000 is not set
256# CONFIG_MTD_DOC2001 is not set
257# CONFIG_MTD_DOC2001PLUS is not set
258
259#
260# NAND Flash Device Drivers
261#
262# CONFIG_MTD_NAND is not set
263
264#
265# Parallel port support
266#
267# CONFIG_PARPORT is not set
268
269#
270# Plug and Play support
271#
272
273#
274# Block devices
275#
276# CONFIG_BLK_DEV_FD is not set
277# CONFIG_BLK_CPQ_DA is not set
278# CONFIG_BLK_CPQ_CISS_DA is not set
279# CONFIG_BLK_DEV_DAC960 is not set
280# CONFIG_BLK_DEV_UMEM is not set
281# CONFIG_BLK_DEV_COW_COMMON is not set
282# CONFIG_BLK_DEV_LOOP is not set
283# CONFIG_BLK_DEV_NBD is not set
284# CONFIG_BLK_DEV_SX8 is not set
285CONFIG_BLK_DEV_RAM=y
286CONFIG_BLK_DEV_RAM_COUNT=16
287CONFIG_BLK_DEV_RAM_SIZE=4096
288CONFIG_BLK_DEV_INITRD=y
289CONFIG_INITRAMFS_SOURCE=""
290# CONFIG_LBD is not set
291# CONFIG_CDROM_PKTCDVD is not set
292
293#
294# IO Schedulers
295#
296CONFIG_IOSCHED_NOOP=y
297CONFIG_IOSCHED_AS=y
298CONFIG_IOSCHED_DEADLINE=y
299CONFIG_IOSCHED_CFQ=y
300# CONFIG_ATA_OVER_ETH is not set
301
302#
303# ATA/ATAPI/MFM/RLL support
304#
305# CONFIG_IDE is not set
306
307#
308# SCSI device support
309#
310# CONFIG_SCSI is not set
311
312#
313# Multi-device support (RAID and LVM)
314#
315# CONFIG_MD is not set
316
317#
318# Fusion MPT device support
319#
320
321#
322# IEEE 1394 (FireWire) support
323#
324# CONFIG_IEEE1394 is not set
325
326#
327# I2O device support
328#
329# CONFIG_I2O is not set
330
331#
332# Networking support
333#
334CONFIG_NET=y
335
336#
337# Networking options
338#
339CONFIG_PACKET=y
340# CONFIG_PACKET_MMAP is not set
341CONFIG_NETLINK_DEV=y
342CONFIG_UNIX=y
343# CONFIG_NET_KEY is not set
344CONFIG_INET=y
345CONFIG_IP_MULTICAST=y
346# CONFIG_IP_ADVANCED_ROUTER is not set
347CONFIG_IP_PNP=y
348CONFIG_IP_PNP_DHCP=y
349CONFIG_IP_PNP_BOOTP=y
350CONFIG_IP_PNP_RARP=y
351# CONFIG_NET_IPIP is not set
352# CONFIG_NET_IPGRE is not set
353# CONFIG_IP_MROUTE is not set
354# CONFIG_ARPD is not set
355# CONFIG_SYN_COOKIES is not set
356# CONFIG_INET_AH is not set
357# CONFIG_INET_ESP is not set
358# CONFIG_INET_IPCOMP is not set
359# CONFIG_INET_TUNNEL is not set
360CONFIG_IP_TCPDIAG=y
361# CONFIG_IP_TCPDIAG_IPV6 is not set
362
363#
364# IP: Virtual Server Configuration
365#
366# CONFIG_IP_VS is not set
367# CONFIG_IPV6 is not set
368CONFIG_NETFILTER=y
369CONFIG_NETFILTER_DEBUG=y
370
371#
372# IP: Netfilter Configuration
373#
374# CONFIG_IP_NF_CONNTRACK is not set
375# CONFIG_IP_NF_CONNTRACK_MARK is not set
376CONFIG_IP_NF_QUEUE=y
377# CONFIG_IP_NF_IPTABLES is not set
378# CONFIG_IP_NF_ARPTABLES is not set
379
380#
381# SCTP Configuration (EXPERIMENTAL)
382#
383# CONFIG_IP_SCTP is not set
384# CONFIG_ATM is not set
385# CONFIG_BRIDGE is not set
386# CONFIG_VLAN_8021Q is not set
387# CONFIG_DECNET is not set
388# CONFIG_LLC2 is not set
389# CONFIG_IPX is not set
390# CONFIG_ATALK is not set
391# CONFIG_X25 is not set
392# CONFIG_LAPB is not set
393# CONFIG_NET_DIVERT is not set
394# CONFIG_ECONET is not set
395# CONFIG_WAN_ROUTER is not set
396
397#
398# QoS and/or fair queueing
399#
400# CONFIG_NET_SCHED is not set
401# CONFIG_NET_CLS_ROUTE is not set
402
403#
404# Network testing
405#
406# CONFIG_NET_PKTGEN is not set
407# CONFIG_NETPOLL is not set
408# CONFIG_NET_POLL_CONTROLLER is not set
409# CONFIG_HAMRADIO is not set
410# CONFIG_IRDA is not set
411# CONFIG_BT is not set
412CONFIG_NETDEVICES=y
413# CONFIG_DUMMY is not set
414# CONFIG_BONDING is not set
415# CONFIG_EQUALIZER is not set
416# CONFIG_TUN is not set
417# CONFIG_ETHERTAP is not set
418
419#
420# ARCnet devices
421#
422# CONFIG_ARCNET is not set
423
424#
425# Ethernet (10 or 100Mbit)
426#
427CONFIG_NET_ETHERNET=y
428CONFIG_MII=y
429# CONFIG_STNIC is not set
430# CONFIG_HAPPYMEAL is not set
431# CONFIG_SUNGEM is not set
432# CONFIG_NET_VENDOR_3COM is not set
433# CONFIG_SMC91X is not set
434
435#
436# Tulip family network device support
437#
438# CONFIG_NET_TULIP is not set
439# CONFIG_HP100 is not set
440CONFIG_NET_PCI=y
441CONFIG_PCNET32=y
442# CONFIG_AMD8111_ETH is not set
443# CONFIG_ADAPTEC_STARFIRE is not set
444# CONFIG_B44 is not set
445# CONFIG_FORCEDETH is not set
446# CONFIG_DGRS is not set
447# CONFIG_EEPRO100 is not set
448# CONFIG_E100 is not set
449# CONFIG_FEALNX is not set
450# CONFIG_NATSEMI is not set
451# CONFIG_NE2K_PCI is not set
452# CONFIG_8139CP is not set
453# CONFIG_8139TOO is not set
454# CONFIG_SIS900 is not set
455# CONFIG_EPIC100 is not set
456# CONFIG_SUNDANCE is not set
457# CONFIG_TLAN is not set
458# CONFIG_VIA_RHINE is not set
459
460#
461# Ethernet (1000 Mbit)
462#
463# CONFIG_ACENIC is not set
464# CONFIG_DL2K is not set
465# CONFIG_E1000 is not set
466# CONFIG_NS83820 is not set
467# CONFIG_HAMACHI is not set
468# CONFIG_YELLOWFIN is not set
469# CONFIG_R8169 is not set
470# CONFIG_SK98LIN is not set
471# CONFIG_VIA_VELOCITY is not set
472# CONFIG_TIGON3 is not set
473
474#
475# Ethernet (10000 Mbit)
476#
477# CONFIG_IXGB is not set
478# CONFIG_S2IO is not set
479
480#
481# Token Ring devices
482#
483# CONFIG_TR is not set
484
485#
486# Wireless LAN (non-hamradio)
487#
488# CONFIG_NET_RADIO is not set
489
490#
491# Wan interfaces
492#
493# CONFIG_WAN is not set
494# CONFIG_FDDI is not set
495# CONFIG_HIPPI is not set
496# CONFIG_PPP is not set
497# CONFIG_SLIP is not set
498# CONFIG_SHAPER is not set
499# CONFIG_NETCONSOLE is not set
500
501#
502# ISDN subsystem
503#
504# CONFIG_ISDN is not set
505
506#
507# Telephony Support
508#
509# CONFIG_PHONE is not set
510
511#
512# Input device support
513#
514# CONFIG_INPUT is not set
515
516#
517# Userland interfaces
518#
519
520#
521# Input I/O drivers
522#
523# CONFIG_GAMEPORT is not set
524CONFIG_SOUND_GAMEPORT=y
525# CONFIG_SERIO is not set
526# CONFIG_SERIO_I8042 is not set
527
528#
529# Input Device Drivers
530#
531
532#
533# Character devices
534#
535# CONFIG_VT is not set
536# CONFIG_SERIAL_NONSTANDARD is not set
537
538#
539# Serial drivers
540#
541# CONFIG_SERIAL_8250 is not set
542
543#
544# Non-8250 serial port support
545#
546# CONFIG_SERIAL_SH_SCI is not set
547CONFIG_UNIX98_PTYS=y
548CONFIG_LEGACY_PTYS=y
549CONFIG_LEGACY_PTY_COUNT=256
550
551#
552# IPMI
553#
554# CONFIG_IPMI_HANDLER is not set
555
556#
557# Watchdog Cards
558#
559CONFIG_WATCHDOG=y
560# CONFIG_WATCHDOG_NOWAYOUT is not set
561
562#
563# Watchdog Device Drivers
564#
565# CONFIG_SOFT_WATCHDOG is not set
566# CONFIG_SH_WDT is not set
567
568#
569# PCI-based Watchdog Cards
570#
571# CONFIG_PCIPCWATCHDOG is not set
572# CONFIG_WDTPCI is not set
573# CONFIG_RTC is not set
574# CONFIG_GEN_RTC is not set
575# CONFIG_DTLK is not set
576# CONFIG_R3964 is not set
577# CONFIG_APPLICOM is not set
578
579#
580# Ftape, the floppy tape device driver
581#
582# CONFIG_DRM is not set
583# CONFIG_RAW_DRIVER is not set
584
585#
586# I2C support
587#
588# CONFIG_I2C is not set
589
590#
591# Dallas's 1-wire bus
592#
593# CONFIG_W1 is not set
594
595#
596# Misc devices
597#
598
599#
600# Multimedia devices
601#
602# CONFIG_VIDEO_DEV is not set
603
604#
605# Digital Video Broadcasting Devices
606#
607# CONFIG_DVB is not set
608
609#
610# Graphics support
611#
612# CONFIG_FB is not set
613
614#
615# Sound
616#
617# CONFIG_SOUND is not set
618
619#
620# USB support
621#
622# CONFIG_USB is not set
623CONFIG_USB_ARCH_HAS_HCD=y
624CONFIG_USB_ARCH_HAS_OHCI=y
625
626#
627# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
628#
629
630#
631# USB Gadget Support
632#
633# CONFIG_USB_GADGET is not set
634
635#
636# MMC/SD Card support
637#
638# CONFIG_MMC is not set
639
640#
641# InfiniBand support
642#
643# CONFIG_INFINIBAND is not set
644
645#
646# File systems
647#
648CONFIG_EXT2_FS=y
649# CONFIG_EXT2_FS_XATTR is not set
650# CONFIG_EXT3_FS is not set
651# CONFIG_JBD is not set
652# CONFIG_REISERFS_FS is not set
653# CONFIG_JFS_FS is not set
654
655#
656# XFS support
657#
658# CONFIG_XFS_FS is not set
659# CONFIG_MINIX_FS is not set
660# CONFIG_ROMFS_FS is not set
661# CONFIG_QUOTA is not set
662CONFIG_DNOTIFY=y
663# CONFIG_AUTOFS_FS is not set
664# CONFIG_AUTOFS4_FS is not set
665
666#
667# CD-ROM/DVD Filesystems
668#
669# CONFIG_ISO9660_FS is not set
670# CONFIG_UDF_FS is not set
671
672#
673# DOS/FAT/NT Filesystems
674#
675# CONFIG_MSDOS_FS is not set
676# CONFIG_VFAT_FS is not set
677# CONFIG_NTFS_FS is not set
678
679#
680# Pseudo filesystems
681#
682CONFIG_PROC_FS=y
683CONFIG_PROC_KCORE=y
684CONFIG_SYSFS=y
685# CONFIG_DEVFS_FS is not set
686# CONFIG_DEVPTS_FS_XATTR is not set
687CONFIG_TMPFS=y
688# CONFIG_TMPFS_XATTR is not set
689# CONFIG_HUGETLBFS is not set
690# CONFIG_HUGETLB_PAGE is not set
691CONFIG_RAMFS=y
692
693#
694# Miscellaneous filesystems
695#
696# CONFIG_ADFS_FS is not set
697# CONFIG_AFFS_FS is not set
698# CONFIG_HFS_FS is not set
699# CONFIG_HFSPLUS_FS is not set
700# CONFIG_BEFS_FS is not set
701# CONFIG_BFS_FS is not set
702# CONFIG_EFS_FS is not set
703# CONFIG_JFFS_FS is not set
704CONFIG_JFFS2_FS=y
705CONFIG_JFFS2_FS_DEBUG=0
706# CONFIG_JFFS2_FS_NAND is not set
707# CONFIG_JFFS2_FS_NOR_ECC is not set
708# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
709CONFIG_JFFS2_ZLIB=y
710CONFIG_JFFS2_RTIME=y
711# CONFIG_JFFS2_RUBIN is not set
712# CONFIG_CRAMFS is not set
713# CONFIG_VXFS_FS is not set
714# CONFIG_HPFS_FS is not set
715# CONFIG_QNX4FS_FS is not set
716# CONFIG_SYSV_FS is not set
717# CONFIG_UFS_FS is not set
718
719#
720# Network File Systems
721#
722# CONFIG_NFS_FS is not set
723# CONFIG_NFSD is not set
724# CONFIG_SMB_FS is not set
725# CONFIG_CIFS is not set
726# CONFIG_NCP_FS is not set
727# CONFIG_CODA_FS is not set
728# CONFIG_AFS_FS is not set
729
730#
731# Partition Types
732#
733# CONFIG_PARTITION_ADVANCED is not set
734CONFIG_MSDOS_PARTITION=y
735
736#
737# Native Language Support
738#
739# CONFIG_NLS is not set
740
741#
742# Profiling support
743#
744# CONFIG_PROFILING is not set
745
746#
747# Kernel hacking
748#
749# CONFIG_DEBUG_KERNEL is not set
750# CONFIG_FRAME_POINTER is not set
751# CONFIG_SH_STANDARD_BIOS is not set
752# CONFIG_EARLY_SCIF_CONSOLE is not set
753# CONFIG_KGDB is not set
754
755#
756# Security options
757#
758# CONFIG_KEYS is not set
759# CONFIG_SECURITY is not set
760
761#
762# Cryptographic options
763#
764# CONFIG_CRYPTO is not set
765
766#
767# Hardware crypto devices
768#
769
770#
771# Library routines
772#
773# CONFIG_CRC_CCITT is not set
774CONFIG_CRC32=y
775# CONFIG_LIBCRC32C is not set
776CONFIG_ZLIB_INFLATE=y
777CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
new file mode 100644
index 000000000000..078f78c7fe53
--- /dev/null
+++ b/arch/sh/configs/sh03_defconfig
@@ -0,0 +1,924 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:49 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17# CONFIG_CLEAN_COMPILE is not set
18CONFIG_BROKEN=y
19CONFIG_BROKEN_ON_SMP=y
20CONFIG_LOCK_KERNEL=y
21
22#
23# General setup
24#
25CONFIG_LOCALVERSION=""
26CONFIG_SWAP=y
27CONFIG_SYSVIPC=y
28CONFIG_POSIX_MQUEUE=y
29CONFIG_BSD_PROCESS_ACCT=y
30# CONFIG_BSD_PROCESS_ACCT_V3 is not set
31CONFIG_SYSCTL=y
32# CONFIG_AUDIT is not set
33CONFIG_LOG_BUF_SHIFT=14
34CONFIG_HOTPLUG=y
35CONFIG_KOBJECT_UEVENT=y
36# CONFIG_IKCONFIG is not set
37# CONFIG_EMBEDDED is not set
38CONFIG_KALLSYMS=y
39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_FUTEX=y
41CONFIG_EPOLL=y
42# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
43CONFIG_SHMEM=y
44CONFIG_CC_ALIGN_FUNCTIONS=0
45CONFIG_CC_ALIGN_LABELS=0
46CONFIG_CC_ALIGN_LOOPS=0
47CONFIG_CC_ALIGN_JUMPS=0
48# CONFIG_TINY_SHMEM is not set
49
50#
51# Loadable module support
52#
53CONFIG_MODULES=y
54CONFIG_MODULE_UNLOAD=y
55CONFIG_MODULE_FORCE_UNLOAD=y
56CONFIG_OBSOLETE_MODPARM=y
57CONFIG_MODVERSIONS=y
58# CONFIG_MODULE_SRCVERSION_ALL is not set
59CONFIG_KMOD=y
60
61#
62# System type
63#
64# CONFIG_SH_SOLUTION_ENGINE is not set
65# CONFIG_SH_7751_SOLUTION_ENGINE is not set
66# CONFIG_SH_7300_SOLUTION_ENGINE is not set
67# CONFIG_SH_73180_SOLUTION_ENGINE is not set
68# CONFIG_SH_7751_SYSTEMH is not set
69# CONFIG_SH_STB1_HARP is not set
70# CONFIG_SH_STB1_OVERDRIVE is not set
71# CONFIG_SH_HP620 is not set
72# CONFIG_SH_HP680 is not set
73# CONFIG_SH_HP690 is not set
74# CONFIG_SH_CQREEK is not set
75# CONFIG_SH_DMIDA is not set
76# CONFIG_SH_EC3104 is not set
77# CONFIG_SH_SATURN is not set
78# CONFIG_SH_DREAMCAST is not set
79# CONFIG_SH_CAT68701 is not set
80# CONFIG_SH_BIGSUR is not set
81# CONFIG_SH_SH2000 is not set
82# CONFIG_SH_ADX is not set
83# CONFIG_SH_MPC1211 is not set
84CONFIG_SH_SH03=y
85# CONFIG_SH_SECUREEDGE5410 is not set
86# CONFIG_SH_HS7751RVOIP is not set
87# CONFIG_SH_RTS7751R2D is not set
88# CONFIG_SH_EDOSK7705 is not set
89# CONFIG_SH_SH4202_MICRODEV is not set
90# CONFIG_SH_UNKNOWN is not set
91# CONFIG_CPU_SH2 is not set
92# CONFIG_CPU_SH3 is not set
93CONFIG_CPU_SH4=y
94# CONFIG_CPU_SUBTYPE_SH7604 is not set
95# CONFIG_CPU_SUBTYPE_SH7300 is not set
96# CONFIG_CPU_SUBTYPE_SH7705 is not set
97# CONFIG_CPU_SUBTYPE_SH7707 is not set
98# CONFIG_CPU_SUBTYPE_SH7708 is not set
99# CONFIG_CPU_SUBTYPE_SH7709 is not set
100# CONFIG_CPU_SUBTYPE_SH7750 is not set
101CONFIG_CPU_SUBTYPE_SH7751=y
102# CONFIG_CPU_SUBTYPE_SH7760 is not set
103# CONFIG_CPU_SUBTYPE_SH73180 is not set
104# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
105# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
106# CONFIG_CPU_SUBTYPE_SH4_202 is not set
107CONFIG_MMU=y
108CONFIG_CMDLINE_BOOL=y
109CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
110CONFIG_MEMORY_START=0x08000000
111CONFIG_MEMORY_SIZE=0x08000000
112CONFIG_MEMORY_SET=y
113# CONFIG_MEMORY_OVERRIDE is not set
114CONFIG_CF_ENABLER=y
115CONFIG_CF_AREA5=y
116# CONFIG_CF_AREA6 is not set
117CONFIG_CF_BASE_ADDR=0xb4000000
118CONFIG_SH_RTC=y
119CONFIG_SH_FPU=y
120CONFIG_ZERO_PAGE_OFFSET=0x00004000
121CONFIG_BOOT_LINK_OFFSET=0x00800000
122CONFIG_CPU_LITTLE_ENDIAN=y
123CONFIG_PREEMPT=y
124# CONFIG_UBC_WAKEUP is not set
125# CONFIG_SH_WRITETHROUGH is not set
126# CONFIG_SH_OCRAM is not set
127# CONFIG_SH_STORE_QUEUES is not set
128# CONFIG_SMP is not set
129CONFIG_SH_PCLK_CALC=y
130CONFIG_SH_PCLK_FREQ=49876504
131
132#
133# CPU Frequency scaling
134#
135# CONFIG_CPU_FREQ is not set
136
137#
138# DMA support
139#
140# CONFIG_SH_DMA is not set
141
142#
143# Companion Chips
144#
145# CONFIG_HD6446X_SERIES is not set
146CONFIG_HEARTBEAT=y
147
148#
149# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
150#
151CONFIG_PCI=y
152CONFIG_SH_PCIDMA_NONCOHERENT=y
153CONFIG_PCI_AUTO=y
154CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
155CONFIG_PCI_LEGACY_PROC=y
156CONFIG_PCI_NAMES=y
157
158#
159# PCCARD (PCMCIA/CardBus) support
160#
161# CONFIG_PCCARD is not set
162
163#
164# PC-card bridges
165#
166
167#
168# PCI Hotplug Support
169#
170CONFIG_HOTPLUG_PCI=m
171# CONFIG_HOTPLUG_PCI_FAKE is not set
172# CONFIG_HOTPLUG_PCI_CPCI is not set
173# CONFIG_HOTPLUG_PCI_SHPC is not set
174
175#
176# Executable file formats
177#
178CONFIG_BINFMT_ELF=y
179# CONFIG_BINFMT_FLAT is not set
180CONFIG_BINFMT_MISC=y
181
182#
183# SH initrd options
184#
185# CONFIG_EMBEDDED_RAMDISK is not set
186
187#
188# Device Drivers
189#
190
191#
192# Generic Driver Options
193#
194# CONFIG_STANDALONE is not set
195# CONFIG_PREVENT_FIRMWARE_BUILD is not set
196# CONFIG_FW_LOADER is not set
197
198#
199# Memory Technology Devices (MTD)
200#
201# CONFIG_MTD is not set
202
203#
204# Parallel port support
205#
206# CONFIG_PARPORT is not set
207
208#
209# Plug and Play support
210#
211
212#
213# Block devices
214#
215# CONFIG_BLK_DEV_FD is not set
216# CONFIG_BLK_CPQ_DA is not set
217# CONFIG_BLK_CPQ_CISS_DA is not set
218# CONFIG_BLK_DEV_DAC960 is not set
219# CONFIG_BLK_DEV_UMEM is not set
220# CONFIG_BLK_DEV_COW_COMMON is not set
221CONFIG_BLK_DEV_LOOP=y
222# CONFIG_BLK_DEV_CRYPTOLOOP is not set
223CONFIG_BLK_DEV_NBD=y
224# CONFIG_BLK_DEV_SX8 is not set
225CONFIG_BLK_DEV_RAM=y
226CONFIG_BLK_DEV_RAM_COUNT=16
227CONFIG_BLK_DEV_RAM_SIZE=4096
228CONFIG_BLK_DEV_INITRD=y
229CONFIG_INITRAMFS_SOURCE=""
230# CONFIG_LBD is not set
231# CONFIG_CDROM_PKTCDVD is not set
232
233#
234# IO Schedulers
235#
236CONFIG_IOSCHED_NOOP=y
237CONFIG_IOSCHED_AS=y
238CONFIG_IOSCHED_DEADLINE=y
239CONFIG_IOSCHED_CFQ=y
240# CONFIG_ATA_OVER_ETH is not set
241
242#
243# ATA/ATAPI/MFM/RLL support
244#
245CONFIG_IDE=y
246CONFIG_IDE_MAX_HWIFS=4
247CONFIG_BLK_DEV_IDE=y
248
249#
250# Please see Documentation/ide.txt for help/info on IDE drives
251#
252# CONFIG_BLK_DEV_IDE_SATA is not set
253CONFIG_BLK_DEV_IDEDISK=y
254CONFIG_IDEDISK_MULTI_MODE=y
255CONFIG_BLK_DEV_IDECD=m
256CONFIG_BLK_DEV_IDETAPE=m
257CONFIG_BLK_DEV_IDEFLOPPY=m
258# CONFIG_BLK_DEV_IDESCSI is not set
259# CONFIG_IDE_TASK_IOCTL is not set
260
261#
262# IDE chipset support/bugfixes
263#
264CONFIG_IDE_GENERIC=y
265# CONFIG_BLK_DEV_IDEPCI is not set
266CONFIG_IDE_SH=y
267# CONFIG_IDE_ARM is not set
268# CONFIG_BLK_DEV_IDEDMA is not set
269# CONFIG_IDEDMA_AUTO is not set
270# CONFIG_BLK_DEV_HD is not set
271
272#
273# SCSI device support
274#
275CONFIG_SCSI=m
276CONFIG_SCSI_PROC_FS=y
277
278#
279# SCSI support type (disk, tape, CD-ROM)
280#
281CONFIG_BLK_DEV_SD=m
282# CONFIG_CHR_DEV_ST is not set
283# CONFIG_CHR_DEV_OSST is not set
284CONFIG_BLK_DEV_SR=m
285CONFIG_BLK_DEV_SR_VENDOR=y
286CONFIG_CHR_DEV_SG=m
287
288#
289# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
290#
291# CONFIG_SCSI_MULTI_LUN is not set
292# CONFIG_SCSI_CONSTANTS is not set
293# CONFIG_SCSI_LOGGING is not set
294
295#
296# SCSI Transport Attributes
297#
298# CONFIG_SCSI_SPI_ATTRS is not set
299# CONFIG_SCSI_FC_ATTRS is not set
300# CONFIG_SCSI_ISCSI_ATTRS is not set
301
302#
303# SCSI low-level drivers
304#
305# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
306# CONFIG_SCSI_3W_9XXX is not set
307# CONFIG_SCSI_ACARD is not set
308# CONFIG_SCSI_AACRAID is not set
309# CONFIG_SCSI_AIC7XXX is not set
310# CONFIG_SCSI_AIC7XXX_OLD is not set
311# CONFIG_SCSI_AIC79XX is not set
312# CONFIG_SCSI_DPT_I2O is not set
313# CONFIG_SCSI_ADVANSYS is not set
314# CONFIG_MEGARAID_NEWGEN is not set
315# CONFIG_MEGARAID_LEGACY is not set
316# CONFIG_SCSI_SATA is not set
317# CONFIG_SCSI_BUSLOGIC is not set
318# CONFIG_SCSI_CPQFCTS is not set
319# CONFIG_SCSI_DMX3191D is not set
320# CONFIG_SCSI_EATA is not set
321# CONFIG_SCSI_EATA_PIO is not set
322# CONFIG_SCSI_FUTURE_DOMAIN is not set
323# CONFIG_SCSI_GDTH is not set
324# CONFIG_SCSI_IPS is not set
325# CONFIG_SCSI_INITIO is not set
326# CONFIG_SCSI_INIA100 is not set
327# CONFIG_SCSI_SYM53C8XX_2 is not set
328# CONFIG_SCSI_IPR is not set
329# CONFIG_SCSI_PCI2000 is not set
330# CONFIG_SCSI_PCI2220I is not set
331# CONFIG_SCSI_QLOGIC_ISP is not set
332# CONFIG_SCSI_QLOGIC_FC is not set
333# CONFIG_SCSI_QLOGIC_1280 is not set
334CONFIG_SCSI_QLA2XXX=m
335# CONFIG_SCSI_QLA21XX is not set
336# CONFIG_SCSI_QLA22XX is not set
337# CONFIG_SCSI_QLA2300 is not set
338# CONFIG_SCSI_QLA2322 is not set
339# CONFIG_SCSI_QLA6312 is not set
340# CONFIG_SCSI_DC395x is not set
341# CONFIG_SCSI_DC390T is not set
342# CONFIG_SCSI_NSP32 is not set
343# CONFIG_SCSI_DEBUG is not set
344
345#
346# Multi-device support (RAID and LVM)
347#
348# CONFIG_MD is not set
349
350#
351# Fusion MPT device support
352#
353# CONFIG_FUSION is not set
354
355#
356# IEEE 1394 (FireWire) support
357#
358# CONFIG_IEEE1394 is not set
359
360#
361# I2O device support
362#
363# CONFIG_I2O is not set
364
365#
366# Networking support
367#
368CONFIG_NET=y
369
370#
371# Networking options
372#
373CONFIG_PACKET=y
374# CONFIG_PACKET_MMAP is not set
375# CONFIG_NETLINK_DEV is not set
376CONFIG_UNIX=y
377CONFIG_NET_KEY=y
378CONFIG_INET=y
379CONFIG_IP_MULTICAST=y
380# CONFIG_IP_ADVANCED_ROUTER is not set
381CONFIG_IP_PNP=y
382CONFIG_IP_PNP_DHCP=y
383CONFIG_IP_PNP_BOOTP=y
384CONFIG_IP_PNP_RARP=y
385# CONFIG_NET_IPIP is not set
386# CONFIG_NET_IPGRE is not set
387# CONFIG_IP_MROUTE is not set
388# CONFIG_ARPD is not set
389# CONFIG_SYN_COOKIES is not set
390# CONFIG_INET_AH is not set
391# CONFIG_INET_ESP is not set
392# CONFIG_INET_IPCOMP is not set
393# CONFIG_INET_TUNNEL is not set
394CONFIG_IP_TCPDIAG=y
395# CONFIG_IP_TCPDIAG_IPV6 is not set
396# CONFIG_IPV6 is not set
397# CONFIG_NETFILTER is not set
398CONFIG_XFRM=y
399# CONFIG_XFRM_USER is not set
400
401#
402# SCTP Configuration (EXPERIMENTAL)
403#
404# CONFIG_IP_SCTP is not set
405# CONFIG_ATM is not set
406# CONFIG_BRIDGE is not set
407# CONFIG_VLAN_8021Q is not set
408# CONFIG_DECNET is not set
409# CONFIG_LLC2 is not set
410# CONFIG_IPX is not set
411# CONFIG_ATALK is not set
412# CONFIG_X25 is not set
413# CONFIG_LAPB is not set
414# CONFIG_NET_DIVERT is not set
415# CONFIG_ECONET is not set
416# CONFIG_WAN_ROUTER is not set
417
418#
419# QoS and/or fair queueing
420#
421# CONFIG_NET_SCHED is not set
422# CONFIG_NET_CLS_ROUTE is not set
423
424#
425# Network testing
426#
427# CONFIG_NET_PKTGEN is not set
428# CONFIG_NETPOLL is not set
429# CONFIG_NET_POLL_CONTROLLER is not set
430# CONFIG_HAMRADIO is not set
431# CONFIG_IRDA is not set
432# CONFIG_BT is not set
433CONFIG_NETDEVICES=y
434# CONFIG_DUMMY is not set
435# CONFIG_BONDING is not set
436# CONFIG_EQUALIZER is not set
437# CONFIG_TUN is not set
438
439#
440# ARCnet devices
441#
442# CONFIG_ARCNET is not set
443
444#
445# Ethernet (10 or 100Mbit)
446#
447CONFIG_NET_ETHERNET=y
448CONFIG_MII=y
449# CONFIG_STNIC is not set
450# CONFIG_HAPPYMEAL is not set
451# CONFIG_SUNGEM is not set
452# CONFIG_NET_VENDOR_3COM is not set
453# CONFIG_SMC91X is not set
454
455#
456# Tulip family network device support
457#
458# CONFIG_NET_TULIP is not set
459# CONFIG_HP100 is not set
460CONFIG_NET_PCI=y
461# CONFIG_PCNET32 is not set
462# CONFIG_AMD8111_ETH is not set
463# CONFIG_ADAPTEC_STARFIRE is not set
464# CONFIG_B44 is not set
465# CONFIG_FORCEDETH is not set
466# CONFIG_DGRS is not set
467# CONFIG_EEPRO100 is not set
468# CONFIG_E100 is not set
469# CONFIG_FEALNX is not set
470# CONFIG_NATSEMI is not set
471# CONFIG_NE2K_PCI is not set
472CONFIG_8139CP=y
473# CONFIG_8139TOO is not set
474# CONFIG_SIS900 is not set
475# CONFIG_EPIC100 is not set
476# CONFIG_SUNDANCE is not set
477# CONFIG_TLAN is not set
478# CONFIG_VIA_RHINE is not set
479
480#
481# Ethernet (1000 Mbit)
482#
483# CONFIG_ACENIC is not set
484# CONFIG_DL2K is not set
485# CONFIG_E1000 is not set
486# CONFIG_NS83820 is not set
487# CONFIG_HAMACHI is not set
488# CONFIG_YELLOWFIN is not set
489# CONFIG_R8169 is not set
490# CONFIG_SK98LIN is not set
491# CONFIG_VIA_VELOCITY is not set
492# CONFIG_TIGON3 is not set
493
494#
495# Ethernet (10000 Mbit)
496#
497# CONFIG_IXGB is not set
498# CONFIG_S2IO is not set
499
500#
501# Token Ring devices
502#
503# CONFIG_TR is not set
504
505#
506# Wireless LAN (non-hamradio)
507#
508# CONFIG_NET_RADIO is not set
509
510#
511# Wan interfaces
512#
513# CONFIG_WAN is not set
514# CONFIG_FDDI is not set
515# CONFIG_HIPPI is not set
516# CONFIG_PPP is not set
517# CONFIG_SLIP is not set
518# CONFIG_NET_FC is not set
519# CONFIG_SHAPER is not set
520# CONFIG_NETCONSOLE is not set
521
522#
523# ISDN subsystem
524#
525# CONFIG_ISDN is not set
526
527#
528# Telephony Support
529#
530# CONFIG_PHONE is not set
531
532#
533# Input device support
534#
535CONFIG_INPUT=y
536
537#
538# Userland interfaces
539#
540CONFIG_INPUT_MOUSEDEV=y
541# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
542CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
543CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
544# CONFIG_INPUT_JOYDEV is not set
545# CONFIG_INPUT_TSDEV is not set
546# CONFIG_INPUT_EVDEV is not set
547# CONFIG_INPUT_EVBUG is not set
548
549#
550# Input I/O drivers
551#
552# CONFIG_GAMEPORT is not set
553CONFIG_SOUND_GAMEPORT=y
554# CONFIG_SERIO is not set
555# CONFIG_SERIO_I8042 is not set
556
557#
558# Input Device Drivers
559#
560# CONFIG_INPUT_KEYBOARD is not set
561# CONFIG_INPUT_MOUSE is not set
562# CONFIG_INPUT_JOYSTICK is not set
563# CONFIG_INPUT_TOUCHSCREEN is not set
564# CONFIG_INPUT_MISC is not set
565
566#
567# Character devices
568#
569CONFIG_VT=y
570CONFIG_VT_CONSOLE=y
571CONFIG_HW_CONSOLE=y
572# CONFIG_SERIAL_NONSTANDARD is not set
573
574#
575# Serial drivers
576#
577CONFIG_SERIAL_8250=m
578CONFIG_SERIAL_8250_NR_UARTS=4
579# CONFIG_SERIAL_8250_EXTENDED is not set
580
581#
582# Non-8250 serial port support
583#
584CONFIG_SERIAL_SH_SCI=y
585CONFIG_SERIAL_SH_SCI_CONSOLE=y
586CONFIG_SERIAL_CORE=y
587CONFIG_SERIAL_CORE_CONSOLE=y
588CONFIG_UNIX98_PTYS=y
589CONFIG_LEGACY_PTYS=y
590CONFIG_LEGACY_PTY_COUNT=256
591
592#
593# IPMI
594#
595# CONFIG_IPMI_HANDLER is not set
596
597#
598# Watchdog Cards
599#
600CONFIG_WATCHDOG=y
601# CONFIG_WATCHDOG_NOWAYOUT is not set
602
603#
604# Watchdog Device Drivers
605#
606# CONFIG_SOFT_WATCHDOG is not set
607CONFIG_SH_WDT=m
608
609#
610# PCI-based Watchdog Cards
611#
612# CONFIG_PCIPCWATCHDOG is not set
613# CONFIG_WDTPCI is not set
614# CONFIG_RTC is not set
615CONFIG_SH03_RTC=y
616# CONFIG_GEN_RTC is not set
617# CONFIG_DTLK is not set
618# CONFIG_R3964 is not set
619# CONFIG_APPLICOM is not set
620
621#
622# Ftape, the floppy tape device driver
623#
624# CONFIG_DRM is not set
625# CONFIG_RAW_DRIVER is not set
626
627#
628# I2C support
629#
630# CONFIG_I2C is not set
631
632#
633# Dallas's 1-wire bus
634#
635# CONFIG_W1 is not set
636
637#
638# Misc devices
639#
640
641#
642# Multimedia devices
643#
644# CONFIG_VIDEO_DEV is not set
645
646#
647# Digital Video Broadcasting Devices
648#
649# CONFIG_DVB is not set
650
651#
652# Graphics support
653#
654# CONFIG_FB is not set
655
656#
657# Console display driver support
658#
659# CONFIG_VGA_CONSOLE is not set
660CONFIG_DUMMY_CONSOLE=y
661
662#
663# Sound
664#
665# CONFIG_SOUND is not set
666
667#
668# USB support
669#
670# CONFIG_USB is not set
671CONFIG_USB_ARCH_HAS_HCD=y
672CONFIG_USB_ARCH_HAS_OHCI=y
673
674#
675# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
676#
677
678#
679# USB Gadget Support
680#
681# CONFIG_USB_GADGET is not set
682
683#
684# MMC/SD Card support
685#
686# CONFIG_MMC is not set
687
688#
689# InfiniBand support
690#
691# CONFIG_INFINIBAND is not set
692
693#
694# File systems
695#
696CONFIG_EXT2_FS=y
697CONFIG_EXT2_FS_XATTR=y
698# CONFIG_EXT2_FS_POSIX_ACL is not set
699# CONFIG_EXT2_FS_SECURITY is not set
700CONFIG_EXT3_FS=y
701CONFIG_EXT3_FS_XATTR=y
702CONFIG_EXT3_FS_POSIX_ACL=y
703# CONFIG_EXT3_FS_SECURITY is not set
704CONFIG_JBD=y
705# CONFIG_JBD_DEBUG is not set
706CONFIG_FS_MBCACHE=y
707# CONFIG_REISERFS_FS is not set
708# CONFIG_JFS_FS is not set
709CONFIG_FS_POSIX_ACL=y
710
711#
712# XFS support
713#
714# CONFIG_XFS_FS is not set
715# CONFIG_MINIX_FS is not set
716# CONFIG_ROMFS_FS is not set
717# CONFIG_QUOTA is not set
718CONFIG_DNOTIFY=y
719CONFIG_AUTOFS_FS=y
720CONFIG_AUTOFS4_FS=y
721
722#
723# CD-ROM/DVD Filesystems
724#
725CONFIG_ISO9660_FS=m
726CONFIG_JOLIET=y
727CONFIG_ZISOFS=y
728CONFIG_ZISOFS_FS=m
729CONFIG_UDF_FS=m
730CONFIG_UDF_NLS=y
731
732#
733# DOS/FAT/NT Filesystems
734#
735CONFIG_FAT_FS=m
736CONFIG_MSDOS_FS=m
737CONFIG_VFAT_FS=m
738CONFIG_FAT_DEFAULT_CODEPAGE=437
739CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
740# CONFIG_NTFS_FS is not set
741
742#
743# Pseudo filesystems
744#
745CONFIG_PROC_FS=y
746CONFIG_PROC_KCORE=y
747CONFIG_SYSFS=y
748# CONFIG_DEVFS_FS is not set
749# CONFIG_DEVPTS_FS_XATTR is not set
750CONFIG_TMPFS=y
751# CONFIG_TMPFS_XATTR is not set
752# CONFIG_HUGETLBFS is not set
753# CONFIG_HUGETLB_PAGE is not set
754CONFIG_RAMFS=y
755
756#
757# Miscellaneous filesystems
758#
759# CONFIG_ADFS_FS is not set
760# CONFIG_AFFS_FS is not set
761# CONFIG_HFS_FS is not set
762# CONFIG_HFSPLUS_FS is not set
763# CONFIG_BEFS_FS is not set
764# CONFIG_BFS_FS is not set
765# CONFIG_EFS_FS is not set
766# CONFIG_CRAMFS is not set
767# CONFIG_VXFS_FS is not set
768# CONFIG_HPFS_FS is not set
769# CONFIG_QNX4FS_FS is not set
770# CONFIG_SYSV_FS is not set
771# CONFIG_UFS_FS is not set
772
773#
774# Network File Systems
775#
776CONFIG_NFS_FS=y
777CONFIG_NFS_V3=y
778CONFIG_NFS_V4=y
779# CONFIG_NFS_DIRECTIO is not set
780CONFIG_NFSD=y
781CONFIG_NFSD_V3=y
782# CONFIG_NFSD_V4 is not set
783CONFIG_NFSD_TCP=y
784CONFIG_ROOT_NFS=y
785CONFIG_LOCKD=y
786CONFIG_LOCKD_V4=y
787CONFIG_EXPORTFS=y
788CONFIG_SUNRPC=y
789CONFIG_SUNRPC_GSS=y
790CONFIG_RPCSEC_GSS_KRB5=y
791# CONFIG_RPCSEC_GSS_SPKM3 is not set
792# CONFIG_SMB_FS is not set
793# CONFIG_CIFS is not set
794# CONFIG_NCP_FS is not set
795# CONFIG_CODA_FS is not set
796# CONFIG_AFS_FS is not set
797
798#
799# Partition Types
800#
801CONFIG_PARTITION_ADVANCED=y
802# CONFIG_ACORN_PARTITION is not set
803# CONFIG_OSF_PARTITION is not set
804# CONFIG_AMIGA_PARTITION is not set
805# CONFIG_ATARI_PARTITION is not set
806# CONFIG_MAC_PARTITION is not set
807CONFIG_MSDOS_PARTITION=y
808# CONFIG_BSD_DISKLABEL is not set
809# CONFIG_MINIX_SUBPARTITION is not set
810# CONFIG_SOLARIS_X86_PARTITION is not set
811# CONFIG_UNIXWARE_DISKLABEL is not set
812# CONFIG_LDM_PARTITION is not set
813# CONFIG_SGI_PARTITION is not set
814# CONFIG_ULTRIX_PARTITION is not set
815# CONFIG_SUN_PARTITION is not set
816# CONFIG_EFI_PARTITION is not set
817
818#
819# Native Language Support
820#
821CONFIG_NLS=m
822CONFIG_NLS_DEFAULT="iso8859-1"
823CONFIG_NLS_CODEPAGE_437=m
824CONFIG_NLS_CODEPAGE_737=m
825CONFIG_NLS_CODEPAGE_775=m
826CONFIG_NLS_CODEPAGE_850=m
827CONFIG_NLS_CODEPAGE_852=m
828CONFIG_NLS_CODEPAGE_855=m
829CONFIG_NLS_CODEPAGE_857=m
830CONFIG_NLS_CODEPAGE_860=m
831CONFIG_NLS_CODEPAGE_861=m
832CONFIG_NLS_CODEPAGE_862=m
833CONFIG_NLS_CODEPAGE_863=m
834CONFIG_NLS_CODEPAGE_864=m
835CONFIG_NLS_CODEPAGE_865=m
836CONFIG_NLS_CODEPAGE_866=m
837CONFIG_NLS_CODEPAGE_869=m
838CONFIG_NLS_CODEPAGE_936=m
839CONFIG_NLS_CODEPAGE_950=m
840CONFIG_NLS_CODEPAGE_932=m
841CONFIG_NLS_CODEPAGE_949=m
842CONFIG_NLS_CODEPAGE_874=m
843CONFIG_NLS_ISO8859_8=m
844CONFIG_NLS_CODEPAGE_1250=m
845CONFIG_NLS_CODEPAGE_1251=m
846CONFIG_NLS_ASCII=m
847CONFIG_NLS_ISO8859_1=m
848CONFIG_NLS_ISO8859_2=m
849CONFIG_NLS_ISO8859_3=m
850CONFIG_NLS_ISO8859_4=m
851CONFIG_NLS_ISO8859_5=m
852CONFIG_NLS_ISO8859_6=m
853CONFIG_NLS_ISO8859_7=m
854CONFIG_NLS_ISO8859_9=m
855CONFIG_NLS_ISO8859_13=m
856CONFIG_NLS_ISO8859_14=m
857CONFIG_NLS_ISO8859_15=m
858CONFIG_NLS_KOI8_R=m
859CONFIG_NLS_KOI8_U=m
860CONFIG_NLS_UTF8=m
861
862#
863# Profiling support
864#
865CONFIG_PROFILING=y
866CONFIG_OPROFILE=m
867
868#
869# Kernel hacking
870#
871# CONFIG_DEBUG_KERNEL is not set
872CONFIG_DEBUG_PREEMPT=y
873# CONFIG_FRAME_POINTER is not set
874CONFIG_SH_STANDARD_BIOS=y
875# CONFIG_EARLY_SCIF_CONSOLE is not set
876# CONFIG_EARLY_PRINTK is not set
877# CONFIG_KGDB is not set
878
879#
880# Security options
881#
882# CONFIG_KEYS is not set
883# CONFIG_SECURITY is not set
884
885#
886# Cryptographic options
887#
888CONFIG_CRYPTO=y
889CONFIG_CRYPTO_HMAC=y
890# CONFIG_CRYPTO_NULL is not set
891# CONFIG_CRYPTO_MD4 is not set
892CONFIG_CRYPTO_MD5=y
893CONFIG_CRYPTO_SHA1=y
894# CONFIG_CRYPTO_SHA256 is not set
895# CONFIG_CRYPTO_SHA512 is not set
896# CONFIG_CRYPTO_WP512 is not set
897CONFIG_CRYPTO_DES=y
898# CONFIG_CRYPTO_BLOWFISH is not set
899# CONFIG_CRYPTO_TWOFISH is not set
900# CONFIG_CRYPTO_SERPENT is not set
901# CONFIG_CRYPTO_AES is not set
902# CONFIG_CRYPTO_CAST5 is not set
903# CONFIG_CRYPTO_CAST6 is not set
904# CONFIG_CRYPTO_TEA is not set
905# CONFIG_CRYPTO_ARC4 is not set
906# CONFIG_CRYPTO_KHAZAD is not set
907# CONFIG_CRYPTO_ANUBIS is not set
908CONFIG_CRYPTO_DEFLATE=y
909# CONFIG_CRYPTO_MICHAEL_MIC is not set
910# CONFIG_CRYPTO_CRC32C is not set
911# CONFIG_CRYPTO_TEST is not set
912
913#
914# Hardware crypto devices
915#
916
917#
918# Library routines
919#
920CONFIG_CRC_CCITT=y
921CONFIG_CRC32=y
922# CONFIG_LIBCRC32C is not set
923CONFIG_ZLIB_INFLATE=y
924CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
new file mode 100644
index 000000000000..69cf02a24761
--- /dev/null
+++ b/arch/sh/configs/snapgear_defconfig
@@ -0,0 +1,699 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:51 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25# CONFIG_SYSVIPC is not set
26# CONFIG_POSIX_MQUEUE is not set
27# CONFIG_BSD_PROCESS_ACCT is not set
28# CONFIG_SYSCTL is not set
29# CONFIG_AUDIT is not set
30CONFIG_LOG_BUF_SHIFT=14
31# CONFIG_HOTPLUG is not set
32CONFIG_KOBJECT_UEVENT=y
33# CONFIG_IKCONFIG is not set
34# CONFIG_EMBEDDED is not set
35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_EXTRA_PASS is not set
37CONFIG_FUTEX=y
38CONFIG_EPOLL=y
39# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
40CONFIG_SHMEM=y
41CONFIG_CC_ALIGN_FUNCTIONS=0
42CONFIG_CC_ALIGN_LABELS=0
43CONFIG_CC_ALIGN_LOOPS=0
44CONFIG_CC_ALIGN_JUMPS=0
45# CONFIG_TINY_SHMEM is not set
46
47#
48# Loadable module support
49#
50# CONFIG_MODULES is not set
51
52#
53# System type
54#
55# CONFIG_SH_SOLUTION_ENGINE is not set
56# CONFIG_SH_7751_SOLUTION_ENGINE is not set
57# CONFIG_SH_7300_SOLUTION_ENGINE is not set
58# CONFIG_SH_73180_SOLUTION_ENGINE is not set
59# CONFIG_SH_7751_SYSTEMH is not set
60# CONFIG_SH_STB1_HARP is not set
61# CONFIG_SH_STB1_OVERDRIVE is not set
62# CONFIG_SH_HP620 is not set
63# CONFIG_SH_HP680 is not set
64# CONFIG_SH_HP690 is not set
65# CONFIG_SH_CQREEK is not set
66# CONFIG_SH_DMIDA is not set
67# CONFIG_SH_EC3104 is not set
68# CONFIG_SH_SATURN is not set
69# CONFIG_SH_DREAMCAST is not set
70# CONFIG_SH_CAT68701 is not set
71# CONFIG_SH_BIGSUR is not set
72# CONFIG_SH_SH2000 is not set
73# CONFIG_SH_ADX is not set
74# CONFIG_SH_MPC1211 is not set
75# CONFIG_SH_SH03 is not set
76CONFIG_SH_SECUREEDGE5410=y
77# CONFIG_SH_HS7751RVOIP is not set
78# CONFIG_SH_RTS7751R2D is not set
79# CONFIG_SH_EDOSK7705 is not set
80# CONFIG_SH_SH4202_MICRODEV is not set
81# CONFIG_SH_UNKNOWN is not set
82# CONFIG_CPU_SH2 is not set
83# CONFIG_CPU_SH3 is not set
84CONFIG_CPU_SH4=y
85# CONFIG_CPU_SUBTYPE_SH7604 is not set
86# CONFIG_CPU_SUBTYPE_SH7300 is not set
87# CONFIG_CPU_SUBTYPE_SH7705 is not set
88# CONFIG_CPU_SUBTYPE_SH7707 is not set
89# CONFIG_CPU_SUBTYPE_SH7708 is not set
90# CONFIG_CPU_SUBTYPE_SH7709 is not set
91# CONFIG_CPU_SUBTYPE_SH7750 is not set
92CONFIG_CPU_SUBTYPE_SH7751=y
93# CONFIG_CPU_SUBTYPE_SH7760 is not set
94# CONFIG_CPU_SUBTYPE_SH73180 is not set
95# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
96# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
97# CONFIG_CPU_SUBTYPE_SH4_202 is not set
98CONFIG_MMU=y
99# CONFIG_CMDLINE_BOOL is not set
100CONFIG_MEMORY_START=0x08000000
101CONFIG_MEMORY_SIZE=0x01000000
102CONFIG_MEMORY_SET=y
103# CONFIG_MEMORY_OVERRIDE is not set
104CONFIG_SH_RTC=y
105CONFIG_SH_FPU=y
106CONFIG_ZERO_PAGE_OFFSET=0x00001000
107CONFIG_BOOT_LINK_OFFSET=0x00800000
108CONFIG_CPU_LITTLE_ENDIAN=y
109# CONFIG_PREEMPT is not set
110# CONFIG_UBC_WAKEUP is not set
111# CONFIG_SH_WRITETHROUGH is not set
112# CONFIG_SH_OCRAM is not set
113# CONFIG_SH_STORE_QUEUES is not set
114# CONFIG_SMP is not set
115CONFIG_SH_PCLK_CALC=y
116CONFIG_SH_PCLK_FREQ=60013568
117
118#
119# CPU Frequency scaling
120#
121# CONFIG_CPU_FREQ is not set
122
123#
124# DMA support
125#
126CONFIG_SH_DMA=y
127CONFIG_NR_ONCHIP_DMA_CHANNELS=4
128# CONFIG_NR_DMA_CHANNELS_BOOL is not set
129
130#
131# Companion Chips
132#
133# CONFIG_HD6446X_SERIES is not set
134
135#
136# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
137#
138CONFIG_PCI=y
139# CONFIG_SH_PCIDMA_NONCOHERENT is not set
140CONFIG_PCI_AUTO=y
141CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
142# CONFIG_PCI_LEGACY_PROC is not set
143CONFIG_PCI_NAMES=y
144
145#
146# PCCARD (PCMCIA/CardBus) support
147#
148# CONFIG_PCCARD is not set
149
150#
151# PC-card bridges
152#
153
154#
155# PCI Hotplug Support
156#
157# CONFIG_HOTPLUG_PCI is not set
158
159#
160# Executable file formats
161#
162CONFIG_BINFMT_ELF=y
163# CONFIG_BINFMT_FLAT is not set
164# CONFIG_BINFMT_MISC is not set
165
166#
167# SH initrd options
168#
169# CONFIG_EMBEDDED_RAMDISK is not set
170
171#
172# Device Drivers
173#
174
175#
176# Generic Driver Options
177#
178CONFIG_STANDALONE=y
179CONFIG_PREVENT_FIRMWARE_BUILD=y
180# CONFIG_FW_LOADER is not set
181
182#
183# Memory Technology Devices (MTD)
184#
185# CONFIG_MTD is not set
186
187#
188# Parallel port support
189#
190# CONFIG_PARPORT is not set
191
192#
193# Plug and Play support
194#
195
196#
197# Block devices
198#
199# CONFIG_BLK_DEV_FD is not set
200# CONFIG_BLK_CPQ_DA is not set
201# CONFIG_BLK_CPQ_CISS_DA is not set
202# CONFIG_BLK_DEV_DAC960 is not set
203# CONFIG_BLK_DEV_UMEM is not set
204# CONFIG_BLK_DEV_COW_COMMON is not set
205# CONFIG_BLK_DEV_LOOP is not set
206# CONFIG_BLK_DEV_NBD is not set
207# CONFIG_BLK_DEV_SX8 is not set
208CONFIG_BLK_DEV_RAM=y
209CONFIG_BLK_DEV_RAM_COUNT=16
210CONFIG_BLK_DEV_RAM_SIZE=4096
211CONFIG_BLK_DEV_INITRD=y
212CONFIG_INITRAMFS_SOURCE=""
213# CONFIG_LBD is not set
214# CONFIG_CDROM_PKTCDVD is not set
215
216#
217# IO Schedulers
218#
219CONFIG_IOSCHED_NOOP=y
220CONFIG_IOSCHED_AS=y
221CONFIG_IOSCHED_DEADLINE=y
222CONFIG_IOSCHED_CFQ=y
223# CONFIG_ATA_OVER_ETH is not set
224
225#
226# ATA/ATAPI/MFM/RLL support
227#
228# CONFIG_IDE is not set
229
230#
231# SCSI device support
232#
233# CONFIG_SCSI is not set
234
235#
236# Multi-device support (RAID and LVM)
237#
238# CONFIG_MD is not set
239
240#
241# Fusion MPT device support
242#
243
244#
245# IEEE 1394 (FireWire) support
246#
247# CONFIG_IEEE1394 is not set
248
249#
250# I2O device support
251#
252# CONFIG_I2O is not set
253
254#
255# Networking support
256#
257CONFIG_NET=y
258
259#
260# Networking options
261#
262# CONFIG_PACKET is not set
263# CONFIG_NETLINK_DEV is not set
264# CONFIG_UNIX is not set
265# CONFIG_NET_KEY is not set
266CONFIG_INET=y
267# CONFIG_IP_MULTICAST is not set
268# CONFIG_IP_ADVANCED_ROUTER is not set
269CONFIG_IP_PNP=y
270CONFIG_IP_PNP_DHCP=y
271# CONFIG_IP_PNP_BOOTP is not set
272# CONFIG_IP_PNP_RARP is not set
273# CONFIG_NET_IPIP is not set
274# CONFIG_NET_IPGRE is not set
275# CONFIG_ARPD is not set
276# CONFIG_SYN_COOKIES is not set
277# CONFIG_INET_AH is not set
278# CONFIG_INET_ESP is not set
279# CONFIG_INET_IPCOMP is not set
280# CONFIG_INET_TUNNEL is not set
281CONFIG_IP_TCPDIAG=y
282# CONFIG_IP_TCPDIAG_IPV6 is not set
283# CONFIG_IPV6 is not set
284# CONFIG_NETFILTER is not set
285
286#
287# SCTP Configuration (EXPERIMENTAL)
288#
289# CONFIG_IP_SCTP is not set
290# CONFIG_ATM is not set
291# CONFIG_BRIDGE is not set
292# CONFIG_VLAN_8021Q is not set
293# CONFIG_DECNET is not set
294# CONFIG_LLC2 is not set
295# CONFIG_IPX is not set
296# CONFIG_ATALK is not set
297# CONFIG_X25 is not set
298# CONFIG_LAPB is not set
299# CONFIG_NET_DIVERT is not set
300# CONFIG_ECONET is not set
301# CONFIG_WAN_ROUTER is not set
302
303#
304# QoS and/or fair queueing
305#
306# CONFIG_NET_SCHED is not set
307# CONFIG_NET_CLS_ROUTE is not set
308
309#
310# Network testing
311#
312# CONFIG_NET_PKTGEN is not set
313# CONFIG_NETPOLL is not set
314# CONFIG_NET_POLL_CONTROLLER is not set
315# CONFIG_HAMRADIO is not set
316# CONFIG_IRDA is not set
317# CONFIG_BT is not set
318CONFIG_NETDEVICES=y
319# CONFIG_DUMMY is not set
320# CONFIG_BONDING is not set
321# CONFIG_EQUALIZER is not set
322# CONFIG_TUN is not set
323
324#
325# ARCnet devices
326#
327# CONFIG_ARCNET is not set
328
329#
330# Ethernet (10 or 100Mbit)
331#
332CONFIG_NET_ETHERNET=y
333CONFIG_MII=y
334# CONFIG_STNIC is not set
335# CONFIG_HAPPYMEAL is not set
336# CONFIG_SUNGEM is not set
337# CONFIG_NET_VENDOR_3COM is not set
338# CONFIG_SMC91X is not set
339
340#
341# Tulip family network device support
342#
343# CONFIG_NET_TULIP is not set
344# CONFIG_HP100 is not set
345CONFIG_NET_PCI=y
346# CONFIG_PCNET32 is not set
347# CONFIG_AMD8111_ETH is not set
348# CONFIG_ADAPTEC_STARFIRE is not set
349# CONFIG_B44 is not set
350# CONFIG_FORCEDETH is not set
351# CONFIG_DGRS is not set
352# CONFIG_EEPRO100 is not set
353# CONFIG_E100 is not set
354# CONFIG_FEALNX is not set
355# CONFIG_NATSEMI is not set
356# CONFIG_NE2K_PCI is not set
357# CONFIG_8139CP is not set
358CONFIG_8139TOO=y
359# CONFIG_8139TOO_PIO is not set
360# CONFIG_8139TOO_TUNE_TWISTER is not set
361# CONFIG_8139TOO_8129 is not set
362# CONFIG_8139_OLD_RX_RESET is not set
363# CONFIG_SIS900 is not set
364# CONFIG_EPIC100 is not set
365# CONFIG_SUNDANCE is not set
366# CONFIG_TLAN is not set
367# CONFIG_VIA_RHINE is not set
368
369#
370# Ethernet (1000 Mbit)
371#
372# CONFIG_ACENIC is not set
373# CONFIG_DL2K is not set
374# CONFIG_E1000 is not set
375# CONFIG_NS83820 is not set
376# CONFIG_HAMACHI is not set
377# CONFIG_YELLOWFIN is not set
378# CONFIG_R8169 is not set
379# CONFIG_SK98LIN is not set
380# CONFIG_VIA_VELOCITY is not set
381# CONFIG_TIGON3 is not set
382
383#
384# Ethernet (10000 Mbit)
385#
386# CONFIG_IXGB is not set
387# CONFIG_S2IO is not set
388
389#
390# Token Ring devices
391#
392# CONFIG_TR is not set
393
394#
395# Wireless LAN (non-hamradio)
396#
397# CONFIG_NET_RADIO is not set
398
399#
400# Wan interfaces
401#
402# CONFIG_WAN is not set
403# CONFIG_FDDI is not set
404# CONFIG_HIPPI is not set
405# CONFIG_PPP is not set
406# CONFIG_SLIP is not set
407# CONFIG_SHAPER is not set
408# CONFIG_NETCONSOLE is not set
409
410#
411# ISDN subsystem
412#
413# CONFIG_ISDN is not set
414
415#
416# Telephony Support
417#
418# CONFIG_PHONE is not set
419
420#
421# Input device support
422#
423CONFIG_INPUT=y
424
425#
426# Userland interfaces
427#
428CONFIG_INPUT_MOUSEDEV=y
429CONFIG_INPUT_MOUSEDEV_PSAUX=y
430CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
431CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
432# CONFIG_INPUT_JOYDEV is not set
433# CONFIG_INPUT_TSDEV is not set
434# CONFIG_INPUT_EVDEV is not set
435# CONFIG_INPUT_EVBUG is not set
436
437#
438# Input I/O drivers
439#
440# CONFIG_GAMEPORT is not set
441CONFIG_SOUND_GAMEPORT=y
442CONFIG_SERIO=y
443CONFIG_SERIO_I8042=y
444CONFIG_SERIO_SERPORT=y
445# CONFIG_SERIO_CT82C710 is not set
446# CONFIG_SERIO_PCIPS2 is not set
447# CONFIG_SERIO_RAW is not set
448
449#
450# Input Device Drivers
451#
452# CONFIG_INPUT_KEYBOARD is not set
453# CONFIG_INPUT_MOUSE is not set
454# CONFIG_INPUT_JOYSTICK is not set
455# CONFIG_INPUT_TOUCHSCREEN is not set
456# CONFIG_INPUT_MISC is not set
457
458#
459# Character devices
460#
461CONFIG_VT=y
462CONFIG_VT_CONSOLE=y
463CONFIG_HW_CONSOLE=y
464# CONFIG_SERIAL_NONSTANDARD is not set
465
466#
467# Serial drivers
468#
469# CONFIG_SERIAL_8250 is not set
470
471#
472# Non-8250 serial port support
473#
474# CONFIG_SERIAL_SH_SCI is not set
475CONFIG_UNIX98_PTYS=y
476CONFIG_LEGACY_PTYS=y
477CONFIG_LEGACY_PTY_COUNT=256
478
479#
480# IPMI
481#
482# CONFIG_IPMI_HANDLER is not set
483
484#
485# Watchdog Cards
486#
487# CONFIG_WATCHDOG is not set
488# CONFIG_RTC is not set
489# CONFIG_GEN_RTC is not set
490# CONFIG_DTLK is not set
491# CONFIG_R3964 is not set
492# CONFIG_APPLICOM is not set
493
494#
495# Ftape, the floppy tape device driver
496#
497# CONFIG_DRM is not set
498# CONFIG_RAW_DRIVER is not set
499
500#
501# I2C support
502#
503# CONFIG_I2C is not set
504
505#
506# Dallas's 1-wire bus
507#
508# CONFIG_W1 is not set
509
510#
511# Misc devices
512#
513
514#
515# Multimedia devices
516#
517# CONFIG_VIDEO_DEV is not set
518
519#
520# Digital Video Broadcasting Devices
521#
522# CONFIG_DVB is not set
523
524#
525# Graphics support
526#
527# CONFIG_FB is not set
528
529#
530# Console display driver support
531#
532CONFIG_VGA_CONSOLE=y
533CONFIG_DUMMY_CONSOLE=y
534
535#
536# Sound
537#
538# CONFIG_SOUND is not set
539
540#
541# USB support
542#
543# CONFIG_USB is not set
544CONFIG_USB_ARCH_HAS_HCD=y
545CONFIG_USB_ARCH_HAS_OHCI=y
546
547#
548# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
549#
550
551#
552# USB Gadget Support
553#
554# CONFIG_USB_GADGET is not set
555
556#
557# MMC/SD Card support
558#
559# CONFIG_MMC is not set
560
561#
562# InfiniBand support
563#
564# CONFIG_INFINIBAND is not set
565
566#
567# File systems
568#
569CONFIG_EXT2_FS=y
570# CONFIG_EXT2_FS_XATTR is not set
571# CONFIG_EXT3_FS is not set
572# CONFIG_JBD is not set
573# CONFIG_REISERFS_FS is not set
574# CONFIG_JFS_FS is not set
575
576#
577# XFS support
578#
579# CONFIG_XFS_FS is not set
580# CONFIG_MINIX_FS is not set
581CONFIG_ROMFS_FS=y
582# CONFIG_QUOTA is not set
583CONFIG_DNOTIFY=y
584# CONFIG_AUTOFS_FS is not set
585# CONFIG_AUTOFS4_FS is not set
586
587#
588# CD-ROM/DVD Filesystems
589#
590# CONFIG_ISO9660_FS is not set
591# CONFIG_UDF_FS is not set
592
593#
594# DOS/FAT/NT Filesystems
595#
596# CONFIG_MSDOS_FS is not set
597# CONFIG_VFAT_FS is not set
598# CONFIG_NTFS_FS is not set
599
600#
601# Pseudo filesystems
602#
603CONFIG_PROC_FS=y
604# CONFIG_PROC_KCORE is not set
605CONFIG_SYSFS=y
606CONFIG_DEVFS_FS=y
607CONFIG_DEVFS_MOUNT=y
608# CONFIG_DEVFS_DEBUG is not set
609# CONFIG_DEVPTS_FS_XATTR is not set
610CONFIG_TMPFS=y
611# CONFIG_TMPFS_XATTR is not set
612# CONFIG_HUGETLBFS is not set
613# CONFIG_HUGETLB_PAGE is not set
614CONFIG_RAMFS=y
615
616#
617# Miscellaneous filesystems
618#
619# CONFIG_ADFS_FS is not set
620# CONFIG_AFFS_FS is not set
621# CONFIG_HFS_FS is not set
622# CONFIG_HFSPLUS_FS is not set
623# CONFIG_BEFS_FS is not set
624# CONFIG_BFS_FS is not set
625# CONFIG_EFS_FS is not set
626CONFIG_CRAMFS=y
627# CONFIG_VXFS_FS is not set
628# CONFIG_HPFS_FS is not set
629# CONFIG_QNX4FS_FS is not set
630# CONFIG_SYSV_FS is not set
631# CONFIG_UFS_FS is not set
632
633#
634# Network File Systems
635#
636CONFIG_NFS_FS=y
637CONFIG_NFS_V3=y
638# CONFIG_NFS_V4 is not set
639# CONFIG_NFS_DIRECTIO is not set
640# CONFIG_NFSD is not set
641CONFIG_ROOT_NFS=y
642CONFIG_LOCKD=y
643CONFIG_LOCKD_V4=y
644CONFIG_SUNRPC=y
645# CONFIG_RPCSEC_GSS_KRB5 is not set
646# CONFIG_RPCSEC_GSS_SPKM3 is not set
647# CONFIG_SMB_FS is not set
648# CONFIG_CIFS is not set
649# CONFIG_NCP_FS is not set
650# CONFIG_CODA_FS is not set
651# CONFIG_AFS_FS is not set
652
653#
654# Partition Types
655#
656# CONFIG_PARTITION_ADVANCED is not set
657CONFIG_MSDOS_PARTITION=y
658
659#
660# Native Language Support
661#
662# CONFIG_NLS is not set
663
664#
665# Profiling support
666#
667# CONFIG_PROFILING is not set
668
669#
670# Kernel hacking
671#
672# CONFIG_DEBUG_KERNEL is not set
673# CONFIG_FRAME_POINTER is not set
674# CONFIG_SH_STANDARD_BIOS is not set
675# CONFIG_EARLY_SCIF_CONSOLE is not set
676# CONFIG_KGDB is not set
677
678#
679# Security options
680#
681# CONFIG_KEYS is not set
682# CONFIG_SECURITY is not set
683
684#
685# Cryptographic options
686#
687# CONFIG_CRYPTO is not set
688
689#
690# Hardware crypto devices
691#
692
693#
694# Library routines
695#
696# CONFIG_CRC_CCITT is not set
697CONFIG_CRC32=y
698# CONFIG_LIBCRC32C is not set
699CONFIG_ZLIB_INFLATE=y
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
new file mode 100644
index 000000000000..431c9c9da165
--- /dev/null
+++ b/arch/sh/configs/systemh_defconfig
@@ -0,0 +1,509 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-sh
4# Wed Mar 2 15:09:53 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17# CONFIG_CLEAN_COMPILE is not set
18CONFIG_BROKEN=y
19CONFIG_BROKEN_ON_SMP=y
20CONFIG_LOCK_KERNEL=y
21
22#
23# General setup
24#
25CONFIG_LOCALVERSION=""
26CONFIG_SWAP=y
27# CONFIG_SYSVIPC is not set
28# CONFIG_BSD_PROCESS_ACCT is not set
29# CONFIG_SYSCTL is not set
30# CONFIG_AUDIT is not set
31CONFIG_LOG_BUF_SHIFT=14
32# CONFIG_HOTPLUG is not set
33# CONFIG_IKCONFIG is not set
34CONFIG_EMBEDDED=y
35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_EXTRA_PASS is not set
37CONFIG_FUTEX=y
38CONFIG_EPOLL=y
39# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
40CONFIG_SHMEM=y
41CONFIG_CC_ALIGN_FUNCTIONS=0
42CONFIG_CC_ALIGN_LABELS=0
43CONFIG_CC_ALIGN_LOOPS=0
44CONFIG_CC_ALIGN_JUMPS=0
45# CONFIG_TINY_SHMEM is not set
46
47#
48# Loadable module support
49#
50CONFIG_MODULES=y
51CONFIG_MODULE_UNLOAD=y
52# CONFIG_MODULE_FORCE_UNLOAD is not set
53CONFIG_OBSOLETE_MODPARM=y
54# CONFIG_MODVERSIONS is not set
55# CONFIG_MODULE_SRCVERSION_ALL is not set
56# CONFIG_KMOD is not set
57
58#
59# System type
60#
61# CONFIG_SH_SOLUTION_ENGINE is not set
62# CONFIG_SH_7751_SOLUTION_ENGINE is not set
63# CONFIG_SH_7300_SOLUTION_ENGINE is not set
64# CONFIG_SH_73180_SOLUTION_ENGINE is not set
65CONFIG_SH_7751_SYSTEMH=y
66# CONFIG_SH_STB1_HARP is not set
67# CONFIG_SH_STB1_OVERDRIVE is not set
68# CONFIG_SH_HP620 is not set
69# CONFIG_SH_HP680 is not set
70# CONFIG_SH_HP690 is not set
71# CONFIG_SH_CQREEK is not set
72# CONFIG_SH_DMIDA is not set
73# CONFIG_SH_EC3104 is not set
74# CONFIG_SH_SATURN is not set
75# CONFIG_SH_DREAMCAST is not set
76# CONFIG_SH_CAT68701 is not set
77# CONFIG_SH_BIGSUR is not set
78# CONFIG_SH_SH2000 is not set
79# CONFIG_SH_ADX is not set
80# CONFIG_SH_MPC1211 is not set
81# CONFIG_SH_SH03 is not set
82# CONFIG_SH_SECUREEDGE5410 is not set
83# CONFIG_SH_HS7751RVOIP is not set
84# CONFIG_SH_RTS7751R2D is not set
85# CONFIG_SH_EDOSK7705 is not set
86# CONFIG_SH_SH4202_MICRODEV is not set
87# CONFIG_SH_UNKNOWN is not set
88# CONFIG_CPU_SH2 is not set
89# CONFIG_CPU_SH3 is not set
90CONFIG_CPU_SH4=y
91# CONFIG_CPU_SUBTYPE_SH7604 is not set
92# CONFIG_CPU_SUBTYPE_SH7300 is not set
93# CONFIG_CPU_SUBTYPE_SH7705 is not set
94# CONFIG_CPU_SUBTYPE_SH7707 is not set
95# CONFIG_CPU_SUBTYPE_SH7708 is not set
96# CONFIG_CPU_SUBTYPE_SH7709 is not set
97# CONFIG_CPU_SUBTYPE_SH7750 is not set
98CONFIG_CPU_SUBTYPE_SH7751=y
99# CONFIG_CPU_SUBTYPE_SH7760 is not set
100# CONFIG_CPU_SUBTYPE_SH73180 is not set
101# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
102# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
103# CONFIG_CPU_SUBTYPE_SH4_202 is not set
104CONFIG_MMU=y
105# CONFIG_CMDLINE_BOOL is not set
106CONFIG_MEMORY_START=0x0c000000
107CONFIG_MEMORY_SIZE=0x00400000
108# CONFIG_MEMORY_OVERRIDE is not set
109CONFIG_SH_RTC=y
110CONFIG_SH_FPU=y
111CONFIG_ZERO_PAGE_OFFSET=0x00001000
112CONFIG_BOOT_LINK_OFFSET=0x00800000
113CONFIG_CPU_LITTLE_ENDIAN=y
114CONFIG_PREEMPT=y
115# CONFIG_UBC_WAKEUP is not set
116# CONFIG_SH_WRITETHROUGH is not set
117# CONFIG_SH_OCRAM is not set
118# CONFIG_SH_STORE_QUEUES is not set
119# CONFIG_SMP is not set
120CONFIG_SH_PCLK_CALC=y
121CONFIG_SH_PCLK_FREQ=49876504
122
123#
124# CPU Frequency scaling
125#
126# CONFIG_CPU_FREQ is not set
127
128#
129# DMA support
130#
131# CONFIG_SH_DMA is not set
132
133#
134# Companion Chips
135#
136# CONFIG_HD6446X_SERIES is not set
137
138#
139# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
140#
141CONFIG_PCI=y
142# CONFIG_SH_PCIDMA_NONCOHERENT is not set
143CONFIG_PCI_AUTO=y
144CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
145CONFIG_PCI_LEGACY_PROC=y
146CONFIG_PCI_NAMES=y
147
148#
149# PCCARD (PCMCIA/CardBus) support
150#
151# CONFIG_PCCARD is not set
152
153#
154# PC-card bridges
155#
156
157#
158# PCI Hotplug Support
159#
160# CONFIG_HOTPLUG_PCI is not set
161
162#
163# Executable file formats
164#
165CONFIG_BINFMT_ELF=y
166# CONFIG_BINFMT_FLAT is not set
167# CONFIG_BINFMT_MISC is not set
168
169#
170# SH initrd options
171#
172# CONFIG_EMBEDDED_RAMDISK is not set
173
174#
175# Device Drivers
176#
177
178#
179# Generic Driver Options
180#
181# CONFIG_STANDALONE is not set
182CONFIG_PREVENT_FIRMWARE_BUILD=y
183# CONFIG_FW_LOADER is not set
184
185#
186# Memory Technology Devices (MTD)
187#
188# CONFIG_MTD is not set
189
190#
191# Parallel port support
192#
193# CONFIG_PARPORT is not set
194
195#
196# Plug and Play support
197#
198
199#
200# Block devices
201#
202# CONFIG_BLK_DEV_FD is not set
203# CONFIG_BLK_CPQ_DA is not set
204# CONFIG_BLK_CPQ_CISS_DA is not set
205# CONFIG_BLK_DEV_DAC960 is not set
206# CONFIG_BLK_DEV_UMEM is not set
207# CONFIG_BLK_DEV_COW_COMMON is not set
208# CONFIG_BLK_DEV_LOOP is not set
209# CONFIG_BLK_DEV_SX8 is not set
210CONFIG_BLK_DEV_RAM=y
211CONFIG_BLK_DEV_RAM_COUNT=16
212CONFIG_BLK_DEV_RAM_SIZE=1024
213CONFIG_BLK_DEV_INITRD=y
214CONFIG_INITRAMFS_SOURCE=""
215# CONFIG_LBD is not set
216# CONFIG_CDROM_PKTCDVD is not set
217
218#
219# IO Schedulers
220#
221CONFIG_IOSCHED_NOOP=y
222CONFIG_IOSCHED_AS=y
223CONFIG_IOSCHED_DEADLINE=y
224CONFIG_IOSCHED_CFQ=y
225
226#
227# ATA/ATAPI/MFM/RLL support
228#
229# CONFIG_IDE is not set
230
231#
232# SCSI device support
233#
234# CONFIG_SCSI is not set
235
236#
237# Multi-device support (RAID and LVM)
238#
239# CONFIG_MD is not set
240
241#
242# Fusion MPT device support
243#
244
245#
246# IEEE 1394 (FireWire) support
247#
248# CONFIG_IEEE1394 is not set
249
250#
251# I2O device support
252#
253# CONFIG_I2O is not set
254
255#
256# Networking support
257#
258# CONFIG_NET is not set
259# CONFIG_NETPOLL is not set
260# CONFIG_NET_POLL_CONTROLLER is not set
261
262#
263# ISDN subsystem
264#
265
266#
267# Telephony Support
268#
269# CONFIG_PHONE is not set
270
271#
272# Input device support
273#
274# CONFIG_INPUT is not set
275
276#
277# Userland interfaces
278#
279
280#
281# Input I/O drivers
282#
283# CONFIG_GAMEPORT is not set
284CONFIG_SOUND_GAMEPORT=y
285CONFIG_SERIO=y
286# CONFIG_SERIO_I8042 is not set
287# CONFIG_SERIO_SERPORT is not set
288# CONFIG_SERIO_CT82C710 is not set
289# CONFIG_SERIO_PCIPS2 is not set
290# CONFIG_SERIO_LIBPS2 is not set
291# CONFIG_SERIO_RAW is not set
292
293#
294# Input Device Drivers
295#
296
297#
298# Character devices
299#
300# CONFIG_VT is not set
301# CONFIG_SERIAL_NONSTANDARD is not set
302
303#
304# Serial drivers
305#
306# CONFIG_SERIAL_8250 is not set
307
308#
309# Non-8250 serial port support
310#
311# CONFIG_SERIAL_SH_SCI is not set
312CONFIG_UNIX98_PTYS=y
313CONFIG_LEGACY_PTYS=y
314CONFIG_LEGACY_PTY_COUNT=256
315
316#
317# IPMI
318#
319# CONFIG_IPMI_HANDLER is not set
320
321#
322# Watchdog Cards
323#
324# CONFIG_WATCHDOG is not set
325# CONFIG_RTC is not set
326# CONFIG_GEN_RTC is not set
327# CONFIG_DTLK is not set
328# CONFIG_R3964 is not set
329# CONFIG_APPLICOM is not set
330
331#
332# Ftape, the floppy tape device driver
333#
334# CONFIG_DRM is not set
335# CONFIG_RAW_DRIVER is not set
336
337#
338# I2C support
339#
340# CONFIG_I2C is not set
341
342#
343# Dallas's 1-wire bus
344#
345# CONFIG_W1 is not set
346
347#
348# Misc devices
349#
350
351#
352# Multimedia devices
353#
354# CONFIG_VIDEO_DEV is not set
355
356#
357# Digital Video Broadcasting Devices
358#
359
360#
361# Graphics support
362#
363# CONFIG_FB is not set
364
365#
366# Sound
367#
368# CONFIG_SOUND is not set
369
370#
371# USB support
372#
373# CONFIG_USB is not set
374CONFIG_USB_ARCH_HAS_HCD=y
375CONFIG_USB_ARCH_HAS_OHCI=y
376
377#
378# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
379#
380
381#
382# USB Gadget Support
383#
384# CONFIG_USB_GADGET is not set
385
386#
387# MMC/SD Card support
388#
389# CONFIG_MMC is not set
390
391#
392# InfiniBand support
393#
394# CONFIG_INFINIBAND is not set
395
396#
397# File systems
398#
399# CONFIG_EXT2_FS is not set
400# CONFIG_EXT3_FS is not set
401# CONFIG_JBD is not set
402# CONFIG_REISERFS_FS is not set
403# CONFIG_JFS_FS is not set
404
405#
406# XFS support
407#
408# CONFIG_XFS_FS is not set
409# CONFIG_MINIX_FS is not set
410CONFIG_ROMFS_FS=y
411# CONFIG_QUOTA is not set
412CONFIG_DNOTIFY=y
413# CONFIG_AUTOFS_FS is not set
414# CONFIG_AUTOFS4_FS is not set
415
416#
417# CD-ROM/DVD Filesystems
418#
419# CONFIG_ISO9660_FS is not set
420# CONFIG_UDF_FS is not set
421
422#
423# DOS/FAT/NT Filesystems
424#
425# CONFIG_MSDOS_FS is not set
426# CONFIG_VFAT_FS is not set
427# CONFIG_NTFS_FS is not set
428
429#
430# Pseudo filesystems
431#
432CONFIG_PROC_FS=y
433CONFIG_PROC_KCORE=y
434CONFIG_SYSFS=y
435CONFIG_DEVFS_FS=y
436CONFIG_DEVFS_MOUNT=y
437# CONFIG_DEVFS_DEBUG is not set
438# CONFIG_DEVPTS_FS_XATTR is not set
439CONFIG_TMPFS=y
440# CONFIG_TMPFS_XATTR is not set
441# CONFIG_HUGETLBFS is not set
442# CONFIG_HUGETLB_PAGE is not set
443CONFIG_RAMFS=y
444
445#
446# Miscellaneous filesystems
447#
448# CONFIG_ADFS_FS is not set
449# CONFIG_AFFS_FS is not set
450# CONFIG_HFS_FS is not set
451# CONFIG_HFSPLUS_FS is not set
452# CONFIG_BEFS_FS is not set
453# CONFIG_BFS_FS is not set
454# CONFIG_EFS_FS is not set
455CONFIG_CRAMFS=y
456# CONFIG_VXFS_FS is not set
457# CONFIG_HPFS_FS is not set
458# CONFIG_QNX4FS_FS is not set
459# CONFIG_SYSV_FS is not set
460# CONFIG_UFS_FS is not set
461
462#
463# Partition Types
464#
465# CONFIG_PARTITION_ADVANCED is not set
466CONFIG_MSDOS_PARTITION=y
467
468#
469# Native Language Support
470#
471# CONFIG_NLS is not set
472
473#
474# Profiling support
475#
476# CONFIG_PROFILING is not set
477
478#
479# Kernel hacking
480#
481# CONFIG_DEBUG_KERNEL is not set
482CONFIG_DEBUG_PREEMPT=y
483# CONFIG_FRAME_POINTER is not set
484# CONFIG_SH_STANDARD_BIOS is not set
485# CONFIG_EARLY_SCIF_CONSOLE is not set
486# CONFIG_KGDB is not set
487
488#
489# Security options
490#
491# CONFIG_KEYS is not set
492# CONFIG_SECURITY is not set
493
494#
495# Cryptographic options
496#
497# CONFIG_CRYPTO is not set
498
499#
500# Hardware crypto devices
501#
502
503#
504# Library routines
505#
506# CONFIG_CRC_CCITT is not set
507CONFIG_CRC32=y
508# CONFIG_LIBCRC32C is not set
509CONFIG_ZLIB_INFLATE=y
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
new file mode 100644
index 000000000000..bd6726cde398
--- /dev/null
+++ b/arch/sh/drivers/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Linux SuperH-specific device drivers.
3#
4
5obj-$(CONFIG_PCI) += pci/
6obj-$(CONFIG_SH_DMA) += dma/
7
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
new file mode 100644
index 000000000000..0f15216cd39d
--- /dev/null
+++ b/arch/sh/drivers/dma/Kconfig
@@ -0,0 +1,55 @@
1menu "DMA support"
2
3config SH_DMA
4 bool "DMA controller (DMAC) support"
5 help
6 Selecting this option will provide same API as PC's Direct Memory
7 Access Controller(8237A) for SuperH DMAC.
8
9 If unsure, say N.
10
11config NR_ONCHIP_DMA_CHANNELS
12 depends on SH_DMA
13 int "Number of on-chip DMAC channels"
14 default "4"
15 help
16 This allows you to specify the number of channels that the on-chip
17 DMAC supports. This will be 4 for SH7750/SH7751 and 8 for the
18 SH7750R/SH7751R.
19
20config NR_DMA_CHANNELS_BOOL
21 depends on SH_DMA
22 bool "Override default number of maximum DMA channels"
23 help
24 This allows you to forcibly update the maximum number of supported
25 DMA channels for a given board. If this is unset, this will default
26 to the number of channels that the on-chip DMAC has.
27
28config NR_DMA_CHANNELS
29 int "Maximum number of DMA channels"
30 depends on SH_DMA && NR_DMA_CHANNELS_BOOL
31 default NR_ONCHIP_DMA_CHANNELS
32 help
33 This allows you to specify the maximum number of DMA channels to
34 support. Setting this to a higher value allows for cascading DMACs
35 with additional channels.
36
37config DMA_PAGE_OPS
38 bool "Use DMAC for page copy/clear"
39 depends on SH_DMA && BROKEN
40 help
41 Selecting this option will use a dual-address mode configured channel
42 in the SH DMAC for copy_page()/clear_page(). Primarily a performance
43 hack.
44
45config DMA_PAGE_OPS_CHANNEL
46 depends on DMA_PAGE_OPS
47 int "DMA channel for sh memory-manager page copy/clear"
48 default "3"
49 help
50 This allows the specification of the dual address dma channel,
51 in case channel 3 is unavailable. On the SH4, channels 1,2, and 3
52 are dual-address capable.
53
54endmenu
55
diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile
new file mode 100644
index 000000000000..065d4c90970e
--- /dev/null
+++ b/arch/sh/drivers/dma/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the SuperH DMA specific kernel interface routines under Linux.
3#
4
5obj-y += dma-api.o dma-isa.o
6obj-$(CONFIG_SYSFS) += dma-sysfs.o
7obj-$(CONFIG_SH_DMA) += dma-sh.o
8obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o
9
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
new file mode 100644
index 000000000000..96e3036ec2bb
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -0,0 +1,292 @@
1/*
2 * arch/sh/drivers/dma/dma-api.c
3 *
4 * SuperH-specific DMA management API
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/spinlock.h>
16#include <linux/proc_fs.h>
17#include <linux/list.h>
18#include <asm/dma.h>
19
20DEFINE_SPINLOCK(dma_spin_lock);
21static LIST_HEAD(registered_dmac_list);
22
23/*
24 * A brief note about the reasons for this API as it stands.
25 *
26 * For starters, the old ISA DMA API didn't work for us for a number of
27 * reasons, for one, the vast majority of channels on the SH DMAC are
28 * dual-address mode only, and both the new and the old DMA APIs are after the
29 * concept of managing a DMA buffer, which doesn't overly fit this model very
30 * well. In addition to which, the new API is largely geared at IOMMUs and
31 * GARTs, and doesn't even support the channel notion very well.
32 *
33 * The other thing that's a marginal issue, is the sheer number of random DMA
34 * engines that are present (ie, in boards like the Dreamcast), some of which
35 * cascade off of the SH DMAC, and others do not. As such, there was a real
36 * need for a scalable subsystem that could deal with both single and
37 * dual-address mode usage, in addition to interoperating with cascaded DMACs.
38 *
39 * There really isn't any reason why this needs to be SH specific, though I'm
40 * not aware of too many other processors (with the exception of some MIPS)
41 * that have the same concept of a dual address mode, or any real desire to
42 * actually make use of the DMAC even if such a subsystem were exposed
43 * elsewhere.
44 *
45 * The idea for this was derived from the ARM port, which acted as an excellent
46 * reference when trying to address these issues.
47 *
48 * It should also be noted that the decision to add Yet Another DMA API(tm) to
49 * the kernel wasn't made easily, and was only decided upon after conferring
50 * with jejb with regards to the state of the old and new APIs as they applied
51 * to these circumstances. Philip Blundell was also a great help in figuring
52 * out some single-address mode DMA semantics that were otherwise rather
53 * confusing.
54 */
55
56struct dma_info *get_dma_info(unsigned int chan)
57{
58 struct list_head *pos, *tmp;
59 unsigned int total = 0;
60
61 /*
62 * Look for each DMAC's range to determine who the owner of
63 * the channel is.
64 */
65 list_for_each_safe(pos, tmp, &registered_dmac_list) {
66 struct dma_info *info = list_entry(pos, struct dma_info, list);
67
68 total += info->nr_channels;
69 if (chan > total)
70 continue;
71
72 return info;
73 }
74
75 return NULL;
76}
77
78struct dma_channel *get_dma_channel(unsigned int chan)
79{
80 struct dma_info *info = get_dma_info(chan);
81
82 if (!info)
83 return ERR_PTR(-EINVAL);
84
85 return info->channels + chan;
86}
87
88int get_dma_residue(unsigned int chan)
89{
90 struct dma_info *info = get_dma_info(chan);
91 struct dma_channel *channel = &info->channels[chan];
92
93 if (info->ops->get_residue)
94 return info->ops->get_residue(channel);
95
96 return 0;
97}
98
99int request_dma(unsigned int chan, const char *dev_id)
100{
101 struct dma_info *info = get_dma_info(chan);
102 struct dma_channel *channel = &info->channels[chan];
103
104 down(&channel->sem);
105
106 if (!info->ops || chan >= MAX_DMA_CHANNELS) {
107 up(&channel->sem);
108 return -EINVAL;
109 }
110
111 atomic_set(&channel->busy, 1);
112
113 strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
114
115 up(&channel->sem);
116
117 if (info->ops->request)
118 return info->ops->request(channel);
119
120 return 0;
121}
122
123void free_dma(unsigned int chan)
124{
125 struct dma_info *info = get_dma_info(chan);
126 struct dma_channel *channel = &info->channels[chan];
127
128 if (info->ops->free)
129 info->ops->free(channel);
130
131 atomic_set(&channel->busy, 0);
132}
133
134void dma_wait_for_completion(unsigned int chan)
135{
136 struct dma_info *info = get_dma_info(chan);
137 struct dma_channel *channel = &info->channels[chan];
138
139 if (channel->flags & DMA_TEI_CAPABLE) {
140 wait_event(channel->wait_queue,
141 (info->ops->get_residue(channel) == 0));
142 return;
143 }
144
145 while (info->ops->get_residue(channel))
146 cpu_relax();
147}
148
149void dma_configure_channel(unsigned int chan, unsigned long flags)
150{
151 struct dma_info *info = get_dma_info(chan);
152 struct dma_channel *channel = &info->channels[chan];
153
154 if (info->ops->configure)
155 info->ops->configure(channel, flags);
156}
157
158int dma_xfer(unsigned int chan, unsigned long from,
159 unsigned long to, size_t size, unsigned int mode)
160{
161 struct dma_info *info = get_dma_info(chan);
162 struct dma_channel *channel = &info->channels[chan];
163
164 channel->sar = from;
165 channel->dar = to;
166 channel->count = size;
167 channel->mode = mode;
168
169 return info->ops->xfer(channel);
170}
171
172#ifdef CONFIG_PROC_FS
173static int dma_read_proc(char *buf, char **start, off_t off,
174 int len, int *eof, void *data)
175{
176 struct list_head *pos, *tmp;
177 char *p = buf;
178
179 if (list_empty(&registered_dmac_list))
180 return 0;
181
182 /*
183 * Iterate over each registered DMAC
184 */
185 list_for_each_safe(pos, tmp, &registered_dmac_list) {
186 struct dma_info *info = list_entry(pos, struct dma_info, list);
187 int i;
188
189 /*
190 * Iterate over each channel
191 */
192 for (i = 0; i < info->nr_channels; i++) {
193 struct dma_channel *channel = info->channels + i;
194
195 if (!(channel->flags & DMA_CONFIGURED))
196 continue;
197
198 p += sprintf(p, "%2d: %14s %s\n", i,
199 info->name, channel->dev_id);
200 }
201 }
202
203 return p - buf;
204}
205#endif
206
207
208int __init register_dmac(struct dma_info *info)
209{
210 int i;
211
212 INIT_LIST_HEAD(&info->list);
213
214 printk(KERN_INFO "DMA: Registering %s handler (%d channel%s).\n",
215 info->name, info->nr_channels,
216 info->nr_channels > 1 ? "s" : "");
217
218 BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels);
219
220 /*
221 * Don't touch pre-configured channels
222 */
223 if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) {
224 unsigned int size;
225
226 size = sizeof(struct dma_channel) * info->nr_channels;
227
228 info->channels = kmalloc(size, GFP_KERNEL);
229 if (!info->channels)
230 return -ENOMEM;
231
232 memset(info->channels, 0, size);
233 }
234
235 for (i = 0; i < info->nr_channels; i++) {
236 struct dma_channel *chan = info->channels + i;
237
238 chan->chan = i;
239
240 memcpy(chan->dev_id, "Unused", 7);
241
242 if (info->flags & DMAC_CHANNELS_TEI_CAPABLE)
243 chan->flags |= DMA_TEI_CAPABLE;
244
245 init_MUTEX(&chan->sem);
246 init_waitqueue_head(&chan->wait_queue);
247
248#ifdef CONFIG_SYSFS
249 dma_create_sysfs_files(chan);
250#endif
251 }
252
253 list_add(&info->list, &registered_dmac_list);
254
255 return 0;
256}
257
258void __exit unregister_dmac(struct dma_info *info)
259{
260 if (!(info->flags & DMAC_CHANNELS_CONFIGURED))
261 kfree(info->channels);
262
263 list_del(&info->list);
264}
265
266static int __init dma_api_init(void)
267{
268 printk("DMA: Registering DMA API.\n");
269
270#ifdef CONFIG_PROC_FS
271 create_proc_read_entry("dma", 0, 0, dma_read_proc, 0);
272#endif
273
274 return 0;
275}
276
277subsys_initcall(dma_api_init);
278
279MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
280MODULE_DESCRIPTION("DMA API for SuperH");
281MODULE_LICENSE("GPL");
282
283EXPORT_SYMBOL(request_dma);
284EXPORT_SYMBOL(free_dma);
285EXPORT_SYMBOL(register_dmac);
286EXPORT_SYMBOL(get_dma_residue);
287EXPORT_SYMBOL(get_dma_info);
288EXPORT_SYMBOL(get_dma_channel);
289EXPORT_SYMBOL(dma_xfer);
290EXPORT_SYMBOL(dma_wait_for_completion);
291EXPORT_SYMBOL(dma_configure_channel);
292
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c
new file mode 100644
index 000000000000..231e3f6fb28f
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-g2.c
@@ -0,0 +1,171 @@
1/*
2 * arch/sh/drivers/dma/dma-g2.c
3 *
4 * G2 bus DMA support
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16
17#include <asm/mach/sysasic.h>
18#include <asm/mach/dma.h>
19#include <asm/dma.h>
20
21struct g2_channel {
22 unsigned long g2_addr; /* G2 bus address */
23 unsigned long root_addr; /* Root bus (SH-4) address */
24 unsigned long size; /* Size (in bytes), 32-byte aligned */
25 unsigned long direction; /* Transfer direction */
26 unsigned long ctrl; /* Transfer control */
27 unsigned long chan_enable; /* Channel enable */
28 unsigned long xfer_enable; /* Transfer enable */
29 unsigned long xfer_stat; /* Transfer status */
30} __attribute__ ((aligned(32)));
31
32struct g2_status {
33 unsigned long g2_addr;
34 unsigned long root_addr;
35 unsigned long size;
36 unsigned long status;
37} __attribute__ ((aligned(16)));
38
39struct g2_dma_info {
40 struct g2_channel channel[G2_NR_DMA_CHANNELS];
41 unsigned long pad1[G2_NR_DMA_CHANNELS];
42 unsigned long wait_state;
43 unsigned long pad2[10];
44 unsigned long magic;
45 struct g2_status status[G2_NR_DMA_CHANNELS];
46} __attribute__ ((aligned(256)));
47
48static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800;
49
50static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
51{
52 /* FIXME: Do some meaningful completion work here.. */
53 return IRQ_HANDLED;
54}
55
56static struct irqaction g2_dma_irq = {
57 .name = "g2 DMA handler",
58 .handler = g2_dma_interrupt,
59 .flags = SA_INTERRUPT,
60};
61
62static int g2_enable_dma(struct dma_channel *chan)
63{
64 unsigned int chan_nr = chan->chan;
65
66 g2_dma->channel[chan_nr].chan_enable = 1;
67 g2_dma->channel[chan_nr].xfer_enable = 1;
68
69 return 0;
70}
71
72static int g2_disable_dma(struct dma_channel *chan)
73{
74 unsigned int chan_nr = chan->chan;
75
76 g2_dma->channel[chan_nr].chan_enable = 0;
77 g2_dma->channel[chan_nr].xfer_enable = 0;
78
79 return 0;
80}
81
82static int g2_xfer_dma(struct dma_channel *chan)
83{
84 unsigned int chan_nr = chan->chan;
85
86 if (chan->sar & 31) {
87 printk("g2dma: unaligned source 0x%lx\n", chan->sar);
88 return -EINVAL;
89 }
90
91 if (chan->dar & 31) {
92 printk("g2dma: unaligned dest 0x%lx\n", chan->dar);
93 return -EINVAL;
94 }
95
96 /* Align the count */
97 if (chan->count & 31)
98 chan->count = (chan->count + (32 - 1)) & ~(32 - 1);
99
100 /* Fixup destination */
101 chan->dar += 0xa0800000;
102
103 /* Fixup direction */
104 chan->mode = !chan->mode;
105
106 flush_icache_range((unsigned long)chan->sar, chan->count);
107
108 g2_disable_dma(chan);
109
110 g2_dma->channel[chan_nr].g2_addr = chan->dar & 0x1fffffe0;
111 g2_dma->channel[chan_nr].root_addr = chan->sar & 0x1fffffe0;
112 g2_dma->channel[chan_nr].size = (chan->count & ~31) | 0x80000000;
113 g2_dma->channel[chan_nr].direction = chan->mode;
114
115 /*
116 * bit 0 - ???
117 * bit 1 - if set, generate a hardware event on transfer completion
118 * bit 2 - ??? something to do with suspend?
119 */
120 g2_dma->channel[chan_nr].ctrl = 5; /* ?? */
121
122 g2_enable_dma(chan);
123
124 /* debug cruft */
125 pr_debug("count, sar, dar, mode, ctrl, chan, xfer: %ld, 0x%08lx, "
126 "0x%08lx, %ld, %ld, %ld, %ld\n",
127 g2_dma->channel[chan_nr].size,
128 g2_dma->channel[chan_nr].root_addr,
129 g2_dma->channel[chan_nr].g2_addr,
130 g2_dma->channel[chan_nr].direction,
131 g2_dma->channel[chan_nr].ctrl,
132 g2_dma->channel[chan_nr].chan_enable,
133 g2_dma->channel[chan_nr].xfer_enable);
134
135 return 0;
136}
137
138static struct dma_ops g2_dma_ops = {
139 .xfer = g2_xfer_dma,
140};
141
142static struct dma_info g2_dma_info = {
143 .name = "G2 DMA",
144 .nr_channels = 4,
145 .ops = &g2_dma_ops,
146 .flags = DMAC_CHANNELS_TEI_CAPABLE,
147};
148
149static int __init g2_dma_init(void)
150{
151 setup_irq(HW_EVENT_G2_DMA, &g2_dma_irq);
152
153 /* Magic */
154 g2_dma->wait_state = 27;
155 g2_dma->magic = 0x4659404f;
156
157 return register_dmac(&g2_dma_info);
158}
159
160static void __exit g2_dma_exit(void)
161{
162 free_irq(HW_EVENT_G2_DMA, 0);
163}
164
165subsys_initcall(g2_dma_init);
166module_exit(g2_dma_exit);
167
168MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
169MODULE_DESCRIPTION("G2 bus DMA driver");
170MODULE_LICENSE("GPL");
171
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c
new file mode 100644
index 000000000000..1c9bc45b8bcb
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-isa.c
@@ -0,0 +1,106 @@
1/*
2 * arch/sh/drivers/dma/dma-isa.c
3 *
4 * Generic ISA DMA wrapper for SH DMA API
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <asm/dma.h>
15
16/*
17 * This implements a small wrapper set to make code using the old ISA DMA API
18 * work with the SH DMA API. Since most of the work in the new API happens
19 * at ops->xfer() time, we simply use the various set_dma_xxx() routines to
20 * fill in per-channel info, and then hand hand this off to ops->xfer() at
21 * enable_dma() time.
22 *
23 * For channels that are doing on-demand data transfer via cascading, the
24 * channel itself will still need to be configured through the new API. As
25 * such, this code is meant for only the simplest of tasks (and shouldn't be
26 * used in any new drivers at all).
27 *
28 * It should also be noted that various functions here are labelled as
29 * being deprecated. This is due to the fact that the ops->xfer() method is
30 * the preferred way of doing things (as well as just grabbing the spinlock
31 * directly). As such, any users of this interface will be warned rather
32 * loudly.
33 */
34
35unsigned long __deprecated claim_dma_lock(void)
36{
37 unsigned long flags;
38
39 spin_lock_irqsave(&dma_spin_lock, flags);
40
41 return flags;
42}
43EXPORT_SYMBOL(claim_dma_lock);
44
45void __deprecated release_dma_lock(unsigned long flags)
46{
47 spin_unlock_irqrestore(&dma_spin_lock, flags);
48}
49EXPORT_SYMBOL(release_dma_lock);
50
51void __deprecated disable_dma(unsigned int chan)
52{
53 /* Nothing */
54}
55EXPORT_SYMBOL(disable_dma);
56
57void __deprecated enable_dma(unsigned int chan)
58{
59 struct dma_info *info = get_dma_info(chan);
60 struct dma_channel *channel = &info->channels[chan];
61
62 info->ops->xfer(channel);
63}
64EXPORT_SYMBOL(enable_dma);
65
66void clear_dma_ff(unsigned int chan)
67{
68 /* Nothing */
69}
70EXPORT_SYMBOL(clear_dma_ff);
71
72void set_dma_mode(unsigned int chan, char mode)
73{
74 struct dma_info *info = get_dma_info(chan);
75 struct dma_channel *channel = &info->channels[chan];
76
77 channel->mode = mode;
78}
79EXPORT_SYMBOL(set_dma_mode);
80
81void set_dma_addr(unsigned int chan, unsigned int addr)
82{
83 struct dma_info *info = get_dma_info(chan);
84 struct dma_channel *channel = &info->channels[chan];
85
86 /*
87 * Single address mode is the only thing supported through
88 * this interface.
89 */
90 if ((channel->mode & DMA_MODE_MASK) == DMA_MODE_READ) {
91 channel->sar = addr;
92 } else {
93 channel->dar = addr;
94 }
95}
96EXPORT_SYMBOL(set_dma_addr);
97
98void set_dma_count(unsigned int chan, unsigned int count)
99{
100 struct dma_info *info = get_dma_info(chan);
101 struct dma_channel *channel = &info->channels[chan];
102
103 channel->count = count;
104}
105EXPORT_SYMBOL(set_dma_count);
106
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c
new file mode 100644
index 000000000000..2e1d58f2d1b9
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-pvr2.c
@@ -0,0 +1,109 @@
1/*
2 * arch/sh/boards/dreamcast/dma-pvr2.c
3 *
4 * NEC PowerVR 2 (Dreamcast) DMA support
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <asm/mach/sysasic.h>
17#include <asm/mach/dma.h>
18#include <asm/dma.h>
19#include <asm/io.h>
20
21static unsigned int xfer_complete = 0;
22static int count = 0;
23
24static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
25{
26 if (get_dma_residue(PVR2_CASCADE_CHAN)) {
27 printk(KERN_WARNING "DMA: SH DMAC did not complete transfer "
28 "on channel %d, waiting..\n", PVR2_CASCADE_CHAN);
29 dma_wait_for_completion(PVR2_CASCADE_CHAN);
30 }
31
32 if (count++ < 10)
33 pr_debug("Got a pvr2 dma interrupt for channel %d\n",
34 irq - HW_EVENT_PVR2_DMA);
35
36 xfer_complete = 1;
37
38 return IRQ_HANDLED;
39}
40
41static int pvr2_request_dma(struct dma_channel *chan)
42{
43 if (ctrl_inl(PVR2_DMA_MODE) != 0)
44 return -EBUSY;
45
46 ctrl_outl(0, PVR2_DMA_LMMODE0);
47
48 return 0;
49}
50
51static int pvr2_get_dma_residue(struct dma_channel *chan)
52{
53 return xfer_complete == 0;
54}
55
56static int pvr2_xfer_dma(struct dma_channel *chan)
57{
58 if (chan->sar || !chan->dar)
59 return -EINVAL;
60
61 xfer_complete = 0;
62
63 ctrl_outl(chan->dar, PVR2_DMA_ADDR);
64 ctrl_outl(chan->count, PVR2_DMA_COUNT);
65 ctrl_outl(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
66
67 return 0;
68}
69
70static struct irqaction pvr2_dma_irq = {
71 .name = "pvr2 DMA handler",
72 .handler = pvr2_dma_interrupt,
73 .flags = SA_INTERRUPT,
74};
75
76static struct dma_ops pvr2_dma_ops = {
77 .request = pvr2_request_dma,
78 .get_residue = pvr2_get_dma_residue,
79 .xfer = pvr2_xfer_dma,
80};
81
82static struct dma_info pvr2_dma_info = {
83 .name = "PowerVR 2 DMA",
84 .nr_channels = 1,
85 .ops = &pvr2_dma_ops,
86 .flags = DMAC_CHANNELS_TEI_CAPABLE,
87};
88
89static int __init pvr2_dma_init(void)
90{
91 setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq);
92 request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
93
94 return register_dmac(&pvr2_dma_info);
95}
96
97static void __exit pvr2_dma_exit(void)
98{
99 free_dma(PVR2_CASCADE_CHAN);
100 free_irq(HW_EVENT_PVR2_DMA, 0);
101}
102
103subsys_initcall(pvr2_dma_init);
104module_exit(pvr2_dma_exit);
105
106MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
107MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver");
108MODULE_LICENSE("GPL");
109
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
new file mode 100644
index 000000000000..31dacd4444b2
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -0,0 +1,267 @@
1/*
2 * arch/sh/drivers/dma/dma-sh.c
3 *
4 * SuperH On-chip DMAC Support
5 *
6 * Copyright (C) 2000 Takashi YOSHII
7 * Copyright (C) 2003, 2004 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/irq.h>
17#include <linux/interrupt.h>
18#include <linux/module.h>
19#include <asm/signal.h>
20#include <asm/irq.h>
21#include <asm/dma.h>
22#include <asm/io.h>
23#include "dma-sh.h"
24
25/*
26 * The SuperH DMAC supports a number of transmit sizes, we list them here,
27 * with their respective values as they appear in the CHCR registers.
28 *
29 * Defaults to a 64-bit transfer size.
30 */
31enum {
32 XMIT_SZ_64BIT,
33 XMIT_SZ_8BIT,
34 XMIT_SZ_16BIT,
35 XMIT_SZ_32BIT,
36 XMIT_SZ_256BIT,
37};
38
39/*
40 * The DMA count is defined as the number of bytes to transfer.
41 */
42static unsigned int ts_shift[] = {
43 [XMIT_SZ_64BIT] = 3,
44 [XMIT_SZ_8BIT] = 0,
45 [XMIT_SZ_16BIT] = 1,
46 [XMIT_SZ_32BIT] = 2,
47 [XMIT_SZ_256BIT] = 5,
48};
49
50static inline unsigned int get_dmte_irq(unsigned int chan)
51{
52 unsigned int irq;
53
54 /*
55 * Normally we could just do DMTE0_IRQ + chan outright, though in the
56 * case of the 7751R, the DMTE IRQs for channels > 4 start right above
57 * the SCIF
58 */
59
60 if (chan < 4) {
61 irq = DMTE0_IRQ + chan;
62 } else {
63 irq = DMTE4_IRQ + chan - 4;
64 }
65
66 return irq;
67}
68
69/*
70 * We determine the correct shift size based off of the CHCR transmit size
71 * for the given channel. Since we know that it will take:
72 *
73 * info->count >> ts_shift[transmit_size]
74 *
75 * iterations to complete the transfer.
76 */
77static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
78{
79 u32 chcr = ctrl_inl(CHCR[chan->chan]);
80
81 chcr >>= 4;
82
83 return ts_shift[chcr & 0x0007];
84}
85
86/*
87 * The transfer end interrupt must read the chcr register to end the
88 * hardware interrupt active condition.
89 * Besides that it needs to waken any waiting process, which should handle
90 * setting up the next transfer.
91 */
92static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs)
93{
94 struct dma_channel *chan = (struct dma_channel *)dev_id;
95 u32 chcr;
96
97 chcr = ctrl_inl(CHCR[chan->chan]);
98
99 if (!(chcr & CHCR_TE))
100 return IRQ_NONE;
101
102 chcr &= ~(CHCR_IE | CHCR_DE);
103 ctrl_outl(chcr, CHCR[chan->chan]);
104
105 wake_up(&chan->wait_queue);
106
107 return IRQ_HANDLED;
108}
109
110static int sh_dmac_request_dma(struct dma_channel *chan)
111{
112 return request_irq(get_dmte_irq(chan->chan), dma_tei,
113 SA_INTERRUPT, "DMAC Transfer End", chan);
114}
115
116static void sh_dmac_free_dma(struct dma_channel *chan)
117{
118 free_irq(get_dmte_irq(chan->chan), chan);
119}
120
121static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
122{
123 if (!chcr)
124 chcr = RS_DUAL;
125
126 ctrl_outl(chcr, CHCR[chan->chan]);
127
128 chan->flags |= DMA_CONFIGURED;
129}
130
131static void sh_dmac_enable_dma(struct dma_channel *chan)
132{
133 int irq = get_dmte_irq(chan->chan);
134 u32 chcr;
135
136 chcr = ctrl_inl(CHCR[chan->chan]);
137 chcr |= CHCR_DE | CHCR_IE;
138 ctrl_outl(chcr, CHCR[chan->chan]);
139
140 enable_irq(irq);
141}
142
143static void sh_dmac_disable_dma(struct dma_channel *chan)
144{
145 int irq = get_dmte_irq(chan->chan);
146 u32 chcr;
147
148 disable_irq(irq);
149
150 chcr = ctrl_inl(CHCR[chan->chan]);
151 chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
152 ctrl_outl(chcr, CHCR[chan->chan]);
153}
154
155static int sh_dmac_xfer_dma(struct dma_channel *chan)
156{
157 /*
158 * If we haven't pre-configured the channel with special flags, use
159 * the defaults.
160 */
161 if (!(chan->flags & DMA_CONFIGURED))
162 sh_dmac_configure_channel(chan, 0);
163
164 sh_dmac_disable_dma(chan);
165
166 /*
167 * Single-address mode usage note!
168 *
169 * It's important that we don't accidentally write any value to SAR/DAR
170 * (this includes 0) that hasn't been directly specified by the user if
171 * we're in single-address mode.
172 *
173 * In this case, only one address can be defined, anything else will
174 * result in a DMA address error interrupt (at least on the SH-4),
175 * which will subsequently halt the transfer.
176 *
177 * Channel 2 on the Dreamcast is a special case, as this is used for
178 * cascading to the PVR2 DMAC. In this case, we still need to write
179 * SAR and DAR, regardless of value, in order for cascading to work.
180 */
181 if (chan->sar || (mach_is_dreamcast() && chan->chan == 2))
182 ctrl_outl(chan->sar, SAR[chan->chan]);
183 if (chan->dar || (mach_is_dreamcast() && chan->chan == 2))
184 ctrl_outl(chan->dar, DAR[chan->chan]);
185
186 ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]);
187
188 sh_dmac_enable_dma(chan);
189
190 return 0;
191}
192
193static int sh_dmac_get_dma_residue(struct dma_channel *chan)
194{
195 if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE))
196 return 0;
197
198 return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan);
199}
200
201#if defined(CONFIG_CPU_SH4)
202static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs)
203{
204 unsigned long dmaor = ctrl_inl(DMAOR);
205
206 printk("DMAE: DMAOR=%lx\n", dmaor);
207
208 ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR);
209 ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR);
210 ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR);
211
212 disable_irq(irq);
213
214 return IRQ_HANDLED;
215}
216#endif
217
218static struct dma_ops sh_dmac_ops = {
219 .request = sh_dmac_request_dma,
220 .free = sh_dmac_free_dma,
221 .get_residue = sh_dmac_get_dma_residue,
222 .xfer = sh_dmac_xfer_dma,
223 .configure = sh_dmac_configure_channel,
224};
225
226static struct dma_info sh_dmac_info = {
227 .name = "SuperH DMAC",
228 .nr_channels = 4,
229 .ops = &sh_dmac_ops,
230 .flags = DMAC_CHANNELS_TEI_CAPABLE,
231};
232
233static int __init sh_dmac_init(void)
234{
235 struct dma_info *info = &sh_dmac_info;
236 int i;
237
238#ifdef CONFIG_CPU_SH4
239 make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
240 i = request_irq(DMAE_IRQ, dma_err, SA_INTERRUPT, "DMAC Address Error", 0);
241 if (i < 0)
242 return i;
243#endif
244
245 for (i = 0; i < info->nr_channels; i++) {
246 int irq = get_dmte_irq(i);
247
248 make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
249 }
250
251 ctrl_outl(0x8000 | DMAOR_DME, DMAOR);
252
253 return register_dmac(info);
254}
255
256static void __exit sh_dmac_exit(void)
257{
258#ifdef CONFIG_CPU_SH4
259 free_irq(DMAE_IRQ, 0);
260#endif
261}
262
263subsys_initcall(sh_dmac_init);
264module_exit(sh_dmac_exit);
265
266MODULE_LICENSE("GPL");
267
diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h
new file mode 100644
index 000000000000..dd9d547539a2
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-sh.h
@@ -0,0 +1,52 @@
1/*
2 * arch/sh/drivers/dma/dma-sh.h
3 *
4 * Copyright (C) 2000 Takashi YOSHII
5 * Copyright (C) 2003 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#ifndef __DMA_SH_H
12#define __DMA_SH_H
13
14/* Definitions for the SuperH DMAC */
15#define REQ_L 0x00000000
16#define REQ_E 0x00080000
17#define RACK_H 0x00000000
18#define RACK_L 0x00040000
19#define ACK_R 0x00000000
20#define ACK_W 0x00020000
21#define ACK_H 0x00000000
22#define ACK_L 0x00010000
23#define DM_INC 0x00004000
24#define DM_DEC 0x00008000
25#define SM_INC 0x00001000
26#define SM_DEC 0x00002000
27#define RS_IN 0x00000200
28#define RS_OUT 0x00000300
29#define TM_BURST 0x0000080
30#define TS_8 0x00000010
31#define TS_16 0x00000020
32#define TS_32 0x00000030
33#define TS_64 0x00000000
34#define TS_BLK 0x00000040
35#define CHCR_DE 0x00000001
36#define CHCR_TE 0x00000002
37#define CHCR_IE 0x00000004
38
39/* Define the default configuration for dual address memory-memory transfer.
40 * The 0x400 value represents auto-request, external->external.
41 */
42#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32)
43
44#define DMAOR_COD 0x00000008
45#define DMAOR_AE 0x00000004
46#define DMAOR_NMIF 0x00000002
47#define DMAOR_DME 0x00000001
48
49#define MAX_DMAC_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS)
50
51#endif /* __DMA_SH_H */
52
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
new file mode 100644
index 000000000000..71a6d4e7809f
--- /dev/null
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -0,0 +1,133 @@
1/*
2 * arch/sh/drivers/dma/dma-sysfs.c
3 *
4 * sysfs interface for SH DMA API
5 *
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/sysdev.h>
15#include <linux/module.h>
16#include <asm/dma.h>
17
18static struct sysdev_class dma_sysclass = {
19 set_kset_name("dma"),
20};
21
22EXPORT_SYMBOL(dma_sysclass);
23
24static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
25{
26 ssize_t len = 0;
27 int i;
28
29 for (i = 0; i < MAX_DMA_CHANNELS; i++) {
30 struct dma_info *info = get_dma_info(i);
31 struct dma_channel *channel = &info->channels[i];
32
33 len += sprintf(buf + len, "%2d: %14s %s\n",
34 channel->chan, info->name,
35 channel->dev_id);
36 }
37
38 return len;
39}
40
41static SYSDEV_ATTR(devices, S_IRUGO, dma_show_devices, NULL);
42
43static int __init dma_sysclass_init(void)
44{
45 int ret;
46
47 ret = sysdev_class_register(&dma_sysclass);
48 if (ret == 0)
49 sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr);
50
51 return ret;
52}
53
54postcore_initcall(dma_sysclass_init);
55
56static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
57{
58 struct dma_channel *channel = to_dma_channel(dev);
59 return sprintf(buf, "%s\n", channel->dev_id);
60}
61
62static ssize_t dma_store_dev_id(struct sys_device *dev,
63 const char *buf, size_t count)
64{
65 struct dma_channel *channel = to_dma_channel(dev);
66 strcpy(channel->dev_id, buf);
67 return count;
68}
69
70static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id);
71
72static ssize_t dma_store_config(struct sys_device *dev,
73 const char *buf, size_t count)
74{
75 struct dma_channel *channel = to_dma_channel(dev);
76 unsigned long config;
77
78 config = simple_strtoul(buf, NULL, 0);
79 dma_configure_channel(channel->chan, config);
80
81 return count;
82}
83
84static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config);
85
86static ssize_t dma_show_mode(struct sys_device *dev, char *buf)
87{
88 struct dma_channel *channel = to_dma_channel(dev);
89 return sprintf(buf, "0x%08x\n", channel->mode);
90}
91
92static ssize_t dma_store_mode(struct sys_device *dev,
93 const char *buf, size_t count)
94{
95 struct dma_channel *channel = to_dma_channel(dev);
96 channel->mode = simple_strtoul(buf, NULL, 0);
97 return count;
98}
99
100static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode);
101
102#define dma_ro_attr(field, fmt) \
103static ssize_t dma_show_##field(struct sys_device *dev, char *buf) \
104{ \
105 struct dma_channel *channel = to_dma_channel(dev); \
106 return sprintf(buf, fmt, channel->field); \
107} \
108static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL);
109
110dma_ro_attr(count, "0x%08x\n");
111dma_ro_attr(flags, "0x%08lx\n");
112
113int __init dma_create_sysfs_files(struct dma_channel *chan)
114{
115 struct sys_device *dev = &chan->dev;
116 int ret;
117
118 dev->id = chan->chan;
119 dev->cls = &dma_sysclass;
120
121 ret = sysdev_register(dev);
122 if (ret)
123 return ret;
124
125 sysdev_create_file(dev, &attr_dev_id);
126 sysdev_create_file(dev, &attr_count);
127 sysdev_create_file(dev, &attr_mode);
128 sysdev_create_file(dev, &attr_flags);
129 sysdev_create_file(dev, &attr_config);
130
131 return 0;
132}
133
diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig
new file mode 100644
index 000000000000..6d1cbbe6745c
--- /dev/null
+++ b/arch/sh/drivers/pci/Kconfig
@@ -0,0 +1,41 @@
1config PCI
2 bool "PCI support"
3 help
4 Find out whether you have a PCI motherboard. PCI is the name of a
5 bus system, i.e. the way the CPU talks to the other stuff inside
6 your box. If you have PCI, say Y, otherwise N.
7
8 The PCI-HOWTO, available from
9 <http://www.tldp.org/docs.html#howto>, contains valuable
10 information about which PCI hardware does work under Linux and which
11 doesn't.
12
13config SH_PCIDMA_NONCOHERENT
14 bool "Cache and PCI noncoherent"
15 depends on PCI
16 default y
17 help
18 Enable this option if your platform does not have a CPU cache which
19 remains coherent with PCI DMA. It is safest to say 'Y', although you
20 will see better performance if you can say 'N', because the PCI DMA
21 code will not have to flush the CPU's caches. If you have a PCI host
22 bridge integrated with your SH CPU, refer carefully to the chip specs
23 to see if you can say 'N' here. Otherwise, leave it as 'Y'.
24
25# This is also board-specific
26config PCI_AUTO
27 bool
28 depends on PCI
29 default y
30
31config PCI_AUTO_UPDATE_RESOURCES
32 bool
33 depends on PCI_AUTO
34 default y if !SH_DREAMCAST
35 help
36 Selecting this option will cause the PCI auto code to leave your
37 BAR values alone. Otherwise they will be updated automatically. If
38 for some reason, you have a board that simply refuses to work
39 with its resources updated beyond what they are when the device
40 is powered up, set this to N. Everyone else will want this as Y.
41
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
new file mode 100644
index 000000000000..365bc16a4a83
--- /dev/null
+++ b/arch/sh/drivers/pci/Makefile
@@ -0,0 +1,16 @@
1#
2# Makefile for the PCI specific kernel interface routines under Linux.
3#
4
5obj-y += pci.o
6obj-$(CONFIG_PCI_AUTO) += pci-auto.o
7
8obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o
10
11obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
12 dma-dreamcast.o
13obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
14obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o
15obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
16obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
new file mode 100644
index 000000000000..83de7ef4e7df
--- /dev/null
+++ b/arch/sh/drivers/pci/dma-dreamcast.c
@@ -0,0 +1,71 @@
1/*
2 * arch/sh/pci/dma-dreamcast.c
3 *
4 * PCI DMA support for the Sega Dreamcast
5 *
6 * Copyright (C) 2001, 2002 M. R. Brown
7 * Copyright (C) 2002, 2003 Paul Mundt
8 *
9 * This file originally bore the message (with enclosed-$):
10 * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
11 * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */
17
18#include <linux/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26#include <linux/dma-mapping.h>
27#include <linux/device.h>
28
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/mach/pci.h>
32
33static int gapspci_dma_used = 0;
34
35void *dreamcast_consistent_alloc(struct device *dev, size_t size,
36 dma_addr_t *dma_handle, int flag)
37{
38 unsigned long buf;
39
40 if (dev && dev->bus != &pci_bus_type)
41 return NULL;
42
43 if (gapspci_dma_used + size > GAPSPCI_DMA_SIZE)
44 return ERR_PTR(-EINVAL);
45
46 buf = GAPSPCI_DMA_BASE + gapspci_dma_used;
47
48 gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
49
50 *dma_handle = (dma_addr_t)buf;
51
52 buf = P2SEGADDR(buf);
53
54 /* Flush the dcache before we hand off the buffer */
55 dma_cache_wback_inv((void *)buf, size);
56
57 return (void *)buf;
58}
59
60int dreamcast_consistent_free(struct device *dev, size_t size,
61 void *vaddr, dma_addr_t dma_handle)
62{
63 if (dev && dev->bus != &pci_bus_type)
64 return -EINVAL;
65
66 /* XXX */
67 gapspci_dma_used = 0;
68
69 return 0;
70}
71
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
new file mode 100644
index 000000000000..cf30e2fa51be
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -0,0 +1,81 @@
1/*
2 * arch/sh/pci/fixups-dreamcast.c
3 *
4 * PCI fixups for the Sega Dreamcast
5 *
6 * Copyright (C) 2001, 2002 M. R. Brown
7 * Copyright (C) 2002, 2003 Paul Mundt
8 *
9 * This file originally bore the message (with enclosed-$):
10 * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
11 * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */
17
18#include <linux/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mach/pci.h>
30
31static void __init gapspci_fixup_resources(struct pci_dev *dev)
32{
33 struct pci_channel *p = board_pci_channels;
34
35 printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
36
37 switch (dev->device) {
38 case PCI_DEVICE_ID_SEGA_BBA:
39 /*
40 * We also assume that dev->devfn == 0
41 */
42 dev->resource[1].start = p->io_resource->start + 0x100;
43 dev->resource[1].end = dev->resource[1].start + 0x200 - 1;
44 break;
45 default:
46 printk("PCI: Failed resource fixup\n");
47 }
48}
49
50DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
51
52void __init pcibios_fixup_bus(struct pci_bus *bus)
53{
54 /*
55 * We don't have any sub bus to fix up, and this is a rather
56 * stupid place to put general device fixups. Don't do it.
57 * Use the pcibios_fixups table or suffer the consequences.
58 */
59}
60
61void __init pcibios_fixup_irqs(void)
62{
63 struct pci_dev *dev = 0;
64
65 for_each_pci_dev(dev) {
66 /*
67 * The interrupt routing semantics here are quite trivial.
68 *
69 * We basically only support one interrupt, so we only bother
70 * updating a device's interrupt line with this single shared
71 * interrupt. Keeps routing quite simple, doesn't it?
72 */
73 printk(KERN_NOTICE "PCI: Fixing up IRQ routing for device %s\n",
74 pci_name(dev));
75
76 dev->irq = GAPSPCI_IRQ;
77
78 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
79 }
80}
81
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
new file mode 100644
index 000000000000..0c590fc7a081
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -0,0 +1,43 @@
1/*
2 * arch/sh/drivers/pci/fixups-rts7751r2d.c
3 *
4 * RTS7751R2D PCI fixups
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 * Copyright (C) 2004 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include "pci-sh7751.h"
14#include <asm/io.h>
15
16#define PCIMCR_MRSET_OFF 0xBFFFFFFF
17#define PCIMCR_RFSH_OFF 0xFFFFFFFB
18
19int pci_fixup_pcic(void)
20{
21 unsigned long bcr1, mcr;
22
23 bcr1 = inl(SH7751_BCR1);
24 bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
25 outl(bcr1, PCI_REG(SH7751_PCIBCR1));
26
27 /* Enable all interrupts, so we known what to fix */
28 outl(0x0000c3ff, PCI_REG(SH7751_PCIINTM));
29 outl(0x0000380f, PCI_REG(SH7751_PCIAINTM));
30
31 outl(0xfb900047, PCI_REG(SH7751_PCICONF1));
32 outl(0xab000001, PCI_REG(SH7751_PCICONF4));
33
34 mcr = inl(SH7751_MCR);
35 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
36 outl(mcr, PCI_REG(SH7751_PCIMCR));
37
38 outl(0x0c000000, PCI_REG(SH7751_PCICONF5));
39 outl(0xd0000000, PCI_REG(SH7751_PCICONF6));
40 outl(0x0c000000, PCI_REG(SH7751_PCILAR0));
41 outl(0x00000000, PCI_REG(SH7751_PCILAR1));
42 return 0;
43}
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c
new file mode 100644
index 000000000000..57ac26c2171f
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-sh03.c
@@ -0,0 +1,61 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/types.h>
4#include <linux/pci.h>
5
6/*
7 * IRQ functions
8 */
9
10int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev)
11{
12 int irq;
13
14 if (dev->bus->number == 0) {
15 switch (slot) {
16 case 4: return 5; /* eth0 */
17 case 8: return 5; /* eth1 */
18 case 6: return 2; /* PCI bridge */
19 default:
20 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
21 return 2;
22 }
23 } else {
24 switch (pin) {
25 case 0: irq = 2; break;
26 case 1: irq = 2; break;
27 case 2: irq = 2; break;
28 case 3: irq = 2; break;
29 case 4: irq = 2; break;
30 default: irq = -1; break;
31 }
32 }
33 return irq;
34}
35
36static u8 __init sh03_no_swizzle(struct pci_dev *dev, u8 *pin)
37{
38 /* no swizzling */
39 return PCI_SLOT(dev->devfn);
40}
41
42static int sh03_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
43{
44 int irq = -1;
45
46 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
47 irq = pcibios_map_platform_irq(slot, pin, dev);
48 if( irq < 0 ) {
49 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
50 return irq;
51 }
52
53 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
54
55 return irq;
56}
57
58void __init pcibios_fixup_irqs(void)
59{
60 pci_fixup_irqs(sh03_no_swizzle, sh03_pci_lookup_irq);
61}
diff --git a/arch/sh/drivers/pci/ops-bigsur.c b/arch/sh/drivers/pci/ops-bigsur.c
new file mode 100644
index 000000000000..9b43da67804b
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-bigsur.c
@@ -0,0 +1,88 @@
1/*
2 * linux/arch/sh/kernel/pci-bigsur.c
3 *
4 * By Dustin McIntire (dustin@sensoria.com) (c)2001
5 *
6 * Ported to new API by Paul Mundt <lethal@linux-sh.org>.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * PCI initialization for the Hitachi Big Sur Evaluation Board
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <asm/io.h>
22#include "pci-sh7751.h"
23#include <asm/bigsur/bigsur.h>
24
25#define BIGSUR_PCI_IO 0x4000
26#define BIGSUR_PCI_MEM 0xfd000000
27
28static struct resource sh7751_io_resource = {
29 .name = "SH7751 IO",
30 .start = BIGSUR_PCI_IO,
31 .end = BIGSUR_PCI_IO + (64*1024) - 1,
32 .flags = IORESOURCE_IO,
33};
34
35static struct resource sh7751_mem_resource = {
36 .name = "SH7751 mem",
37 .start = BIGSUR_PCI_MEM,
38 .end = BIGSUR_PCI_MEM + (64*1024*1024) - 1,
39 .flags = IORESOURCE_MEM,
40};
41
42extern struct pci_ops sh7751_pci_ops;
43
44struct pci_channel board_pci_channels[] = {
45 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
46 { 0, }
47};
48
49static struct sh7751_pci_address_map sh7751_pci_map = {
50 .window0 = {
51 .base = SH7751_CS3_BASE_ADDR,
52 .size = BIGSUR_LSR0_SIZE,
53 },
54
55 .window1 = {
56 .base = SH7751_CS3_BASE_ADDR,
57 .size = BIGSUR_LSR1_SIZE,
58 },
59};
60
61/*
62 * Initialize the Big Sur PCI interface
63 * Setup hardware to be Central Funtion
64 * Copy the BSR regs to the PCI interface
65 * Setup PCI windows into local RAM
66 */
67int __init pcibios_init_platform(void)
68{
69 return sh7751_pcic_init(&sh7751_pci_map);
70}
71
72int pcibios_map_platform_irq(u8 slot, u8 pin)
73{
74 /*
75 * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI
76 * interface is on the wrong end of the board so that it can also
77 * support a V320 CPI interface chip... Therefor the IRQ mapping is
78 * somewhat use dependent... I'l assume a linear map for now, i.e.
79 * INTA=slot0,pin0... INTD=slot3,pin0...
80 */
81 int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE;
82
83 PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n",
84 slot, pin-1+'A', irq);
85
86 return irq;
87}
88
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
new file mode 100644
index 000000000000..69af80b93e3f
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -0,0 +1,169 @@
1/*
2 * arch/sh/pci/ops-dreamcast.c
3 *
4 * PCI operations for the Sega Dreamcast
5 *
6 * Copyright (C) 2001, 2002 M. R. Brown
7 * Copyright (C) 2002, 2003 Paul Mundt
8 *
9 * This file originally bore the message (with enclosed-$):
10 * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
11 * Dreamcast PCI: Supports SEGA Broadband Adaptor only.
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */
17
18#include <linux/config.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/interrupt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/pci.h>
26
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mach/pci.h>
30
31static struct resource gapspci_io_resource = {
32 .name = "GAPSPCI IO",
33 .start = GAPSPCI_BBA_CONFIG,
34 .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1,
35 .flags = IORESOURCE_IO,
36};
37
38static struct resource gapspci_mem_resource = {
39 .name = "GAPSPCI mem",
40 .start = GAPSPCI_DMA_BASE,
41 .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1,
42 .flags = IORESOURCE_MEM,
43};
44
45static struct pci_ops gapspci_pci_ops;
46
47struct pci_channel board_pci_channels[] = {
48 { &gapspci_pci_ops, &gapspci_io_resource,
49 &gapspci_mem_resource, 0, 1 },
50 { 0, }
51};
52
53/*
54 * The !gapspci_config_access case really shouldn't happen, ever, unless
55 * someone implicitly messes around with the last devfn value.. otherwise we
56 * only support a single device anyways, and if we didn't have a BBA, we
57 * wouldn't make it terribly far through the PCI setup anyways.
58 *
59 * Also, we could very easily support both Type 0 and Type 1 configurations
60 * here, but since it doesn't seem that there is any such implementation in
61 * existance, we don't bother.
62 *
63 * I suppose if someone actually gets around to ripping the chip out of
64 * the BBA and hanging some more devices off of it, then this might be
65 * something to take into consideration. However, due to the cost of the BBA,
66 * and the general lack of activity by DC hardware hackers, this doesn't seem
67 * likely to happen anytime soon.
68 */
69static int gapspci_config_access(unsigned char bus, unsigned int devfn)
70{
71 return (bus == 0) && (devfn == 0);
72}
73
74/*
75 * We can also actually read and write in b/w/l sizes! Thankfully this part
76 * was at least done right, and we don't have to do the stupid masking and
77 * shifting that we do on the 7751! Small wonders never cease to amaze.
78 */
79static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
80{
81 *val = 0xffffffff;
82
83 if (!gapspci_config_access(bus->number, devfn))
84 return PCIBIOS_DEVICE_NOT_FOUND;
85
86 switch (size) {
87 case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
88 case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
89 case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
90 }
91
92 return PCIBIOS_SUCCESSFUL;
93}
94
95static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
96{
97 if (!gapspci_config_access(bus->number, devfn))
98 return PCIBIOS_DEVICE_NOT_FOUND;
99
100 switch (size) {
101 case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
102 case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
103 case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
104 }
105
106 return PCIBIOS_SUCCESSFUL;
107}
108
109static struct pci_ops gapspci_pci_ops = {
110 .read = gapspci_read,
111 .write = gapspci_write,
112};
113
114/*
115 * gapspci init
116 */
117
118int __init gapspci_init(void)
119{
120 char idbuf[16];
121 int i;
122
123 /*
124 * FIXME: All of this wants documenting to some degree,
125 * even some basic register definitions would be nice.
126 *
127 * I haven't seen anything this ugly since.. maple.
128 */
129
130 for (i=0; i<16; i++)
131 idbuf[i] = inb(GAPSPCI_REGS+i);
132
133 if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
134 return -ENODEV;
135
136 outl(0x5a14a501, GAPSPCI_REGS+0x18);
137
138 for (i=0; i<1000000; i++)
139 ;
140
141 if (inl(GAPSPCI_REGS+0x18) != 1)
142 return -EINVAL;
143
144 outl(0x01000000, GAPSPCI_REGS+0x20);
145 outl(0x01000000, GAPSPCI_REGS+0x24);
146
147 outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
148 outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
149
150 outl(1, GAPSPCI_REGS+0x14);
151 outl(1, GAPSPCI_REGS+0x34);
152
153 /* Setting Broadband Adapter */
154 outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
155 outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
156 outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
157 outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
158 outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
159 outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
160 outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
161
162 return 0;
163}
164
165/* Haven't done anything here as yet */
166char * __devinit pcibios_setup(char *str)
167{
168 return str;
169}
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
new file mode 100644
index 000000000000..beafa11f4d0c
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -0,0 +1,79 @@
1/*
2 * linux/arch/sh/kernel/pci-rts7751r2d.c
3 *
4 * Author: Ian DaSilva (idasilva@mvista.com)
5 *
6 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * PCI initialization for the Renesas SH7751R RTS7751R2D board
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20#include <linux/module.h>
21
22#include <asm/io.h>
23#include "pci-sh7751.h"
24#include <asm/rts7751r2d/rts7751r2d.h>
25
26int __init pcibios_map_platform_irq(u8 slot, u8 pin)
27{
28 switch (slot) {
29 case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */
30 case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */
31 case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */
32 case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */
33 default:
34 printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
35 return -1;
36 }
37}
38
39static struct resource sh7751_io_resource = {
40 .name = "SH7751_IO",
41 .start = 0x4000,
42 .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
43 .flags = IORESOURCE_IO
44};
45
46static struct resource sh7751_mem_resource = {
47 .name = "SH7751_mem",
48 .start = SH7751_PCI_MEMORY_BASE,
49 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
50 .flags = IORESOURCE_MEM
51};
52
53extern struct pci_ops sh7751_pci_ops;
54
55struct pci_channel board_pci_channels[] = {
56 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
57 { NULL, NULL, NULL, 0, 0 },
58};
59EXPORT_SYMBOL(board_pci_channels);
60
61static struct sh7751_pci_address_map sh7751_pci_map = {
62 .window0 = {
63 .base = SH7751_CS3_BASE_ADDR,
64 .size = 0x04000000,
65 },
66
67 .window1 = {
68 .base = 0x00000000, /* Unused */
69 .size = 0x00000000, /* Unused */
70 },
71
72 .flags = SH7751_PCIC_NO_RESET,
73};
74
75int __init pcibios_init_platform(void)
76{
77 return sh7751_pcic_init(&sh7751_pci_map);
78}
79
diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c
new file mode 100644
index 000000000000..df2199732348
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sh03.c
@@ -0,0 +1,45 @@
1/*
2 * linux/arch/sh/drivers/pci/ops-sh03.c
3 *
4 * PCI initialization for the Interface CTP/PCI-SH03 board
5 */
6
7#include <linux/config.h>
8#include <linux/kernel.h>
9#include <linux/types.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/pci.h>
13#include <asm/io.h>
14#include "pci-sh7751.h"
15
16/*
17 * Description: This function sets up and initializes the pcic, sets
18 * up the BARS, maps the DRAM into the address space etc, etc.
19 */
20int __init pcibios_init_platform(void)
21{
22 return 1;
23}
24
25static struct resource sh7751_io_resource = {
26 .name = "SH03 IO",
27 .start = SH7751_PCI_IO_BASE,
28 .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
29 .flags = IORESOURCE_IO
30};
31
32static struct resource sh7751_mem_resource = {
33 .name = "SH03 mem",
34 .start = SH7751_PCI_MEMORY_BASE,
35 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
36 .flags = IORESOURCE_MEM
37};
38
39extern struct pci_ops sh7751_pci_ops;
40
41struct pci_channel board_pci_channels[] = {
42 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
43 { NULL, NULL, NULL, 0, 0 },
44};
45
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c
new file mode 100644
index 000000000000..6fdb9765c99a
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-snapgear.c
@@ -0,0 +1,102 @@
1/*
2 * arch/sh/drivers/pci/ops-snapgear.c
3 *
4 * Author: David McCullough <davidm@snapgear.com>
5 *
6 * Ported to new API by Paul Mundt <lethal@linux-sh.org>
7 *
8 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 *
13 * PCI initialization for the SnapGear boards
14 */
15
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/pci.h>
22
23#include <asm/io.h>
24#include "pci-sh7751.h"
25
26#define SNAPGEAR_PCI_IO 0x4000
27#define SNAPGEAR_PCI_MEM 0xfd000000
28
29/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
30#define SNAPGEAR_LSR0_SIZE (64*(1<<20)) //64MB
31#define SNAPGEAR_LSR1_SIZE (64*(1<<20)) //64MB
32
33static struct resource sh7751_io_resource = {
34 .name = "SH7751 IO",
35 .start = SNAPGEAR_PCI_IO,
36 .end = SNAPGEAR_PCI_IO + (64*1024) - 1, /* 64KiB I/O */
37 .flags = IORESOURCE_IO,
38};
39
40static struct resource sh7751_mem_resource = {
41 .name = "SH7751 mem",
42 .start = SNAPGEAR_PCI_MEM,
43 .end = SNAPGEAR_PCI_MEM + (64*1024*1024) - 1, /* 64MiB mem */
44 .flags = IORESOURCE_MEM,
45};
46
47extern struct pci_ops sh7751_pci_ops;
48
49struct pci_channel board_pci_channels[] = {
50 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
51 { 0, }
52};
53
54static struct sh7751_pci_address_map sh7751_pci_map = {
55 .window0 = {
56 .base = SH7751_CS2_BASE_ADDR,
57 .size = SNAPGEAR_LSR0_SIZE,
58 },
59
60 .window1 = {
61 .base = SH7751_CS2_BASE_ADDR,
62 .size = SNAPGEAR_LSR1_SIZE,
63 },
64
65 .flags = SH7751_PCIC_NO_RESET,
66};
67
68/*
69 * Initialize the SnapGear PCI interface
70 * Setup hardware to be Central Funtion
71 * Copy the BSR regs to the PCI interface
72 * Setup PCI windows into local RAM
73 */
74int __init pcibios_init_platform(void)
75{
76 return sh7751_pcic_init(&sh7751_pci_map);
77}
78
79int __init pcibios_map_platform_irq(u8 slot, u8 pin)
80{
81 int irq = -1;
82
83 switch (slot) {
84 case 8: /* the PCI bridge */ break;
85 case 11: irq = 8; break; /* USB */
86 case 12: irq = 11; break; /* PCMCIA */
87 case 13: irq = 5; break; /* eth0 */
88 case 14: irq = 8; break; /* eth1 */
89 case 15: irq = 11; break; /* safenet (unused) */
90 }
91
92 printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n",
93 slot, pin - 1 + 'A', irq);
94
95 return irq;
96}
97
98void __init pcibios_fixup(void)
99{
100 /* Nothing to fixup .. */
101}
102
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
new file mode 100644
index 000000000000..4cef4d1d8c84
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -0,0 +1,555 @@
1/*
2 * PCI autoconfiguration library
3 *
4 * Author: Matt Porter <mporter@mvista.com>
5 *
6 * Copyright 2000, 2001 MontaVista Software Inc.
7 * Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
8 * Copyright 2003 Paul Mundt <lethal@linux-sh.org>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16/*
17 * Modified for MIPS by Jun Sun, jsun@mvista.com
18 *
19 * . Simplify the interface between pci_auto and the rest: a single function.
20 * . Assign resources from low address to upper address.
21 * . change most int to u32.
22 *
23 * Further modified to include it as mips generic code, ppopov@mvista.com.
24 *
25 * 2001-10-26 Bradley D. LaRonde <brad@ltc.com>
26 * - Add a top_bus argument to the "early config" functions so that
27 * they can set a fake parent bus pointer to convince the underlying
28 * pci ops to use type 1 configuration for sub busses.
29 * - Set bridge base and limit registers correctly.
30 * - Align io and memory base properly before and after bridge setup.
31 * - Don't fall through to pci_setup_bars for bridge.
32 * - Reformat the debug output to look more like lspci's output.
33 *
34 * Cloned for SuperH by M. R. Brown, mrbrown@0xd6.org
35 *
36 * 2003-08-05 Paul Mundt <lethal@linux-sh.org>
37 * - Don't update the BAR values on systems that already have valid addresses
38 * and don't want these updated for whatever reason, by way of a new config
39 * option check. However, we still read in the old BAR values so that they
40 * can still be reported through the debug output.
41 */
42
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/types.h>
46#include <linux/pci.h>
47
48#undef DEBUG
49#ifdef DEBUG
50#define DBG(x...) printk(x)
51#else
52#define DBG(x...)
53#endif
54
55/*
56 * These functions are used early on before PCI scanning is done
57 * and all of the pci_dev and pci_bus structures have been created.
58 */
59static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
60 int top_bus, int busnr, int devfn)
61{
62 static struct pci_dev dev;
63 static struct pci_bus bus;
64
65 dev.bus = &bus;
66 dev.sysdata = hose;
67 dev.devfn = devfn;
68 bus.number = busnr;
69 bus.ops = hose->pci_ops;
70
71 if(busnr != top_bus)
72 /* Fake a parent bus structure. */
73 bus.parent = &bus;
74 else
75 bus.parent = NULL;
76
77 return &dev;
78}
79
80#define EARLY_PCI_OP(rw, size, type) \
81int early_##rw##_config_##size(struct pci_channel *hose, \
82 int top_bus, int bus, int devfn, int offset, type value) \
83{ \
84 return pci_##rw##_config_##size( \
85 fake_pci_dev(hose, top_bus, bus, devfn), \
86 offset, value); \
87}
88
89EARLY_PCI_OP(read, byte, u8 *)
90EARLY_PCI_OP(read, word, u16 *)
91EARLY_PCI_OP(read, dword, u32 *)
92EARLY_PCI_OP(write, byte, u8)
93EARLY_PCI_OP(write, word, u16)
94EARLY_PCI_OP(write, dword, u32)
95
96static struct resource *io_resource_inuse;
97static struct resource *mem_resource_inuse;
98
99static u32 pciauto_lower_iospc;
100static u32 pciauto_upper_iospc;
101
102static u32 pciauto_lower_memspc;
103static u32 pciauto_upper_memspc;
104
105static void __init
106pciauto_setup_bars(struct pci_channel *hose,
107 int top_bus,
108 int current_bus,
109 int pci_devfn,
110 int bar_limit)
111{
112 u32 bar_response, bar_size, bar_value;
113 u32 bar, addr_mask, bar_nr = 0;
114 u32 * upper_limit;
115 u32 * lower_limit;
116 int found_mem64 = 0;
117
118 for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
119#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
120 u32 bar_addr;
121
122 /* Read the old BAR value */
123 early_read_config_dword(hose, top_bus,
124 current_bus,
125 pci_devfn,
126 bar,
127 &bar_addr);
128#endif
129
130 /* Tickle the BAR and get the response */
131 early_write_config_dword(hose, top_bus,
132 current_bus,
133 pci_devfn,
134 bar,
135 0xffffffff);
136
137 early_read_config_dword(hose, top_bus,
138 current_bus,
139 pci_devfn,
140 bar,
141 &bar_response);
142
143#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
144 /*
145 * Write the old BAR value back out, only update the BAR
146 * if we implicitly want resources to be updated, which
147 * is done by the generic code further down. -- PFM.
148 */
149 early_write_config_dword(hose, top_bus,
150 current_bus,
151 pci_devfn,
152 bar,
153 bar_addr);
154#endif
155
156 /* If BAR is not implemented go to the next BAR */
157 if (!bar_response)
158 continue;
159
160 /*
161 * Workaround for a BAR that doesn't use its upper word,
162 * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457).
163 * bdl <brad@ltc.com>
164 */
165 if (!(bar_response & 0xffff0000))
166 bar_response |= 0xffff0000;
167
168retry:
169 /* Check the BAR type and set our address mask */
170 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
171 addr_mask = PCI_BASE_ADDRESS_IO_MASK;
172 upper_limit = &pciauto_upper_iospc;
173 lower_limit = &pciauto_lower_iospc;
174 DBG(" I/O");
175 } else {
176 if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
177 PCI_BASE_ADDRESS_MEM_TYPE_64)
178 found_mem64 = 1;
179
180 addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
181 upper_limit = &pciauto_upper_memspc;
182 lower_limit = &pciauto_lower_memspc;
183 DBG(" Mem");
184 }
185
186
187 /* Calculate requested size */
188 bar_size = ~(bar_response & addr_mask) + 1;
189
190 /* Allocate a base address */
191 bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size;
192
193 if ((bar_value + bar_size) > *upper_limit) {
194 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
195 if (io_resource_inuse->child) {
196 io_resource_inuse =
197 io_resource_inuse->child;
198 pciauto_lower_iospc =
199 io_resource_inuse->start;
200 pciauto_upper_iospc =
201 io_resource_inuse->end + 1;
202 goto retry;
203 }
204
205 } else {
206 if (mem_resource_inuse->child) {
207 mem_resource_inuse =
208 mem_resource_inuse->child;
209 pciauto_lower_memspc =
210 mem_resource_inuse->start;
211 pciauto_upper_memspc =
212 mem_resource_inuse->end + 1;
213 goto retry;
214 }
215 }
216 DBG(" unavailable -- skipping, value %x size %x\n",
217 bar_value, bar_size);
218 continue;
219 }
220
221#ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES
222 /* Write it out and update our limit */
223 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
224 bar, bar_value);
225#endif
226
227 *lower_limit = bar_value + bar_size;
228
229 /*
230 * If we are a 64-bit decoder then increment to the
231 * upper 32 bits of the bar and force it to locate
232 * in the lower 4GB of memory.
233 */
234 if (found_mem64) {
235 bar += 4;
236 early_write_config_dword(hose, top_bus,
237 current_bus,
238 pci_devfn,
239 bar,
240 0x00000000);
241 }
242
243 DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size);
244
245 bar_nr++;
246 }
247
248}
249
250static void __init
251pciauto_prescan_setup_bridge(struct pci_channel *hose,
252 int top_bus,
253 int current_bus,
254 int pci_devfn,
255 int sub_bus)
256{
257 /* Configure bus number registers */
258 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
259 PCI_PRIMARY_BUS, current_bus);
260 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
261 PCI_SECONDARY_BUS, sub_bus + 1);
262 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
263 PCI_SUBORDINATE_BUS, 0xff);
264
265 /* Align memory and I/O to 1MB and 4KB boundaries. */
266 pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
267 & ~(0x100000 - 1);
268 pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
269 & ~(0x1000 - 1);
270
271 /* Set base (lower limit) of address range behind bridge. */
272 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
273 PCI_MEMORY_BASE, pciauto_lower_memspc >> 16);
274 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
275 PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8);
276 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
277 PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16);
278
279 /* We don't support prefetchable memory for now, so disable */
280 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
281 PCI_PREF_MEMORY_BASE, 0);
282 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
283 PCI_PREF_MEMORY_LIMIT, 0);
284}
285
286static void __init
287pciauto_postscan_setup_bridge(struct pci_channel *hose,
288 int top_bus,
289 int current_bus,
290 int pci_devfn,
291 int sub_bus)
292{
293 u32 temp;
294
295 /*
296 * [jsun] we always bump up baselines a little, so that if there
297 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
298 * spaces.
299 */
300 pciauto_lower_memspc += 1;
301 pciauto_lower_iospc += 1;
302
303 /* Configure bus number registers */
304 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
305 PCI_SUBORDINATE_BUS, sub_bus);
306
307 /* Set upper limit of address range behind bridge. */
308 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
309 PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16);
310 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
311 PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8);
312 early_write_config_word(hose, top_bus, current_bus, pci_devfn,
313 PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16);
314
315 /* Align memory and I/O to 1MB and 4KB boundaries. */
316 pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1))
317 & ~(0x100000 - 1);
318 pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1))
319 & ~(0x1000 - 1);
320
321 /* Enable memory and I/O accesses, enable bus master */
322 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
323 PCI_COMMAND, &temp);
324 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
325 PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY
326 | PCI_COMMAND_MASTER);
327}
328
329static void __init
330pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose,
331 int top_bus,
332 int current_bus,
333 int pci_devfn,
334 int sub_bus)
335{
336 /* Configure bus number registers */
337 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
338 PCI_PRIMARY_BUS, current_bus);
339 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
340 PCI_SECONDARY_BUS, sub_bus + 1);
341 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
342 PCI_SUBORDINATE_BUS, 0xff);
343
344 /* Align memory and I/O to 4KB and 4 byte boundaries. */
345 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
346 & ~(0x1000 - 1);
347 pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
348 & ~(0x4 - 1);
349
350 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
351 PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc);
352 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
353 PCI_CB_IO_BASE_0, pciauto_lower_iospc);
354}
355
356static void __init
357pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
358 int top_bus,
359 int current_bus,
360 int pci_devfn,
361 int sub_bus)
362{
363 u32 temp;
364
365#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
366 /*
367 * [jsun] we always bump up baselines a little, so that if there
368 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
369 * spaces.
370 */
371 pciauto_lower_memspc += 1;
372 pciauto_lower_iospc += 1;
373#endif
374
375 /*
376 * Configure subordinate bus number. The PCI subsystem
377 * bus scan will renumber buses (reserving three additional
378 * for this PCI<->CardBus bridge for the case where a CardBus
379 * adapter contains a P2P or CB2CB bridge.
380 */
381
382 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
383 PCI_SUBORDINATE_BUS, sub_bus);
384
385 /*
386 * Reserve an additional 4MB for mem space and 16KB for
387 * I/O space. This should cover any additional space
388 * requirement of unusual CardBus devices with
389 * additional bridges that can consume more address space.
390 *
391 * Although pcmcia-cs currently will reprogram bridge
392 * windows, the goal is to add an option to leave them
393 * alone and use the bridge window ranges as the regions
394 * that are searched for free resources upon hot-insertion
395 * of a device. This will allow a PCI<->CardBus bridge
396 * configured by this routine to happily live behind a
397 * P2P bridge in a system.
398 */
399#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
400 pciauto_lower_memspc += 0x00400000;
401 pciauto_lower_iospc += 0x00004000;
402#endif
403
404 /* Align memory and I/O to 4KB and 4 byte boundaries. */
405 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
406 & ~(0x1000 - 1);
407 pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1))
408 & ~(0x4 - 1);
409 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
410 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
411 PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1);
412 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
413 PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1);
414
415 /* Enable memory and I/O accesses, enable bus master */
416 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
417 PCI_COMMAND, &temp);
418 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
419 PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
420 PCI_COMMAND_MASTER);
421}
422
423#define PCIAUTO_IDE_MODE_MASK 0x05
424
425static int __init
426pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
427{
428 int sub_bus;
429 u32 pci_devfn, pci_class, cmdstat, found_multi=0;
430 unsigned short vid, did;
431 unsigned char header_type;
432 int devfn_start = 0;
433 int devfn_stop = 0xff;
434
435 sub_bus = current_bus;
436
437 if (hose->first_devfn)
438 devfn_start = hose->first_devfn;
439 if (hose->last_devfn)
440 devfn_stop = hose->last_devfn;
441
442 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
443
444 if (PCI_FUNC(pci_devfn) && !found_multi)
445 continue;
446
447 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
448 PCI_VENDOR_ID, &vid);
449
450 if (vid == 0xffff) continue;
451
452 early_read_config_byte(hose, top_bus, current_bus, pci_devfn,
453 PCI_HEADER_TYPE, &header_type);
454
455 if (!PCI_FUNC(pci_devfn))
456 found_multi = header_type & 0x80;
457
458 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
459 PCI_DEVICE_ID, &did);
460
461 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
462 PCI_CLASS_REVISION, &pci_class);
463
464 DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x",
465 current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn),
466 pci_class >> 16, vid, did);
467 if (pci_class & 0xff)
468 DBG(" (rev %.2x)", pci_class & 0xff);
469 DBG("\n");
470
471 if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
472 DBG(" Bridge: primary=%.2x, secondary=%.2x\n",
473 current_bus, sub_bus + 1);
474#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
475 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
476#endif
477 pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
478 pci_devfn, sub_bus);
479 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
480 sub_bus + 1,
481 pciauto_lower_iospc, pciauto_lower_memspc);
482 sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
483 DBG("Back to bus %.2x\n", current_bus);
484 pciauto_postscan_setup_bridge(hose, top_bus, current_bus,
485 pci_devfn, sub_bus);
486 continue;
487 } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
488 DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n",
489 current_bus, sub_bus + 1);
490 DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
491 /* Place CardBus Socket/ExCA registers */
492 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
493
494 pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
495 current_bus, pci_devfn, sub_bus);
496
497 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
498 sub_bus + 1,
499 pciauto_lower_iospc, pciauto_lower_memspc);
500 sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1);
501 DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus);
502 pciauto_postscan_setup_cardbus_bridge(hose, top_bus,
503 current_bus, pci_devfn, sub_bus);
504 continue;
505 } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
506
507 unsigned char prg_iface;
508
509 early_read_config_byte(hose, top_bus, current_bus,
510 pci_devfn, PCI_CLASS_PROG, &prg_iface);
511 if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
512 DBG("Skipping legacy mode IDE controller\n");
513 continue;
514 }
515 }
516
517 /*
518 * Found a peripheral, enable some standard
519 * settings
520 */
521 early_read_config_dword(hose, top_bus, current_bus, pci_devfn,
522 PCI_COMMAND, &cmdstat);
523 early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
524 PCI_COMMAND, cmdstat | PCI_COMMAND_IO |
525 PCI_COMMAND_MEMORY |
526 PCI_COMMAND_MASTER);
527#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
528 early_write_config_byte(hose, top_bus, current_bus, pci_devfn,
529 PCI_LATENCY_TIMER, 0x80);
530#endif
531
532 /* Allocate PCI I/O and/or memory space */
533 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5);
534 }
535 return sub_bus;
536}
537
538int __init
539pciauto_assign_resources(int busno, struct pci_channel *hose)
540{
541 /* setup resource limits */
542 io_resource_inuse = hose->io_resource;
543 mem_resource_inuse = hose->mem_resource;
544
545 pciauto_lower_iospc = io_resource_inuse->start;
546 pciauto_upper_iospc = io_resource_inuse->end + 1;
547 pciauto_lower_memspc = mem_resource_inuse->start;
548 pciauto_upper_memspc = mem_resource_inuse->end + 1;
549 DBG("Autoconfig PCI channel 0x%p\n", hose);
550 DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n",
551 busno, pciauto_lower_iospc, pciauto_upper_iospc,
552 pciauto_lower_memspc, pciauto_upper_memspc);
553
554 return pciauto_bus_scan(hose, busno, busno);
555}
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
new file mode 100644
index 000000000000..30b14ac7ae5a
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -0,0 +1,417 @@
1/*
2 * Low-Level PCI Support for the SH7751
3 *
4 * Dustin McIntire (dustin@sensoria.com)
5 * Derived from arch/i386/kernel/pci-*.c which bore the message:
6 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
7 *
8 * Ported to the new API by Paul Mundt <lethal@linux-sh.org>
9 * With cleanup by Paul van Gool <pvangool@mimotech.com>
10 *
11 * May be copied or modified under the terms of the GNU General Public
12 * License. See linux/COPYING for more information.
13 *
14 */
15
16#undef DEBUG
17
18#include <linux/config.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/pci.h>
23#include <linux/sched.h>
24#include <linux/ioport.h>
25#include <linux/errno.h>
26#include <linux/irq.h>
27#include <linux/delay.h>
28
29#include <asm/machvec.h>
30#include <asm/io.h>
31#include "pci-sh7751.h"
32
33static unsigned int pci_probe = PCI_PROBE_CONF1;
34extern int pci_fixup_pcic(void);
35
36void pcibios_fixup_irqs(void) __attribute__ ((weak));
37
38/*
39 * Direct access to PCI hardware...
40 */
41
42#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
43
44/*
45 * Functions for accessing PCI configuration space with type 1 accesses
46 */
47static int sh7751_pci_read(struct pci_bus *bus, unsigned int devfn,
48 int where, int size, u32 *val)
49{
50 unsigned long flags;
51 u32 data;
52
53 /*
54 * PCIPDR may only be accessed as 32 bit words,
55 * so we must do byte alignment by hand
56 */
57 local_irq_save(flags);
58 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
59 data = inl(PCI_REG(SH7751_PCIPDR));
60 local_irq_restore(flags);
61
62 switch (size) {
63 case 1:
64 *val = (data >> ((where & 3) << 3)) & 0xff;
65 break;
66 case 2:
67 *val = (data >> ((where & 2) << 3)) & 0xffff;
68 break;
69 case 4:
70 *val = data;
71 break;
72 default:
73 return PCIBIOS_FUNC_NOT_SUPPORTED;
74 }
75
76 return PCIBIOS_SUCCESSFUL;
77}
78
79/*
80 * Since SH7751 only does 32bit access we'll have to do a read,
81 * mask,write operation.
82 * We'll allow an odd byte offset, though it should be illegal.
83 */
84static int sh7751_pci_write(struct pci_bus *bus, unsigned int devfn,
85 int where, int size, u32 val)
86{
87 unsigned long flags;
88 int shift;
89 u32 data;
90
91 local_irq_save(flags);
92 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
93 data = inl(PCI_REG(SH7751_PCIPDR));
94 local_irq_restore(flags);
95
96 switch (size) {
97 case 1:
98 shift = (where & 3) << 3;
99 data &= ~(0xff << shift);
100 data |= ((val & 0xff) << shift);
101 break;
102 case 2:
103 shift = (where & 2) << 3;
104 data &= ~(0xffff << shift);
105 data |= ((val & 0xffff) << shift);
106 break;
107 case 4:
108 data = val;
109 break;
110 default:
111 return PCIBIOS_FUNC_NOT_SUPPORTED;
112 }
113
114 outl(data, PCI_REG(SH7751_PCIPDR));
115
116 return PCIBIOS_SUCCESSFUL;
117}
118
119#undef CONFIG_CMD
120
121struct pci_ops sh7751_pci_ops = {
122 .read = sh7751_pci_read,
123 .write = sh7751_pci_write,
124};
125
126static int __init pci_check_direct(void)
127{
128 unsigned int tmp, id;
129
130 /* check for SH7751/SH7751R hardware */
131 id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0);
132 if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
133 id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
134 pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
135 return -ENODEV;
136 }
137
138 /*
139 * Check if configuration works.
140 */
141 if (pci_probe & PCI_PROBE_CONF1) {
142 tmp = inl (PCI_REG(SH7751_PCIPAR));
143 outl (0x80000000, PCI_REG(SH7751_PCIPAR));
144 if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) {
145 outl (tmp, PCI_REG(SH7751_PCIPAR));
146 printk(KERN_INFO "PCI: Using configuration type 1\n");
147 request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1");
148 return 0;
149 }
150 outl (tmp, PCI_REG(SH7751_PCIPAR));
151 }
152
153 pr_debug("PCI: pci_check_direct failed\n");
154 return -EINVAL;
155}
156
157/***************************************************************************************/
158
159/*
160 * Handle bus scanning and fixups ....
161 */
162
163static void __init pci_fixup_ide_bases(struct pci_dev *d)
164{
165 int i;
166
167 /*
168 * PCI IDE controllers use non-standard I/O port decoding, respect it.
169 */
170 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
171 return;
172 pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
173 for(i=0; i<4; i++) {
174 struct resource *r = &d->resource[i];
175 if ((r->start & ~0x80) == 0x374) {
176 r->start |= 2;
177 r->end = r->start;
178 }
179 }
180}
181
182DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
183
184/*
185 * Called after each bus is probed, but before its children
186 * are examined.
187 */
188
189void __init pcibios_fixup_bus(struct pci_bus *b)
190{
191 pci_read_bridge_bases(b);
192}
193
194/*
195 * Initialization. Try all known PCI access methods. Note that we support
196 * using both PCI BIOS and direct access: in such cases, we use I/O ports
197 * to access config space.
198 *
199 * Note that the platform specific initialization (BSC registers, and memory
200 * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it
201 * exitst and via the platform defined function pcibios_init_platform().
202 * See pci_bigsur.c for implementation;
203 *
204 * The BIOS version of the pci functions is not yet implemented but it is left
205 * in for completeness. Currently an error will be genereated at compile time.
206 */
207
208static int __init sh7751_pci_init(void)
209{
210 int ret;
211
212 pr_debug("PCI: Starting intialization.\n");
213 if ((ret = pci_check_direct()) != 0)
214 return ret;
215
216 return pcibios_init_platform();
217}
218
219subsys_initcall(sh7751_pci_init);
220
221static int __init __area_sdram_check(unsigned int area)
222{
223 u32 word;
224
225 word = inl(SH7751_BCR1);
226 /* check BCR for SDRAM in area */
227 if(((word >> area) & 1) == 0) {
228 printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n",
229 area, word);
230 return 0;
231 }
232 outl(word, PCI_REG(SH7751_PCIBCR1));
233
234 word = (u16)inw(SH7751_BCR2);
235 /* check BCR2 for 32bit SDRAM interface*/
236 if(((word >> (area << 1)) & 0x3) != 0x3) {
237 printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n",
238 area, word);
239 return 0;
240 }
241 outl(word, PCI_REG(SH7751_PCIBCR2));
242
243 return 1;
244}
245
246int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
247{
248 u32 reg;
249 u32 word;
250
251 /* Set the BCR's to enable PCI access */
252 reg = inl(SH7751_BCR1);
253 reg |= 0x80000;
254 outl(reg, SH7751_BCR1);
255
256 /* Turn the clocks back on (not done in reset)*/
257 outl(0, PCI_REG(SH7751_PCICLKR));
258 /* Clear Powerdown IRQ's (not done in reset) */
259 word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0;
260 outl(word, PCI_REG(SH7751_PCIPINT));
261
262 /*
263 * This code is unused for some boards as it is done in the
264 * bootloader and doing it here means the MAC addresses loaded
265 * by the bootloader get lost.
266 */
267 if (!(map->flags & SH7751_PCIC_NO_RESET)) {
268 /* toggle PCI reset pin */
269 word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
270 outl(word,PCI_REG(SH7751_PCICR));
271 /* Wait for a long time... not 1 sec. but long enough */
272 mdelay(100);
273 word = SH7751_PCICR_PREFIX;
274 outl(word,PCI_REG(SH7751_PCICR));
275 }
276
277 /* set the command/status bits to:
278 * Wait Cycle Control + Parity Enable + Bus Master +
279 * Mem space enable
280 */
281 word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
282 SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
283 outl(word, PCI_REG(SH7751_PCICONF1));
284
285 /* define this host as the host bridge */
286 word = SH7751_PCI_HOST_BRIDGE << 24;
287 outl(word, PCI_REG(SH7751_PCICONF2));
288
289 /* Set IO and Mem windows to local address
290 * Make PCI and local address the same for easy 1 to 1 mapping
291 * Window0 = map->window0.size @ non-cached area base = SDRAM
292 * Window1 = map->window1.size @ cached area base = SDRAM
293 */
294 word = map->window0.size - 1;
295 outl(word, PCI_REG(SH7751_PCILSR0));
296 word = map->window1.size - 1;
297 outl(word, PCI_REG(SH7751_PCILSR1));
298 /* Set the values on window 0 PCI config registers */
299 word = P2SEGADDR(map->window0.base);
300 outl(word, PCI_REG(SH7751_PCILAR0));
301 outl(word, PCI_REG(SH7751_PCICONF5));
302 /* Set the values on window 1 PCI config registers */
303 word = PHYSADDR(map->window1.base);
304 outl(word, PCI_REG(SH7751_PCILAR1));
305 outl(word, PCI_REG(SH7751_PCICONF6));
306
307 /* Set the local 16MB PCI memory space window to
308 * the lowest PCI mapped address
309 */
310 word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK;
311 PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word);
312 outl(word , PCI_REG(SH7751_PCIMBR));
313
314 /* Map IO space into PCI IO window
315 * The IO window is 64K-PCIBIOS_MIN_IO in size
316 * IO addresses will be translated to the
317 * PCI IO window base address
318 */
319 PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
320 (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO);
321
322 /*
323 * XXX: For now, leave this board-specific. In the event we have other
324 * boards that need to do similar work, this can be wrapped.
325 */
326#ifdef CONFIG_SH_BIGSUR
327 bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0);
328#endif
329
330 /* Make sure the MSB's of IO window are set to access PCI space correctly */
331 word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK;
332 PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word);
333 outl(word, PCI_REG(SH7751_PCIIOBR));
334
335 /* Set PCI WCRx, BCRx's, copy from BSC locations */
336
337 /* check BCR for SDRAM in specified area */
338 switch (map->window0.base) {
339 case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(0); break;
340 case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(1); break;
341 case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(2); break;
342 case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(3); break;
343 case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(4); break;
344 case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break;
345 case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break;
346 }
347
348 if (!word)
349 return 0;
350
351 /* configure the wait control registers */
352 word = inl(SH7751_WCR1);
353 outl(word, PCI_REG(SH7751_PCIWCR1));
354 word = inl(SH7751_WCR2);
355 outl(word, PCI_REG(SH7751_PCIWCR2));
356 word = inl(SH7751_WCR3);
357 outl(word, PCI_REG(SH7751_PCIWCR3));
358 word = inl(SH7751_MCR);
359 outl(word, PCI_REG(SH7751_PCIMCR));
360
361 /* NOTE: I'm ignoring the PCI error IRQs for now..
362 * TODO: add support for the internal error interrupts and
363 * DMA interrupts...
364 */
365
366#ifdef CONFIG_SH_RTS7751R2D
367 pci_fixup_pcic();
368#endif
369
370 /* SH7751 init done, set central function init complete */
371 /* use round robin mode to stop a device starving/overruning */
372 word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM;
373 outl(word,PCI_REG(SH7751_PCICR));
374
375 return 1;
376}
377
378char * __init pcibios_setup(char *str)
379{
380 if (!strcmp(str, "off")) {
381 pci_probe = 0;
382 return NULL;
383 }
384
385 return str;
386}
387
388/*
389 * IRQ functions
390 */
391static u8 __init sh7751_no_swizzle(struct pci_dev *dev, u8 *pin)
392{
393 /* no swizzling */
394 return PCI_SLOT(dev->devfn);
395}
396
397static int sh7751_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
398{
399 int irq = -1;
400
401 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
402 irq = pcibios_map_platform_irq(slot,pin);
403 if( irq < 0 ) {
404 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
405 return irq;
406 }
407
408 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
409
410 return irq;
411}
412
413void __init pcibios_fixup_irqs(void)
414{
415 pci_fixup_irqs(sh7751_no_swizzle, sh7751_pci_lookup_irq);
416}
417
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
new file mode 100644
index 000000000000..1fee5cae10d1
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -0,0 +1,303 @@
1/*
2 * Low-Level PCI Support for SH7751 targets
3 *
4 * Dustin McIntire (dustin@sensoria.com) (c) 2001
5 * Paul Mundt (lethal@linux-sh.org) (c) 2003
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 */
11
12#ifndef _PCI_SH7751_H_
13#define _PCI_SH7751_H_
14
15#include <linux/pci.h>
16
17/* set debug level 4=verbose...1=terse */
18//#define DEBUG_PCI 3
19#undef DEBUG_PCI
20
21#ifdef DEBUG_PCI
22#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
23#else
24#define PCIDBG(n, x...)
25#endif
26
27/* startup values */
28#define PCI_PROBE_BIOS 1
29#define PCI_PROBE_CONF1 2
30#define PCI_PROBE_CONF2 4
31#define PCI_NO_SORT 0x100
32#define PCI_BIOS_SORT 0x200
33#define PCI_NO_CHECKS 0x400
34#define PCI_ASSIGN_ROMS 0x1000
35#define PCI_BIOS_IRQ_SCAN 0x2000
36
37/* Platform Specific Values */
38#define SH7751_VENDOR_ID 0x1054
39#define SH7751_DEVICE_ID 0x3505
40#define SH7751R_DEVICE_ID 0x350e
41
42/* SH7751 Specific Values */
43#define SH7751_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */
44#define SH7751_PCI_CONFIG_SIZE 0x1000000 /* Config space size */
45#define SH7751_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */
46#define SH7751_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */
47#define SH7751_PCI_IO_BASE 0xFE240000 /* IO space base address */
48#define SH7751_PCI_IO_SIZE 0x40000 /* Size of IO window */
49
50#define SH7751_PCIREG_BASE 0xFE200000 /* PCI regs base address */
51#define PCI_REG(n) (SH7751_PCIREG_BASE+ n)
52
53#define SH7751_PCICONF0 0x0 /* PCI Config Reg 0 */
54 #define SH7751_PCICONF0_DEVID 0xFFFF0000 /* Device ID */
55 #define SH7751_PCICONF0_VNDID 0x0000FFFF /* Vendor ID */
56#define SH7751_PCICONF1 0x4 /* PCI Config Reg 1 */
57 #define SH7751_PCICONF1_DPE 0x80000000 /* Data Parity Error */
58 #define SH7751_PCICONF1_SSE 0x40000000 /* System Error Status */
59 #define SH7751_PCICONF1_RMA 0x20000000 /* Master Abort */
60 #define SH7751_PCICONF1_RTA 0x10000000 /* Target Abort Rx Status */
61 #define SH7751_PCICONF1_STA 0x08000000 /* Target Abort Exec Status */
62 #define SH7751_PCICONF1_DEV 0x06000000 /* Timing Status */
63 #define SH7751_PCICONF1_DPD 0x01000000 /* Data Parity Status */
64 #define SH7751_PCICONF1_FBBC 0x00800000 /* Back 2 Back Status */
65 #define SH7751_PCICONF1_UDF 0x00400000 /* User Defined Status */
66 #define SH7751_PCICONF1_66M 0x00200000 /* 66Mhz Operation Status */
67 #define SH7751_PCICONF1_PM 0x00100000 /* Power Management Status */
68 #define SH7751_PCICONF1_PBBE 0x00000200 /* Back 2 Back Control */
69 #define SH7751_PCICONF1_SER 0x00000100 /* SERR Output Control */
70 #define SH7751_PCICONF1_WCC 0x00000080 /* Wait Cycle Control */
71 #define SH7751_PCICONF1_PER 0x00000040 /* Parity Error Response */
72 #define SH7751_PCICONF1_VPS 0x00000020 /* VGA Pallet Snoop */
73 #define SH7751_PCICONF1_MWIE 0x00000010 /* Memory Write+Invalidate */
74 #define SH7751_PCICONF1_SPC 0x00000008 /* Special Cycle Control */
75 #define SH7751_PCICONF1_BUM 0x00000004 /* Bus Master Control */
76 #define SH7751_PCICONF1_MES 0x00000002 /* Memory Space Control */
77 #define SH7751_PCICONF1_IOS 0x00000001 /* I/O Space Control */
78#define SH7751_PCICONF2 0x8 /* PCI Config Reg 2 */
79 #define SH7751_PCICONF2_BCC 0xFF000000 /* Base Class Code */
80 #define SH7751_PCICONF2_SCC 0x00FF0000 /* Sub-Class Code */
81 #define SH7751_PCICONF2_RLPI 0x0000FF00 /* Programming Interface */
82 #define SH7751_PCICONF2_REV 0x000000FF /* Revision ID */
83#define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */
84 #define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */
85 #define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */
86 #define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */
87 #define SH7751_PCICONF3_HD7 0x00800000 /* Single Funtion device */
88 #define SH7751_PCICONF3_HD6_0 0x007F0000 /* Configuration Layout */
89 #define SH7751_PCICONF3_LAT 0x0000FF00 /* Latency Timer */
90 #define SH7751_PCICONF3_CLS 0x000000FF /* Cache Line Size */
91#define SH7751_PCICONF4 0x10 /* PCI Config Reg 4 */
92 #define SH7751_PCICONF4_BASE 0xFFFFFFFC /* I/O Space Base Addr */
93 #define SH7751_PCICONF4_ASI 0x00000001 /* Address Space Type */
94#define SH7751_PCICONF5 0x14 /* PCI Config Reg 5 */
95 #define SH7751_PCICONF5_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
96 #define SH7751_PCICONF5_LAP 0x00000008 /* Prefetch Enabled */
97 #define SH7751_PCICONF5_LAT 0x00000006 /* Local Memory type */
98 #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */
99#define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */
100 #define SH7751_PCICONF6_BASE 0xFFFFFFF0 /* Mem Space Base Addr */
101 #define SH7751_PCICONF6_LAP 0x00000008 /* Prefetch Enabled */
102 #define SH7751_PCICONF6_LAT 0x00000006 /* Local Memory type */
103 #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */
104/* PCICONF7 - PCICONF10 are undefined */
105#define SH7751_PCICONF11 0x2C /* PCI Config Reg 11 */
106 #define SH7751_PCICONF11_SSID 0xFFFF0000 /* Subsystem ID */
107 #define SH7751_PCICONF11_SVID 0x0000FFFF /* Subsystem Vendor ID */
108/* PCICONF12 is undefined */
109#define SH7751_PCICONF13 0x34 /* PCI Config Reg 13 */
110 #define SH7751_PCICONF13_CPTR 0x000000FF /* PM function pointer */
111/* PCICONF14 is undefined */
112#define SH7751_PCICONF15 0x3C /* PCI Config Reg 15 */
113 #define SH7751_PCICONF15_IPIN 0x000000FF /* Interrupt Pin */
114#define SH7751_PCICONF16 0x40 /* PCI Config Reg 16 */
115 #define SH7751_PCICONF16_PMES 0xF8000000 /* PME Support */
116 #define SH7751_PCICONF16_D2S 0x04000000 /* D2 Support */
117 #define SH7751_PCICONF16_D1S 0x02000000 /* D1 Support */
118 #define SH7751_PCICONF16_DSI 0x00200000 /* Bit Device Init. */
119 #define SH7751_PCICONF16_PMCK 0x00080000 /* Clock for PME req. */
120 #define SH7751_PCICONF16_VER 0x00070000 /* PM Version */
121 #define SH7751_PCICONF16_NIP 0x0000FF00 /* Next Item Pointer */
122 #define SH7751_PCICONF16_CID 0x000000FF /* Capability Identifier */
123#define SH7751_PCICONF17 0x44 /* PCI Config Reg 17 */
124 #define SH7751_PCICONF17_DATA 0xFF000000 /* Data field for PM */
125 #define SH7751_PCICONF17_PMES 0x00800000 /* PME Status */
126 #define SH7751_PCICONF17_DSCL 0x00600000 /* Data Scaling Value */
127 #define SH7751_PCICONF17_DSEL 0x001E0000 /* Data Select */
128 #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */
129 #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */
130/* SH7715 Internal PCI Registers */
131#define SH7751_PCICR 0x100 /* PCI Control Register */
132 #define SH7751_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
133 #define SH7751_PCICR_TRSB 0x00000200 /* Target Read Single */
134 #define SH7751_PCICR_BSWP 0x00000100 /* Target Byte Swap */
135 #define SH7751_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */
136 #define SH7751_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */
137 #define SH7751_PCICR_MD 0x00000030 /* MD9 and MD10 status */
138 #define SH7751_PCICR_SERR 0x00000008 /* SERR output assert */
139 #define SH7751_PCICR_INTA 0x00000004 /* INTA output assert */
140 #define SH7751_PCICR_PRST 0x00000002 /* PCI Reset Assert */
141 #define SH7751_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */
142#define SH7751_PCILSR0 0x104 /* PCI Local Space Register0 */
143#define SH7751_PCILSR1 0x108 /* PCI Local Space Register1 */
144#define SH7751_PCILAR0 0x10C /* PCI Local Address Register1 */
145#define SH7751_PCILAR1 0x110 /* PCI Local Address Register1 */
146#define SH7751_PCIINT 0x114 /* PCI Interrupt Register */
147 #define SH7751_PCIINT_MLCK 0x00008000 /* Master Lock Error */
148 #define SH7751_PCIINT_TABT 0x00004000 /* Target Abort Error */
149 #define SH7751_PCIINT_TRET 0x00000200 /* Target Retry Error */
150 #define SH7751_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */
151 #define SH7751_PCIINT_PRTY 0x00000080 /* Address Parity Error */
152 #define SH7751_PCIINT_SERR 0x00000040 /* SERR Detection Error */
153 #define SH7751_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */
154 #define SH7751_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Error Det. */
155 #define SH7751_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */
156 #define SH7751_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */
157 #define SH7751_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */
158 #define SH7751_PCIINT_MRPD 0x00000002 /* Master Read PERR Detect */
159#define SH7751_PCIINTM 0x118 /* PCI Interrupt Mask Register */
160#define SH7751_PCIALR 0x11C /* Error Address Register */
161#define SH7751_PCICLR 0x120 /* Error Command/Data Register */
162 #define SH7751_PCICLR_MPIO 0x80000000 /* Error Command/Data Register */
163 #define SH7751_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */
164 #define SH7751_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */
165 #define SH7751_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */
166 #define SH7751_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */
167 #define SH7751_PCICLR_TGT 0x04000000 /* Target Transfer Error */
168 #define SH7751_PCICLR_CMDL 0x0000000F /* PCI Command at Error */
169#define SH7751_PCIAINT 0x130 /* Arbiter Interrupt Register */
170 #define SH7751_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */
171 #define SH7751_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */
172 #define SH7751_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */
173 #define SH7751_PCIAINT_TABT 0x00000008 /* Target Abort */
174 #define SH7751_PCIAINT_MABT 0x00000004 /* Master Abort */
175 #define SH7751_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */
176 #define SH7751_PCIAINT_WDPE 0x00000002 /* Write Data Parity Error */
177#define SH7751_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
178#define SH7751_PCIBMLR 0x138 /* Error Bus Master Register */
179 #define SH7751_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */
180 #define SH7751_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */
181 #define SH7751_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */
182 #define SH7751_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */
183 #define SH7751_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */
184#define SH7751_PCIDMABT 0x140 /* DMA Transfer Arb. Register */
185 #define SH7751_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */
186#define SH7751_PCIDPA0 0x180 /* DMA0 Transfer Addr. Register */
187#define SH7751_PCIDLA0 0x184 /* DMA0 Local Addr. Register */
188#define SH7751_PCIDTC0 0x188 /* DMA0 Transfer Cnt. Register */
189#define SH7751_PCIDCR0 0x18C /* DMA0 Control Register */
190 #define SH7751_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */
191 #define SH7751_PCIDCR_MAST 0x00000100 /* DMA Termination Type */
192 #define SH7751_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/
193 #define SH7751_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */
194 #define SH7751_PCIDCR_LHLD 0x00000020 /* Local Address Control */
195 #define SH7751_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/
196 #define SH7751_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */
197 #define SH7751_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */
198 #define SH7751_PCIDCR_STOP 0x00000002 /* Force DMA Stop */
199 #define SH7751_PCIDCR_STRT 0x00000001 /* DMA Start */
200#define SH7751_PCIDPA1 0x190 /* DMA1 Transfer Addr. Register */
201#define SH7751_PCIDLA1 0x194 /* DMA1 Local Addr. Register */
202#define SH7751_PCIDTC1 0x198 /* DMA1 Transfer Cnt. Register */
203#define SH7751_PCIDCR1 0x19C /* DMA1 Control Register */
204#define SH7751_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. Register */
205#define SH7751_PCIDLA2 0x1A4 /* DMA2 Local Addr. Register */
206#define SH7751_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. Register */
207#define SH7751_PCIDCR2 0x1AC /* DMA2 Control Register */
208#define SH7751_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. Register */
209#define SH7751_PCIDLA3 0x1B4 /* DMA3 Local Addr. Register */
210#define SH7751_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. Register */
211#define SH7751_PCIDCR3 0x1BC /* DMA3 Control Register */
212#define SH7751_PCIPAR 0x1C0 /* PIO Address Register */
213 #define SH7751_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */
214 #define SH7751_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */
215 #define SH7751_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */
216 #define SH7751_PCIPAR_REGAD 0x000000FC /* Register Address Number */
217#define SH7751_PCIMBR 0x1C4 /* Memory Base Address Register */
218 #define SH7751_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */
219 #define SH7751_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */
220#define SH7751_PCIIOBR 0x1C8 /* I/O Base Address Register */
221 #define SH7751_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */
222 #define SH7751_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */
223#define SH7751_PCIPINT 0x1CC /* Power Mgmnt Int. Register */
224 #define SH7751_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */
225 #define SH7751_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */
226#define SH7751_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */
227#define SH7751_PCICLKR 0x1D4 /* Clock Ctrl. Register */
228 #define SH7751_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */
229 #define SH7751_PCICLKR_BCSTP 0x00000002 /* BCLK Clock Stop */
230/* For definitions of BCR, MCR see ... */
231#define SH7751_PCIBCR1 0x1E0 /* Memory BCR1 Register */
232#define SH7751_PCIBCR2 0x1E4 /* Memory BCR2 Register */
233#define SH7751_PCIWCR1 0x1E8 /* Wait Control 1 Register */
234#define SH7751_PCIWCR2 0x1EC /* Wait Control 2 Register */
235#define SH7751_PCIWCR3 0x1F0 /* Wait Control 3 Register */
236#define SH7751_PCIMCR 0x1F4 /* Memory Control Register */
237#define SH7751_PCIBCR3 0x1f8 /* Memory BCR3 Register */
238#define SH7751_PCIPCTR 0x200 /* Port Control Register */
239 #define SH7751_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */
240 #define SH7751_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */
241 #define SH7751_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */
242 #define SH7751_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */
243 #define SH7751_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */
244 #define SH7751_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */
245 #define SH7751_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */
246 #define SH7751_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */
247 #define SH7751_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */
248#define SH7751_PCIPDTR 0x204 /* Port Data Register */
249 #define SH7751_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */
250 #define SH7751_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */
251 #define SH7751_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */
252 #define SH7751_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */
253 #define SH7751_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */
254 #define SH7751_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */
255#define SH7751_PCIPDR 0x220 /* Port IO Data Register */
256
257/* Memory Control Registers */
258#define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */
259#define SH7751_BCR2 0xFF800004 /* Memory BCR2 Register */
260#define SH7751_BCR3 0xFF800050 /* Memory BCR3 Register */
261#define SH7751_BCR4 0xFE0A00F0 /* Memory BCR4 Register */
262#define SH7751_WCR1 0xFF800008 /* Wait Control 1 Register */
263#define SH7751_WCR2 0xFF80000C /* Wait Control 2 Register */
264#define SH7751_WCR3 0xFF800010 /* Wait Control 3 Register */
265#define SH7751_MCR 0xFF800014 /* Memory Control Register */
266
267/* General Memory Config Addresses */
268#define SH7751_CS0_BASE_ADDR 0x0
269#define SH7751_MEM_REGION_SIZE 0x04000000
270#define SH7751_CS1_BASE_ADDR (SH7751_CS0_BASE_ADDR + SH7751_MEM_REGION_SIZE)
271#define SH7751_CS2_BASE_ADDR (SH7751_CS1_BASE_ADDR + SH7751_MEM_REGION_SIZE)
272#define SH7751_CS3_BASE_ADDR (SH7751_CS2_BASE_ADDR + SH7751_MEM_REGION_SIZE)
273#define SH7751_CS4_BASE_ADDR (SH7751_CS3_BASE_ADDR + SH7751_MEM_REGION_SIZE)
274#define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
275#define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
276
277/* General PCI values */
278#define SH7751_PCI_HOST_BRIDGE 0x6
279
280/* Flags */
281#define SH7751_PCIC_NO_RESET 0x0001
282
283/* External functions defined per platform i.e. Big Sur, SE... (these could be routed
284 * through the machine vectors... */
285extern int pcibios_init_platform(void);
286extern int pcibios_map_platform_irq(u8 slot, u8 pin);
287
288struct sh7751_pci_address_space {
289 unsigned long base;
290 unsigned long size;
291};
292
293struct sh7751_pci_address_map {
294 struct sh7751_pci_address_space window0;
295 struct sh7751_pci_address_space window1;
296 unsigned long flags;
297};
298
299/* arch/sh/drivers/pci/pci-sh7751.c */
300extern int sh7751_pcic_init(struct sh7751_pci_address_map *map);
301
302#endif /* _PCI_SH7751_H_ */
303
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
new file mode 100644
index 000000000000..cb6752131156
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -0,0 +1,509 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Support functions for the ST40 PCI hardware.
8 */
9
10#include <linux/config.h>
11#include <linux/kernel.h>
12#include <linux/smp.h>
13#include <linux/smp_lock.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18#include <linux/types.h>
19#include <asm/pci.h>
20#include <linux/irq.h>
21#include <linux/interrupt.h> /* irqreturn_t */
22
23#include "pci-st40.h"
24
25/* This is in P2 of course */
26#define ST40PCI_BASE_ADDRESS (0xb0000000)
27#define ST40PCI_MEM_ADDRESS (ST40PCI_BASE_ADDRESS+0x0)
28#define ST40PCI_IO_ADDRESS (ST40PCI_BASE_ADDRESS+0x06000000)
29#define ST40PCI_REG_ADDRESS (ST40PCI_BASE_ADDRESS+0x07000000)
30
31#define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
32#define ST40PCI_REG_INDEXED(reg, index) \
33 (ST40PCI_REG(reg##0) + \
34 ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index))
35
36#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
37#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
38#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
39#define ST40PCI_WRITE_INDEXED(reg, index, val) \
40 writel((val), ST40PCI_REG_INDEXED(reg, index));
41
42#define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
43#define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
44#define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
45
46#define ST40PCI_SERR_IRQ 64
47#define ST40PCI_ERR_IRQ 65
48
49
50/* Macros to extract PLL params */
51#define PLL_MDIV(reg) ( ((unsigned)reg) & 0xff )
52#define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
53#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
54#define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
55
56/* Build up the appropriate settings */
57#define PLL_SET(mdiv,ndiv,pdiv,setup) \
58( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
59
60#define PLLPCICR (0xbb040000+0x10)
61
62#define PLLPCICR_POWERON (1<<28)
63#define PLLPCICR_OUT_EN (1<<29)
64#define PLLPCICR_LOCKSELECT (1<<30)
65#define PLLPCICR_LOCK (1<<31)
66
67
68#define PLL_25MHZ 0x793c8512
69#define PLL_33MHZ PLL_SET(18,88,3,295)
70
71static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
72 unsigned long pciOffset, unsigned long regionSize);
73
74/*
75 * The pcibios_map_platform_irq function is defined in the appropriate
76 * board specific code and referenced here
77 */
78extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
79
80static __init void SetPCIPLL(void)
81{
82 {
83 /* Lets play with the PLL values */
84 unsigned long pll1cr1;
85 unsigned long mdiv, ndiv, pdiv;
86 unsigned long muxcr;
87 unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 };
88 unsigned int freq;
89
90#define CLKGENA 0xbb040000
91#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48
92 pll1cr1 = ctrl_inl(PLLPCICR);
93 printk("PLL1CR1 %08lx\n", pll1cr1);
94 mdiv = PLL_MDIV(pll1cr1);
95 ndiv = PLL_NDIV(pll1cr1);
96 pdiv = PLL_PDIV(pll1cr1);
97 printk("mdiv %02lx ndiv %02lx pdiv %02lx\n", mdiv, ndiv, pdiv);
98 freq = ((2*27*ndiv)/mdiv) / (1 << pdiv);
99 printk("PLL freq %dMHz\n", freq);
100 muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR);
101 printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]);
102 }
103}
104
105
106struct pci_err {
107 unsigned mask;
108 const char *error_string;
109};
110
111static struct pci_err int_error[]={
112 { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"},
113 { INT_TTADI, "TTADI: Illegal byte enable in I/O transfer"},
114 { INT_TMTO, "TMTO: Target memory read/write timeout"},
115 { INT_MDEI, "MDEI: Master function disable error"},
116 { INT_APEDI, "APEDI: Address parity error"},
117 { INT_SDI, "SDI: SERR detected"},
118 { INT_DPEITW, "DPEITW: Data parity error target write"},
119 { INT_PEDITR, "PEDITR: PERR detected"},
120 { INT_TADIM, "TADIM: Target abort detected"},
121 { INT_MADIM, "MADIM: Master abort detected"},
122 { INT_MWPDI, "MWPDI: PERR from target at data write"},
123 { INT_MRDPEI, "MRDPEI: Master read data parity error"}
124};
125#define NUM_PCI_INT_ERRS (sizeof(int_error)/sizeof(struct pci_err))
126
127static struct pci_err aint_error[]={
128 { AINT_MBI, "MBI: Master broken"},
129 { AINT_TBTOI, "TBTOI: Target bus timeout"},
130 { AINT_MBTOI, "MBTOI: Master bus timeout"},
131 { AINT_TAI, "TAI: Target abort"},
132 { AINT_MAI, "MAI: Master abort"},
133 { AINT_RDPEI, "RDPEI: Read data parity"},
134 { AINT_WDPE, "WDPE: Write data parity"}
135};
136
137#define NUM_PCI_AINT_ERRS (sizeof(aint_error)/sizeof(struct pci_err))
138
139static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors)
140{
141 int i;
142
143 for(i=0;i<num_errors;i++) {
144 if(reg & error[i].mask) {
145 printk("%s\n",error[i].error_string);
146 }
147 }
148
149}
150
151
152static char * pci_commands[16]={
153 "Int Ack",
154 "Special Cycle",
155 "I/O Read",
156 "I/O Write",
157 "Reserved",
158 "Reserved",
159 "Memory Read",
160 "Memory Write",
161 "Reserved",
162 "Reserved",
163 "Configuration Read",
164 "Configuration Write",
165 "Memory Read Multiple",
166 "Dual Address Cycle",
167 "Memory Read Line",
168 "Memory Write-and-Invalidate"
169};
170
171static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs)
172{
173 unsigned pci_int, pci_air, pci_cir, pci_aint;
174 static int count=0;
175
176
177 pci_int = ST40PCI_READ(INT);pci_aint = ST40PCI_READ(AINT);
178 pci_cir = ST40PCI_READ(CIR);pci_air = ST40PCI_READ(AIR);
179
180 /* Reset state to stop multiple interrupts */
181 ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0);
182
183
184 if(++count>1) return IRQ_HANDLED;
185
186 printk("** PCI ERROR **\n");
187
188 if(pci_int) {
189 printk("** INT register status\n");
190 print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS);
191 }
192
193 if(pci_aint) {
194 printk("** AINT register status\n");
195 print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS);
196 }
197
198 printk("** Address and command info\n");
199
200 printk("** Command %s : Address 0x%x\n",
201 pci_commands[pci_cir&0xf],pci_air);
202
203 if(pci_cir&CIR_PIOTEM) {
204 printk("CIR_PIOTEM:PIO transfer error for master\n");
205 }
206 if(pci_cir&CIR_RWTET) {
207 printk("CIR_RWTET:Read/Write transfer error for target\n");
208 }
209
210 return IRQ_HANDLED;
211}
212
213
214/* Rounds a number UP to the nearest power of two. Used for
215 * sizing the PCI window.
216 */
217static u32 r2p2(u32 num)
218{
219 int i = 31;
220 u32 tmp = num;
221
222 if (num == 0)
223 return 0;
224
225 do {
226 if (tmp & (1 << 31))
227 break;
228 i--;
229 tmp <<= 1;
230 } while (i >= 0);
231
232 tmp = 1 << i;
233 /* If the original number isn't a power of 2, round it up */
234 if (tmp != num)
235 tmp <<= 1;
236
237 return tmp;
238}
239
240static void __init pci_fixup_ide_bases(struct pci_dev *d)
241{
242 int i;
243
244 /*
245 * PCI IDE controllers use non-standard I/O port decoding, respect it.
246 */
247 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
248 return;
249 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
250 for(i=0; i<4; i++) {
251 struct resource *r = &d->resource[i];
252 if ((r->start & ~0x80) == 0x374) {
253 r->start |= 2;
254 r->end = r->start;
255 }
256 }
257}
258DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
259
260int __init st40pci_init(unsigned memStart, unsigned memSize)
261{
262 u32 lsr0;
263
264 SetPCIPLL();
265
266 /* Initialises the ST40 pci subsystem, performing a reset, then programming
267 * up the address space decoders appropriately
268 */
269
270 /* Should reset core here as well methink */
271
272 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_SOFT_RESET);
273
274 /* Loop while core resets */
275 while (ST40PCI_READ(CR) & CR_SOFT_RESET);
276
277 /* Switch off interrupts */
278 ST40PCI_WRITE(INTM, 0);
279 ST40PCI_WRITE(AINT, 0);
280
281 /* Now, lets reset all the cards on the bus with extreme prejudice */
282 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
283 udelay(250);
284
285 /* Set bus active, take it out of reset */
286 ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE);
287
288 /* The PCI spec says that no access must be made to the bus until 1 second
289 * after reset. This seem ludicrously long, but some delay is needed here
290 */
291 mdelay(1000);
292
293 /* Switch off interrupts */
294 ST40PCI_WRITE(INTM, 0);
295 ST40PCI_WRITE(AINT, 0);
296
297 /* Allow it to be a master */
298
299 ST40PCI_WRITE_SHORT(CSR_CMD,
300 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
301 PCI_COMMAND_IO);
302
303 /* Accesse to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
304 * on the PCI bus. This allows a nice 1-1 bus to phys mapping.
305 */
306
307
308 ST40PCI_WRITE(MBR, 0x10000000);
309 /* Always set the max size 128M (actually, it is only 96MB wide) */
310 ST40PCI_WRITE(MBMR, 0x07ff0000);
311
312 /* I/O addresses are mapped at 0xb6000000 -> 0xb7000000. These are changed to 0, to
313 * allow cards that have legacy io such as vga to function correctly. This gives a
314 * maximum of 64K of io/space as only the bottom 16 bits of the address are copied
315 * over to the bus when the transaction is made. 64K of io space is more than enough
316 */
317 ST40PCI_WRITE(IOBR, 0x0);
318 /* Set up the 64K window */
319 ST40PCI_WRITE(IOBMR, 0x0);
320
321 /* Now we set up the mbars so the PCI bus can see the local memory */
322 /* Expose a 256M window starting at PCI address 0... */
323 ST40PCI_WRITE(CSR_MBAR0, 0);
324 ST40PCI_WRITE(LSR0, 0x0fff0001);
325
326 /* ... and set up the initial incomming window to expose all of RAM */
327 pci_set_rbar_region(7, memStart, memStart, memSize);
328
329 /* Maximise timeout values */
330 ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
331 ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
332 ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
333
334 ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING);
335
336 return 1;
337}
338
339char * __init pcibios_setup(char *str)
340{
341 return str;
342}
343
344
345#define SET_CONFIG_BITS(bus,devfn,where)\
346 (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
347
348#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
349
350
351static int CheckForMasterAbort(void)
352{
353 if (ST40PCI_READ(INT) & INT_MADIM) {
354 /* Should we clear config space version as well ??? */
355 ST40PCI_WRITE(INT, INT_MADIM);
356 ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
357 return 1;
358 }
359
360 return 0;
361}
362
363/* Write to config register */
364static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
365{
366 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
367 switch (size) {
368 case 1:
369 *val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
370 break;
371 case 2:
372 *val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
373 break;
374 case 4:
375 *val = ST40PCI_READ(PDR);
376 break;
377 }
378
379 if (CheckForMasterAbort()){
380 switch (size) {
381 case 1:
382 *val = (u8)0xff;
383 break;
384 case 2:
385 *val = (u16)0xffff;
386 break;
387 case 4:
388 *val = 0xffffffff;
389 break;
390 }
391 }
392
393 return PCIBIOS_SUCCESSFUL;
394}
395
396static int st40pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
397{
398 ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
399
400 switch (size) {
401 case 1:
402 ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
403 break;
404 case 2:
405 ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
406 break;
407 case 4:
408 ST40PCI_WRITE(PDR, val);
409 break;
410 }
411
412 CheckForMasterAbort();
413
414 return PCIBIOS_SUCCESSFUL;
415}
416
417struct pci_ops st40pci_config_ops = {
418 .read = st40pci_read,
419 .write = st40pci_write,
420};
421
422
423/* Everything hangs off this */
424static struct pci_bus *pci_root_bus;
425
426
427static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
428{
429 return PCI_SLOT(dev->devfn);
430}
431
432
433static int __init pcibios_init(void)
434{
435 extern unsigned long memory_start, memory_end;
436
437 printk(KERN_ALERT "pci-st40.c: pcibios_init\n");
438
439 if (sh_mv.mv_init_pci != NULL) {
440 sh_mv.mv_init_pci();
441 }
442
443 /* The pci subsytem needs to know where memory is and how much
444 * of it there is. I've simply made these globals. A better mechanism
445 * is probably needed.
446 */
447 st40pci_init(PHYSADDR(memory_start),
448 PHYSADDR(memory_end) - PHYSADDR(memory_start));
449
450 if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq,
451 SA_INTERRUPT, "st40pci", NULL)) {
452 printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
453 return -EIO;
454 }
455
456 /* Enable the PCI interrupts on the device */
457 ST40PCI_WRITE(INTM, ~0);
458 ST40PCI_WRITE(AINT, ~0);
459
460 /* Map the io address apprioately */
461#ifdef CONFIG_HD64465
462 hd64465_port_map(PCIBIOS_MIN_IO, (64 * 1024) - PCIBIOS_MIN_IO + 1,
463 ST40_IO_ADDR + PCIBIOS_MIN_IO, 0);
464#endif
465
466 /* ok, do the scan man */
467 pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL);
468 pci_assign_unassigned_resources();
469 pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq);
470
471 return 0;
472}
473
474subsys_initcall(pcibios_init);
475
476void __init pcibios_fixup_bus(struct pci_bus *bus)
477{
478}
479
480/*
481 * Publish a region of local address space over the PCI bus
482 * to other devices.
483 */
484static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
485 unsigned long pciOffset, unsigned long regionSize)
486{
487 unsigned long mask;
488
489 if (region > 7)
490 return;
491
492 if (regionSize > (512 * 1024 * 1024))
493 return;
494
495 mask = r2p2(regionSize) - 0x10000;
496
497 /* Diable the region (in case currently in use, should never happen) */
498 ST40PCI_WRITE_INDEXED(RSR, region, 0);
499
500 /* Start of local address space to publish */
501 ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) );
502
503 /* Start of region in PCI address space as an offset from MBAR0 */
504 ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset);
505
506 /* Size of region */
507 ST40PCI_WRITE_INDEXED(RSR, region, mask | 1);
508}
509
diff --git a/arch/sh/drivers/pci/pci-st40.h b/arch/sh/drivers/pci/pci-st40.h
new file mode 100644
index 000000000000..d729e0c2d5fe
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-st40.h
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Defintions for the ST40 PCI hardware.
8 */
9
10#ifndef __PCI_ST40_H__
11#define __PCI_ST40_H__
12
13#define ST40PCI_VCR_STATUS 0x00
14
15#define ST40PCI_VCR_VERSION 0x08
16
17#define ST40PCI_CR 0x10
18
19#define CR_SOFT_RESET (1<<12)
20#define CR_PFCS (1<<11)
21#define CR_PFE (1<<9)
22#define CR_BMAM (1<<6)
23#define CR_HOST (1<<5)
24#define CR_CLKEN (1<<4)
25#define CR_SOCS (1<<3)
26#define CR_IOCS (1<<2)
27#define CR_RSTCTL (1<<1)
28#define CR_CFINT (1<<0)
29#define CR_LOCK_MASK 0x5a000000
30
31
32#define ST40PCI_LSR0 0X14
33#define ST40PCI_LAR0 0x1c
34
35#define ST40PCI_INT 0x24
36#define INT_MNLTDIM (1<<15)
37#define INT_TTADI (1<<14)
38#define INT_TMTO (1<<9)
39#define INT_MDEI (1<<8)
40#define INT_APEDI (1<<7)
41#define INT_SDI (1<<6)
42#define INT_DPEITW (1<<5)
43#define INT_PEDITR (1<<4)
44#define INT_TADIM (1<<3)
45#define INT_MADIM (1<<2)
46#define INT_MWPDI (1<<1)
47#define INT_MRDPEI (1<<0)
48
49
50#define ST40PCI_INTM 0x28
51#define ST40PCI_AIR 0x2c
52
53#define ST40PCI_CIR 0x30
54#define CIR_PIOTEM (1<<31)
55#define CIR_RWTET (1<<26)
56
57#define ST40PCI_AINT 0x40
58#define AINT_MBI (1<<13)
59#define AINT_TBTOI (1<<12)
60#define AINT_MBTOI (1<<11)
61#define AINT_TAI (1<<3)
62#define AINT_MAI (1<<2)
63#define AINT_RDPEI (1<<1)
64#define AINT_WDPE (1<<0)
65
66#define ST40PCI_AINTM 0x44
67#define ST40PCI_BMIR 0x48
68#define ST40PCI_PAR 0x4c
69#define ST40PCI_MBR 0x50
70#define ST40PCI_IOBR 0x54
71#define ST40PCI_PINT 0x58
72#define ST40PCI_PINTM 0x5c
73#define ST40PCI_MBMR 0x70
74#define ST40PCI_IOBMR 0x74
75#define ST40PCI_PDR 0x78
76
77/* H8 specific registers start here */
78#define ST40PCI_WCBAR 0x7c
79#define ST40PCI_LOCCFG_UNLOCK 0x34
80
81#define ST40PCI_RBAR0 0x100
82#define ST40PCI_RSR0 0x104
83#define ST40PCI_RLAR0 0x108
84
85#define ST40PCI_RBAR1 0x110
86#define ST40PCI_RSR1 0x114
87#define ST40PCI_RLAR1 0x118
88
89
90#define ST40PCI_RBAR2 0x120
91#define ST40PCI_RSR2 0x124
92#define ST40PCI_RLAR2 0x128
93
94#define ST40PCI_RBAR3 0x130
95#define ST40PCI_RSR3 0x134
96#define ST40PCI_RLAR3 0x138
97
98#define ST40PCI_RBAR4 0x140
99#define ST40PCI_RSR4 0x144
100#define ST40PCI_RLAR4 0x148
101
102#define ST40PCI_RBAR5 0x150
103#define ST40PCI_RSR5 0x154
104#define ST40PCI_RLAR5 0x158
105
106#define ST40PCI_RBAR6 0x160
107#define ST40PCI_RSR6 0x164
108#define ST40PCI_RLAR6 0x168
109
110#define ST40PCI_RBAR7 0x170
111#define ST40PCI_RSR7 0x174
112#define ST40PCI_RLAR7 0x178
113
114
115#define ST40PCI_RBAR(n) (0x100+(0x10*(n)))
116#define ST40PCI_RSR(n) (0x104+(0x10*(n)))
117#define ST40PCI_RLAR(n) (0x108+(0x10*(n)))
118
119#define ST40PCI_PERF 0x80
120#define PERF_MASTER_WRITE_POSTING (1<<4)
121/* H8 specific registers end here */
122
123
124/* These are configs space registers */
125#define ST40PCI_CSR_VID 0x10000
126#define ST40PCI_CSR_DID 0x10002
127#define ST40PCI_CSR_CMD 0x10004
128#define ST40PCI_CSR_STATUS 0x10006
129#define ST40PCI_CSR_MBAR0 0x10010
130#define ST40PCI_CSR_TRDY 0x10040
131#define ST40PCI_CSR_RETRY 0x10041
132#define ST40PCI_CSR_MIT 0x1000d
133
134#define ST40_IO_ADDR 0xb6000000
135
136#endif /* __PCI_ST40_H__ */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
new file mode 100644
index 000000000000..c1669905abe4
--- /dev/null
+++ b/arch/sh/drivers/pci/pci.c
@@ -0,0 +1,155 @@
1/* arch/sh/kernel/pci.c
2 * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $
3 *
4 * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org>
5 *
6 *
7 * These functions are collected here to reduce duplication of common
8 * code amongst the many platform-specific PCI support code files.
9 *
10 * These routines require the following board-specific routines:
11 * void pcibios_fixup_irqs();
12 *
13 * See include/asm-sh/pci.h for more information.
14 */
15
16#include <linux/kernel.h>
17#include <linux/pci.h>
18#include <linux/init.h>
19
20static int __init pcibios_init(void)
21{
22 struct pci_channel *p;
23 struct pci_bus *bus;
24 int busno;
25
26#ifdef CONFIG_PCI_AUTO
27 /* assign resources */
28 busno = 0;
29 for (p = board_pci_channels; p->pci_ops != NULL; p++) {
30 busno = pciauto_assign_resources(busno, p) + 1;
31 }
32#endif
33
34 /* scan the buses */
35 busno = 0;
36 for (p= board_pci_channels; p->pci_ops != NULL; p++) {
37 bus = pci_scan_bus(busno, p->pci_ops, p);
38 busno = bus->subordinate+1;
39 }
40
41 /* board-specific fixups */
42 pcibios_fixup_irqs();
43
44 return 0;
45}
46
47subsys_initcall(pcibios_init);
48
49void
50pcibios_update_resource(struct pci_dev *dev, struct resource *root,
51 struct resource *res, int resource)
52{
53 u32 new, check;
54 int reg;
55
56 new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
57 if (resource < 6) {
58 reg = PCI_BASE_ADDRESS_0 + 4*resource;
59 } else if (resource == PCI_ROM_RESOURCE) {
60 res->flags |= IORESOURCE_ROM_ENABLE;
61 new |= PCI_ROM_ADDRESS_ENABLE;
62 reg = dev->rom_base_reg;
63 } else {
64 /* Somebody might have asked allocation of a non-standard resource */
65 return;
66 }
67
68 pci_write_config_dword(dev, reg, new);
69 pci_read_config_dword(dev, reg, &check);
70 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
71 printk(KERN_ERR "PCI: Error while updating region "
72 "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
73 new, check);
74 }
75}
76
77void pcibios_align_resource(void *data, struct resource *res,
78 unsigned long size, unsigned long align)
79 __attribute__ ((weak));
80
81/*
82 * We need to avoid collisions with `mirrored' VGA ports
83 * and other strange ISA hardware, so we always want the
84 * addresses to be allocated in the 0x000-0x0ff region
85 * modulo 0x400.
86 */
87void pcibios_align_resource(void *data, struct resource *res,
88 unsigned long size, unsigned long align)
89{
90 if (res->flags & IORESOURCE_IO) {
91 unsigned long start = res->start;
92
93 if (start & 0x300) {
94 start = (start + 0x3ff) & ~0x3ff;
95 res->start = start;
96 }
97 }
98}
99
100int pcibios_enable_device(struct pci_dev *dev, int mask)
101{
102 u16 cmd, old_cmd;
103 int idx;
104 struct resource *r;
105
106 pci_read_config_word(dev, PCI_COMMAND, &cmd);
107 old_cmd = cmd;
108 for(idx=0; idx<6; idx++) {
109 if (!(mask & (1 << idx)))
110 continue;
111 r = &dev->resource[idx];
112 if (!r->start && r->end) {
113 printk(KERN_ERR "PCI: Device %s not available because "
114 "of resource collisions\n", pci_name(dev));
115 return -EINVAL;
116 }
117 if (r->flags & IORESOURCE_IO)
118 cmd |= PCI_COMMAND_IO;
119 if (r->flags & IORESOURCE_MEM)
120 cmd |= PCI_COMMAND_MEMORY;
121 }
122 if (dev->resource[PCI_ROM_RESOURCE].start)
123 cmd |= PCI_COMMAND_MEMORY;
124 if (cmd != old_cmd) {
125 printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n",
126 pci_name(dev), old_cmd, cmd);
127 pci_write_config_word(dev, PCI_COMMAND, cmd);
128 }
129 return 0;
130}
131
132/*
133 * If we set up a device for bus mastering, we need to check and set
134 * the latency timer as it may not be properly set.
135 */
136unsigned int pcibios_max_latency = 255;
137
138void pcibios_set_master(struct pci_dev *dev)
139{
140 u8 lat;
141 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
142 if (lat < 16)
143 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
144 else if (lat > pcibios_max_latency)
145 lat = pcibios_max_latency;
146 else
147 return;
148 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
149 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
150}
151
152void __init pcibios_update_irq(struct pci_dev *dev, int irq)
153{
154 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
155}
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
new file mode 100644
index 000000000000..8b819698df14
--- /dev/null
+++ b/arch/sh/kernel/Makefile
@@ -0,0 +1,22 @@
1#
2# Makefile for the Linux/SuperH kernel.
3#
4
5extra-y := head.o init_task.o vmlinux.lds
6
7obj-y := process.o signal.o entry.o traps.o irq.o \
8 ptrace.o setup.o time.o sys_sh.o semaphore.o \
9 io.o io_generic.o sh_ksyms.o
10
11obj-y += cpu/
12
13obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
15obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
16obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
17obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
18obj-$(CONFIG_MODULES) += module.o
19obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
20
21USE_STANDARD_AS_RULE := true
22
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c
new file mode 100644
index 000000000000..dc6725c51a89
--- /dev/null
+++ b/arch/sh/kernel/asm-offsets.c
@@ -0,0 +1,32 @@
1/*
2 * This program is used to generate definitions needed by
3 * assembly language modules.
4 *
5 * We use the technique used in the OSF Mach kernel code:
6 * generate asm statements containing #defines,
7 * compile this file to assembler, and then extract the
8 * #defines from the assembly-language output.
9 */
10
11#include <linux/stddef.h>
12#include <linux/types.h>
13#include <linux/mm.h>
14#include <asm/thread_info.h>
15
16#define DEFINE(sym, val) \
17 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
18
19#define BLANK() asm volatile("\n->" : : )
20
21int main(void)
22{
23 /* offsets into the thread_info struct */
24 DEFINE(TI_TASK, offsetof(struct thread_info, task));
25 DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
26 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
27 DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
28 DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
29 DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
30
31 return 0;
32}
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
new file mode 100644
index 000000000000..7a3b18faa277
--- /dev/null
+++ b/arch/sh/kernel/cf-enabler.c
@@ -0,0 +1,158 @@
1/* $Id: cf-enabler.c,v 1.4 2004/02/22 22:44:36 kkojima Exp $
2 *
3 * linux/drivers/block/cf-enabler.c
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2000 Toshiharu Nozawa
7 * Copyright (C) 2001 A&D Co., Ltd.
8 *
9 * Enable the CF configuration.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14
15#include <asm/io.h>
16#include <asm/irq.h>
17
18/*
19 * You can connect Compact Flash directly to the bus of SuperH.
20 * This is the enabler for that.
21 *
22 * SIM: How generic is this really? It looks pretty board, or at
23 * least SH sub-type, specific to me.
24 * I know it doesn't work on the Overdrive!
25 */
26
27/*
28 * 0xB8000000 : Attribute
29 * 0xB8001000 : Common Memory
30 * 0xBA000000 : I/O
31 */
32#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4)
33/* SH4 can't access PCMCIA interface through P2 area.
34 * we must remap it with appropreate attribute bit of the page set.
35 * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
36#include <linux/mm.h>
37#include <linux/vmalloc.h>
38
39#if defined(CONFIG_CF_AREA6)
40#define slot_no 0
41#else
42#define slot_no 1
43#endif
44
45/* defined in mm/ioremap.c */
46extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
47
48/* use this pointer to access to directly connected compact flash io area*/
49void *cf_io_base;
50
51static int __init allocate_cf_area(void)
52{
53 pgprot_t prot;
54 unsigned long paddrbase, psize;
55
56 /* open I/O area window */
57 paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR);
58 psize = PAGE_SIZE;
59 prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16);
60 cf_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
61 if (!cf_io_base) {
62 printk("allocate_cf_area : can't open CF I/O window!\n");
63 return -ENOMEM;
64 }
65/* printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n",
66 paddrbase, psize, prot.pgprot, cf_io_base);*/
67
68 /* XXX : do we need attribute and common-memory area also? */
69
70 return 0;
71}
72#endif
73
74static int __init cf_init_default(void)
75{
76/* You must have enabled the card, and set the level interrupt
77 * before reaching this point. Possibly in boot ROM or boot loader.
78 */
79#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4)
80 allocate_cf_area();
81#endif
82#if defined(CONFIG_SH_UNKNOWN)
83 /* This should be done in each board's init_xxx_irq. */
84 make_imask_irq(14);
85 disable_irq(14);
86#endif
87 return 0;
88}
89
90#if defined(CONFIG_SH_SOLUTION_ENGINE)
91#include <asm/se/se.h>
92
93/*
94 * SolutionEngine
95 *
96 * 0xB8400000 : Common Memory
97 * 0xB8500000 : Attribute
98 * 0xB8600000 : I/O
99 */
100
101static int __init cf_init_se(void)
102{
103 if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
104 return 0; /* Not detected */
105
106 if ((ctrl_inw(MRSHPC_CSR) & 0x0080) == 0) {
107 ctrl_outw(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
108 } else {
109 ctrl_outw(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
110 }
111
112 /*
113 * PC-Card window open
114 * flag == COMMON/ATTRIBUTE/IO
115 */
116 /* common window open */
117 ctrl_outw(0x8a84, MRSHPC_MW0CR1);/* window 0xb8400000 */
118 if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
119 /* common mode & bus width 16bit SWAP = 1*/
120 ctrl_outw(0x0b00, MRSHPC_MW0CR2);
121 else
122 /* common mode & bus width 16bit SWAP = 0*/
123 ctrl_outw(0x0300, MRSHPC_MW0CR2);
124
125 /* attribute window open */
126 ctrl_outw(0x8a85, MRSHPC_MW1CR1);/* window 0xb8500000 */
127 if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
128 /* attribute mode & bus width 16bit SWAP = 1*/
129 ctrl_outw(0x0a00, MRSHPC_MW1CR2);
130 else
131 /* attribute mode & bus width 16bit SWAP = 0*/
132 ctrl_outw(0x0200, MRSHPC_MW1CR2);
133
134 /* I/O window open */
135 ctrl_outw(0x8a86, MRSHPC_IOWCR1);/* I/O window 0xb8600000 */
136 ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */
137 if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
138 ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
139 else
140 ctrl_outw(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
141
142 ctrl_outw(0x2000, MRSHPC_ICR);
143 ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206);
144 ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
145 return 0;
146}
147#endif
148
149int __init cf_init(void)
150{
151#if defined(CONFIG_SH_SOLUTION_ENGINE)
152 if (MACH_SE)
153 return cf_init_se();
154#endif
155 return cf_init_default();
156}
157
158__initcall (cf_init);
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
new file mode 100644
index 000000000000..cd43714df61a
--- /dev/null
+++ b/arch/sh/kernel/cpu/Makefile
@@ -0,0 +1,16 @@
1#
2# Makefile for the Linux/SuperH CPU-specifc backends.
3#
4
5obj-y := irq_ipr.o irq_imask.o init.o bus.o
6
7obj-$(CONFIG_CPU_SH2) += sh2/
8obj-$(CONFIG_CPU_SH3) += sh3/
9obj-$(CONFIG_CPU_SH4) += sh4/
10
11obj-$(CONFIG_SH_RTC) += rtc.o
12obj-$(CONFIG_UBC_WAKEUP) += ubc.o
13obj-$(CONFIG_SH_ADC) += adc.o
14
15USE_STANDARD_AS_RULE := true
16
diff --git a/arch/sh/kernel/cpu/adc.c b/arch/sh/kernel/cpu/adc.c
new file mode 100644
index 000000000000..da3d6877f93d
--- /dev/null
+++ b/arch/sh/kernel/cpu/adc.c
@@ -0,0 +1,36 @@
1/*
2 * linux/arch/sh/kernel/adc.c -- SH3 on-chip ADC support
3 *
4 * Copyright (C) 2004 Andriy Skulysh <askulysh@image.kiev.ua>
5 */
6
7#include <linux/module.h>
8#include <asm/adc.h>
9#include <asm/io.h>
10
11
12int adc_single(unsigned int channel)
13{
14 int off;
15 unsigned char csr;
16
17 if (channel >= 8) return -1;
18
19 off = (channel & 0x03) << 2;
20
21 csr = ctrl_inb(ADCSR);
22 csr = channel | ADCSR_ADST | ADCSR_CKS;
23 ctrl_outb(csr, ADCSR);
24
25 do {
26 csr = ctrl_inb(ADCSR);
27 } while ((csr & ADCSR_ADF) == 0);
28
29 csr &= ~(ADCSR_ADF | ADCSR_ADST);
30 ctrl_outb(csr, ADCSR);
31
32 return (((ctrl_inb(ADDRAH + off) << 8) |
33 ctrl_inb(ADDRAL + off)) >> 6);
34}
35
36EXPORT_SYMBOL(adc_single);
diff --git a/arch/sh/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c
new file mode 100644
index 000000000000..ace82f4b4a59
--- /dev/null
+++ b/arch/sh/kernel/cpu/bus.c
@@ -0,0 +1,195 @@
1/*
2 * arch/sh/kernel/cpu/bus.c
3 *
4 * Virtual bus for SuperH.
5 *
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * Shamelessly cloned from arch/arm/mach-omap/bus.c, which was written
9 * by:
10 *
11 * Copyright (C) 2003 - 2004 Nokia Corporation
12 * Written by Tony Lindgren <tony@atomide.com>
13 * Portions of code based on sa1111.c.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
20#include <linux/kernel.h>
21#include <linux/device.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <asm/bus-sh.h>
25
26static int sh_bus_match(struct device *dev, struct device_driver *drv)
27{
28 struct sh_driver *shdrv = to_sh_driver(drv);
29 struct sh_dev *shdev = to_sh_dev(dev);
30
31 return shdev->dev_id == shdrv->dev_id;
32}
33
34static int sh_bus_suspend(struct device *dev, u32 state)
35{
36 struct sh_dev *shdev = to_sh_dev(dev);
37 struct sh_driver *shdrv = to_sh_driver(dev->driver);
38
39 if (shdrv && shdrv->suspend)
40 return shdrv->suspend(shdev, state);
41
42 return 0;
43}
44
45static int sh_bus_resume(struct device *dev)
46{
47 struct sh_dev *shdev = to_sh_dev(dev);
48 struct sh_driver *shdrv = to_sh_driver(dev->driver);
49
50 if (shdrv && shdrv->resume)
51 return shdrv->resume(shdev);
52
53 return 0;
54}
55
56static struct device sh_bus_devices[SH_NR_BUSES] = {
57 {
58 .bus_id = SH_BUS_NAME_VIRT,
59 },
60};
61
62struct bus_type sh_bus_types[SH_NR_BUSES] = {
63 {
64 .name = SH_BUS_NAME_VIRT,
65 .match = sh_bus_match,
66 .suspend = sh_bus_suspend,
67 .resume = sh_bus_resume,
68 },
69};
70
71static int sh_device_probe(struct device *dev)
72{
73 struct sh_dev *shdev = to_sh_dev(dev);
74 struct sh_driver *shdrv = to_sh_driver(dev->driver);
75
76 if (shdrv && shdrv->probe)
77 return shdrv->probe(shdev);
78
79 return -ENODEV;
80}
81
82static int sh_device_remove(struct device *dev)
83{
84 struct sh_dev *shdev = to_sh_dev(dev);
85 struct sh_driver *shdrv = to_sh_driver(dev->driver);
86
87 if (shdrv && shdrv->remove)
88 return shdrv->remove(shdev);
89
90 return 0;
91}
92
93int sh_device_register(struct sh_dev *dev)
94{
95 if (!dev)
96 return -EINVAL;
97
98 if (dev->bus_id < 0 || dev->bus_id >= SH_NR_BUSES) {
99 printk(KERN_ERR "%s: bus_id invalid: %s bus: %d\n",
100 __FUNCTION__, dev->name, dev->bus_id);
101 return -EINVAL;
102 }
103
104 dev->dev.parent = &sh_bus_devices[dev->bus_id];
105 dev->dev.bus = &sh_bus_types[dev->bus_id];
106
107 /* This is needed for USB OHCI to work */
108 if (dev->dma_mask)
109 dev->dev.dma_mask = dev->dma_mask;
110
111 snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u",
112 dev->name, dev->dev_id);
113
114 printk(KERN_INFO "Registering SH device '%s'. Parent at %s\n",
115 dev->dev.bus_id, dev->dev.parent->bus_id);
116
117 return device_register(&dev->dev);
118}
119
120void sh_device_unregister(struct sh_dev *dev)
121{
122 device_unregister(&dev->dev);
123}
124
125int sh_driver_register(struct sh_driver *drv)
126{
127 if (!drv)
128 return -EINVAL;
129
130 if (drv->bus_id < 0 || drv->bus_id >= SH_NR_BUSES) {
131 printk(KERN_ERR "%s: bus_id invalid: bus: %d device %d\n",
132 __FUNCTION__, drv->bus_id, drv->dev_id);
133 return -EINVAL;
134 }
135
136 drv->drv.probe = sh_device_probe;
137 drv->drv.remove = sh_device_remove;
138 drv->drv.bus = &sh_bus_types[drv->bus_id];
139
140 return driver_register(&drv->drv);
141}
142
143void sh_driver_unregister(struct sh_driver *drv)
144{
145 driver_unregister(&drv->drv);
146}
147
148static int __init sh_bus_init(void)
149{
150 int i, ret = 0;
151
152 for (i = 0; i < SH_NR_BUSES; i++) {
153 ret = device_register(&sh_bus_devices[i]);
154 if (ret != 0) {
155 printk(KERN_ERR "Unable to register bus device %s\n",
156 sh_bus_devices[i].bus_id);
157 continue;
158 }
159
160 ret = bus_register(&sh_bus_types[i]);
161 if (ret != 0) {
162 printk(KERN_ERR "Unable to register bus %s\n",
163 sh_bus_types[i].name);
164 device_unregister(&sh_bus_devices[i]);
165 }
166 }
167
168 printk(KERN_INFO "SH Virtual Bus initialized\n");
169
170 return ret;
171}
172
173static void __exit sh_bus_exit(void)
174{
175 int i;
176
177 for (i = 0; i < SH_NR_BUSES; i++) {
178 bus_unregister(&sh_bus_types[i]);
179 device_unregister(&sh_bus_devices[i]);
180 }
181}
182
183module_init(sh_bus_init);
184module_exit(sh_bus_exit);
185
186MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
187MODULE_DESCRIPTION("SH Virtual Bus");
188MODULE_LICENSE("GPL");
189
190EXPORT_SYMBOL(sh_bus_types);
191EXPORT_SYMBOL(sh_device_register);
192EXPORT_SYMBOL(sh_device_unregister);
193EXPORT_SYMBOL(sh_driver_register);
194EXPORT_SYMBOL(sh_driver_unregister);
195
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
new file mode 100644
index 000000000000..cf94e8ef17c5
--- /dev/null
+++ b/arch/sh/kernel/cpu/init.c
@@ -0,0 +1,222 @@
1/*
2 * arch/sh/kernel/cpu/init.c
3 *
4 * CPU init code
5 *
6 * Copyright (C) 2002, 2003 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <asm/processor.h>
15#include <asm/uaccess.h>
16#include <asm/system.h>
17#include <asm/cacheflush.h>
18#include <asm/cache.h>
19#include <asm/io.h>
20
21extern void detect_cpu_and_cache_system(void);
22
23/*
24 * Generic wrapper for command line arguments to disable on-chip
25 * peripherals (nofpu, nodsp, and so forth).
26 */
27#define onchip_setup(x) \
28static int x##_disabled __initdata = 0; \
29 \
30static int __init x##_setup(char *opts) \
31{ \
32 x##_disabled = 1; \
33 return 0; \
34} \
35__setup("no" __stringify(x), x##_setup);
36
37onchip_setup(fpu);
38onchip_setup(dsp);
39
40/*
41 * Generic first-level cache init
42 */
43static void __init cache_init(void)
44{
45 unsigned long ccr, flags;
46
47 if (cpu_data->type == CPU_SH_NONE)
48 panic("Unknown CPU");
49
50 jump_to_P2();
51 ccr = ctrl_inl(CCR);
52
53 /*
54 * If the cache is already enabled .. flush it.
55 */
56 if (ccr & CCR_CACHE_ENABLE) {
57 unsigned long ways, waysize, addrstart;
58
59 waysize = cpu_data->dcache.sets;
60
61 /*
62 * If the OC is already in RAM mode, we only have
63 * half of the entries to flush..
64 */
65 if (ccr & CCR_CACHE_ORA)
66 waysize >>= 1;
67
68 waysize <<= cpu_data->dcache.entry_shift;
69
70#ifdef CCR_CACHE_EMODE
71 /* If EMODE is not set, we only have 1 way to flush. */
72 if (!(ccr & CCR_CACHE_EMODE))
73 ways = 1;
74 else
75#endif
76 ways = cpu_data->dcache.ways;
77
78 addrstart = CACHE_OC_ADDRESS_ARRAY;
79 do {
80 unsigned long addr;
81
82 for (addr = addrstart;
83 addr < addrstart + waysize;
84 addr += cpu_data->dcache.linesz)
85 ctrl_outl(0, addr);
86
87 addrstart += cpu_data->dcache.way_incr;
88 } while (--ways);
89 }
90
91 /*
92 * Default CCR values .. enable the caches
93 * and invalidate them immediately..
94 */
95 flags = CCR_CACHE_ENABLE | CCR_CACHE_INVALIDATE;
96
97#ifdef CCR_CACHE_EMODE
98 /* Force EMODE if possible */
99 if (cpu_data->dcache.ways > 1)
100 flags |= CCR_CACHE_EMODE;
101#endif
102
103#ifdef CONFIG_SH_WRITETHROUGH
104 /* Turn on Write-through caching */
105 flags |= CCR_CACHE_WT;
106#else
107 /* .. or default to Write-back */
108 flags |= CCR_CACHE_CB;
109#endif
110
111#ifdef CONFIG_SH_OCRAM
112 /* Turn on OCRAM -- halve the OC */
113 flags |= CCR_CACHE_ORA;
114 cpu_data->dcache.sets >>= 1;
115#endif
116
117 ctrl_outl(flags, CCR);
118 back_to_P1();
119}
120
121#ifdef CONFIG_SH_DSP
122static void __init release_dsp(void)
123{
124 unsigned long sr;
125
126 /* Clear SR.DSP bit */
127 __asm__ __volatile__ (
128 "stc\tsr, %0\n\t"
129 "and\t%1, %0\n\t"
130 "ldc\t%0, sr\n\t"
131 : "=&r" (sr)
132 : "r" (~SR_DSP)
133 );
134}
135
136static void __init dsp_init(void)
137{
138 unsigned long sr;
139
140 /*
141 * Set the SR.DSP bit, wait for one instruction, and then read
142 * back the SR value.
143 */
144 __asm__ __volatile__ (
145 "stc\tsr, %0\n\t"
146 "or\t%1, %0\n\t"
147 "ldc\t%0, sr\n\t"
148 "nop\n\t"
149 "stc\tsr, %0\n\t"
150 : "=&r" (sr)
151 : "r" (SR_DSP)
152 );
153
154 /* If the DSP bit is still set, this CPU has a DSP */
155 if (sr & SR_DSP)
156 cpu_data->flags |= CPU_HAS_DSP;
157
158 /* Now that we've determined the DSP status, clear the DSP bit. */
159 release_dsp();
160}
161#endif /* CONFIG_SH_DSP */
162
163/**
164 * sh_cpu_init
165 *
166 * This is our initial entry point for each CPU, and is invoked on the boot
167 * CPU prior to calling start_kernel(). For SMP, a combination of this and
168 * start_secondary() will bring up each processor to a ready state prior
169 * to hand forking the idle loop.
170 *
171 * We do all of the basic processor init here, including setting up the
172 * caches, FPU, DSP, kicking the UBC, etc. By the time start_kernel() is
173 * hit (and subsequently platform_setup()) things like determining the
174 * CPU subtype and initial configuration will all be done.
175 *
176 * Each processor family is still responsible for doing its own probing
177 * and cache configuration in detect_cpu_and_cache_system().
178 */
179asmlinkage void __init sh_cpu_init(void)
180{
181 /* First, probe the CPU */
182 detect_cpu_and_cache_system();
183
184 /* Init the cache */
185 cache_init();
186
187 /* Disable the FPU */
188 if (fpu_disabled) {
189 printk("FPU Disabled\n");
190 cpu_data->flags &= ~CPU_HAS_FPU;
191 disable_fpu();
192 }
193
194 /* FPU initialization */
195 if ((cpu_data->flags & CPU_HAS_FPU)) {
196 clear_thread_flag(TIF_USEDFPU);
197 clear_used_math();
198 }
199
200#ifdef CONFIG_SH_DSP
201 /* Probe for DSP */
202 dsp_init();
203
204 /* Disable the DSP */
205 if (dsp_disabled) {
206 printk("DSP Disabled\n");
207 cpu_data->flags &= ~CPU_HAS_DSP;
208 release_dsp();
209 }
210#endif
211
212#ifdef CONFIG_UBC_WAKEUP
213 /*
214 * Some brain-damaged loaders decided it would be a good idea to put
215 * the UBC to sleep. This causes some issues when it comes to things
216 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So ..
217 * we wake it up and hope that all is well.
218 */
219 ubc_wakeup();
220#endif
221}
222
diff --git a/arch/sh/kernel/cpu/irq_imask.c b/arch/sh/kernel/cpu/irq_imask.c
new file mode 100644
index 000000000000..f76901e732fb
--- /dev/null
+++ b/arch/sh/kernel/cpu/irq_imask.c
@@ -0,0 +1,116 @@
1/* $Id: irq_imask.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $
2 *
3 * linux/arch/sh/kernel/irq_imask.c
4 *
5 * Copyright (C) 1999, 2000 Niibe Yutaka
6 *
7 * Simple interrupt handling using IMASK of SR register.
8 *
9 */
10
11/* NOTE: Will not work on level 15 */
12
13
14#include <linux/ptrace.h>
15#include <linux/errno.h>
16#include <linux/kernel_stat.h>
17#include <linux/signal.h>
18#include <linux/sched.h>
19#include <linux/interrupt.h>
20#include <linux/init.h>
21#include <linux/bitops.h>
22
23#include <asm/system.h>
24#include <asm/irq.h>
25
26#include <linux/spinlock.h>
27#include <linux/cache.h>
28#include <linux/irq.h>
29
30/* Bitmap of IRQ masked */
31static unsigned long imask_mask = 0x7fff;
32static int interrupt_priority = 0;
33
34static void enable_imask_irq(unsigned int irq);
35static void disable_imask_irq(unsigned int irq);
36static void shutdown_imask_irq(unsigned int irq);
37static void mask_and_ack_imask(unsigned int);
38static void end_imask_irq(unsigned int irq);
39
40#define IMASK_PRIORITY 15
41
42static unsigned int startup_imask_irq(unsigned int irq)
43{
44 /* Nothing to do */
45 return 0; /* never anything pending */
46}
47
48static struct hw_interrupt_type imask_irq_type = {
49 "SR.IMASK",
50 startup_imask_irq,
51 shutdown_imask_irq,
52 enable_imask_irq,
53 disable_imask_irq,
54 mask_and_ack_imask,
55 end_imask_irq
56};
57
58void static inline set_interrupt_registers(int ip)
59{
60 unsigned long __dummy;
61
62 asm volatile("ldc %2, r6_bank\n\t"
63 "stc sr, %0\n\t"
64 "and #0xf0, %0\n\t"
65 "shlr2 %0\n\t"
66 "cmp/eq #0x3c, %0\n\t"
67 "bt/s 1f ! CLI-ed\n\t"
68 " stc sr, %0\n\t"
69 "and %1, %0\n\t"
70 "or %2, %0\n\t"
71 "ldc %0, sr\n"
72 "1:"
73 : "=&z" (__dummy)
74 : "r" (~0xf0), "r" (ip << 4)
75 : "t");
76}
77
78static void disable_imask_irq(unsigned int irq)
79{
80 clear_bit(irq, &imask_mask);
81 if (interrupt_priority < IMASK_PRIORITY - irq)
82 interrupt_priority = IMASK_PRIORITY - irq;
83
84 set_interrupt_registers(interrupt_priority);
85}
86
87static void enable_imask_irq(unsigned int irq)
88{
89 set_bit(irq, &imask_mask);
90 interrupt_priority = IMASK_PRIORITY - ffz(imask_mask);
91
92 set_interrupt_registers(interrupt_priority);
93}
94
95static void mask_and_ack_imask(unsigned int irq)
96{
97 disable_imask_irq(irq);
98}
99
100static void end_imask_irq(unsigned int irq)
101{
102 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
103 enable_imask_irq(irq);
104}
105
106static void shutdown_imask_irq(unsigned int irq)
107{
108 /* Nothing to do */
109}
110
111void make_imask_irq(unsigned int irq)
112{
113 disable_irq_nosync(irq);
114 irq_desc[irq].handler = &imask_irq_type;
115 enable_irq(irq);
116}
diff --git a/arch/sh/kernel/cpu/irq_ipr.c b/arch/sh/kernel/cpu/irq_ipr.c
new file mode 100644
index 000000000000..7ea3d2d030e5
--- /dev/null
+++ b/arch/sh/kernel/cpu/irq_ipr.c
@@ -0,0 +1,339 @@
1/* $Id: irq_ipr.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $
2 *
3 * linux/arch/sh/kernel/irq_ipr.c
4 *
5 * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi
6 * Copyright (C) 2000 Kazumoto Kojima
7 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
8 *
9 * Interrupt handling for IPR-based IRQ.
10 *
11 * Supported system:
12 * On-chip supporting modules (TMU, RTC, etc.).
13 * On-chip supporting modules for SH7709/SH7709A/SH7729/SH7300.
14 * Hitachi SolutionEngine external I/O:
15 * MS7709SE01, MS7709ASE01, and MS7750SE01
16 *
17 */
18
19#include <linux/config.h>
20#include <linux/init.h>
21#include <linux/irq.h>
22#include <linux/module.h>
23
24#include <asm/system.h>
25#include <asm/io.h>
26#include <asm/machvec.h>
27
28struct ipr_data {
29 unsigned int addr; /* Address of Interrupt Priority Register */
30 int shift; /* Shifts of the 16-bit data */
31 int priority; /* The priority */
32};
33static struct ipr_data ipr_data[NR_IRQS];
34
35static void enable_ipr_irq(unsigned int irq);
36static void disable_ipr_irq(unsigned int irq);
37
38/* shutdown is same as "disable" */
39#define shutdown_ipr_irq disable_ipr_irq
40
41static void mask_and_ack_ipr(unsigned int);
42static void end_ipr_irq(unsigned int irq);
43
44static unsigned int startup_ipr_irq(unsigned int irq)
45{
46 enable_ipr_irq(irq);
47 return 0; /* never anything pending */
48}
49
50static struct hw_interrupt_type ipr_irq_type = {
51 "IPR-IRQ",
52 startup_ipr_irq,
53 shutdown_ipr_irq,
54 enable_ipr_irq,
55 disable_ipr_irq,
56 mask_and_ack_ipr,
57 end_ipr_irq
58};
59
60static void disable_ipr_irq(unsigned int irq)
61{
62 unsigned long val, flags;
63 unsigned int addr = ipr_data[irq].addr;
64 unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
65
66 /* Set the priority in IPR to 0 */
67 local_irq_save(flags);
68 val = ctrl_inw(addr);
69 val &= mask;
70 ctrl_outw(val, addr);
71 local_irq_restore(flags);
72}
73
74static void enable_ipr_irq(unsigned int irq)
75{
76 unsigned long val, flags;
77 unsigned int addr = ipr_data[irq].addr;
78 int priority = ipr_data[irq].priority;
79 unsigned short value = (priority << ipr_data[irq].shift);
80
81 /* Set priority in IPR back to original value */
82 local_irq_save(flags);
83 val = ctrl_inw(addr);
84 val |= value;
85 ctrl_outw(val, addr);
86 local_irq_restore(flags);
87}
88
89static void mask_and_ack_ipr(unsigned int irq)
90{
91 disable_ipr_irq(irq);
92
93#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
94 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
95 /* This is needed when we use edge triggered setting */
96 /* XXX: Is it really needed? */
97 if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
98 /* Clear external interrupt request */
99 int a = ctrl_inb(INTC_IRR0);
100 a &= ~(1 << (irq - IRQ0_IRQ));
101 ctrl_outb(a, INTC_IRR0);
102 }
103#endif
104}
105
106static void end_ipr_irq(unsigned int irq)
107{
108 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
109 enable_ipr_irq(irq);
110}
111
112void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
113{
114 disable_irq_nosync(irq);
115 ipr_data[irq].addr = addr;
116 ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
117 ipr_data[irq].priority = priority;
118
119 irq_desc[irq].handler = &ipr_irq_type;
120 disable_ipr_irq(irq);
121}
122
123#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
124 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
125 defined(CONFIG_CPU_SUBTYPE_SH7709)
126static unsigned char pint_map[256];
127static unsigned long portcr_mask = 0;
128
129static void enable_pint_irq(unsigned int irq);
130static void disable_pint_irq(unsigned int irq);
131
132/* shutdown is same as "disable" */
133#define shutdown_pint_irq disable_pint_irq
134
135static void mask_and_ack_pint(unsigned int);
136static void end_pint_irq(unsigned int irq);
137
138static unsigned int startup_pint_irq(unsigned int irq)
139{
140 enable_pint_irq(irq);
141 return 0; /* never anything pending */
142}
143
144static struct hw_interrupt_type pint_irq_type = {
145 "PINT-IRQ",
146 startup_pint_irq,
147 shutdown_pint_irq,
148 enable_pint_irq,
149 disable_pint_irq,
150 mask_and_ack_pint,
151 end_pint_irq
152};
153
154static void disable_pint_irq(unsigned int irq)
155{
156 unsigned long val, flags;
157
158 local_irq_save(flags);
159 val = ctrl_inw(INTC_INTER);
160 val &= ~(1 << (irq - PINT_IRQ_BASE));
161 ctrl_outw(val, INTC_INTER); /* disable PINTn */
162 portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2);
163 local_irq_restore(flags);
164}
165
166static void enable_pint_irq(unsigned int irq)
167{
168 unsigned long val, flags;
169
170 local_irq_save(flags);
171 val = ctrl_inw(INTC_INTER);
172 val |= 1 << (irq - PINT_IRQ_BASE);
173 ctrl_outw(val, INTC_INTER); /* enable PINTn */
174 portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2;
175 local_irq_restore(flags);
176}
177
178static void mask_and_ack_pint(unsigned int irq)
179{
180 disable_pint_irq(irq);
181}
182
183static void end_pint_irq(unsigned int irq)
184{
185 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
186 enable_pint_irq(irq);
187}
188
189void make_pint_irq(unsigned int irq)
190{
191 disable_irq_nosync(irq);
192 irq_desc[irq].handler = &pint_irq_type;
193 disable_pint_irq(irq);
194}
195#endif
196
197void __init init_IRQ(void)
198{
199#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
200 defined(CONFIG_CPU_SUBTYPE_SH7707) || \
201 defined(CONFIG_CPU_SUBTYPE_SH7709)
202 int i;
203#endif
204
205 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
206 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
207#if defined(CONFIG_SH_RTC)
208 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
209#endif
210
211#ifdef SCI_ERI_IRQ
212 make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
213 make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
214 make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
215#endif
216
217#ifdef SCIF1_ERI_IRQ
218 make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
219 make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
220 make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
221 make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
222#endif
223
224#if defined(CONFIG_CPU_SUBTYPE_SH7300)
225 make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
226 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
227 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
228 make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
229#endif
230
231#ifdef SCIF_ERI_IRQ
232 make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
233 make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
234 make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
235 make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
236#endif
237
238#ifdef IRDA_ERI_IRQ
239 make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
240 make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
241 make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
242 make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
243#endif
244
245#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
246 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
247 /*
248 * Initialize the Interrupt Controller (INTC)
249 * registers to their power on values
250 */
251
252 /*
253 * Enable external irq (INTC IRQ mode).
254 * You should set corresponding bits of PFC to "00"
255 * to enable these interrupts.
256 */
257 make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
258 make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
259 make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
260 make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
261 make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
262 make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
263#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
264 make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY);
265 make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY);
266 enable_ipr_irq(PINT0_IRQ);
267 enable_ipr_irq(PINT8_IRQ);
268
269 for(i = 0; i < 16; i++)
270 make_pint_irq(PINT_IRQ_BASE + i);
271 for(i = 0; i < 256; i++)
272 {
273 if(i & 1) pint_map[i] = 0;
274 else if(i & 2) pint_map[i] = 1;
275 else if(i & 4) pint_map[i] = 2;
276 else if(i & 8) pint_map[i] = 3;
277 else if(i & 0x10) pint_map[i] = 4;
278 else if(i & 0x20) pint_map[i] = 5;
279 else if(i & 0x40) pint_map[i] = 6;
280 else if(i & 0x80) pint_map[i] = 7;
281 }
282#endif /* !CONFIG_CPU_SUBTYPE_SH7300 */
283#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 || CONFIG_CPU_SUBTYPE_SH7300*/
284
285#ifdef CONFIG_CPU_SUBTYPE_ST40
286 init_IRQ_intc2();
287#endif
288
289 /* Perform the machine specific initialisation */
290 if (sh_mv.mv_init_irq != NULL) {
291 sh_mv.mv_init_irq();
292 }
293}
294#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
295 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
296int ipr_irq_demux(int irq)
297{
298#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
299 unsigned long creg, dreg, d, sav;
300
301 if(irq == PINT0_IRQ)
302 {
303#if defined(CONFIG_CPU_SUBTYPE_SH7707)
304 creg = PORT_PACR;
305 dreg = PORT_PADR;
306#else
307 creg = PORT_PCCR;
308 dreg = PORT_PCDR;
309#endif
310 sav = ctrl_inw(creg);
311 ctrl_outw(sav | portcr_mask, creg);
312 d = (~ctrl_inb(dreg) ^ ctrl_inw(INTC_ICR2)) & ctrl_inw(INTC_INTER) & 0xff;
313 ctrl_outw(sav, creg);
314 if(d == 0) return irq;
315 return PINT_IRQ_BASE + pint_map[d];
316 }
317 else if(irq == PINT8_IRQ)
318 {
319#if defined(CONFIG_CPU_SUBTYPE_SH7707)
320 creg = PORT_PBCR;
321 dreg = PORT_PBDR;
322#else
323 creg = PORT_PFCR;
324 dreg = PORT_PFDR;
325#endif
326 sav = ctrl_inw(creg);
327 ctrl_outw(sav | (portcr_mask >> 16), creg);
328 d = (~ctrl_inb(dreg) ^ (ctrl_inw(INTC_ICR2) >> 8)) & (ctrl_inw(INTC_INTER) >> 8) & 0xff;
329 ctrl_outw(sav, creg);
330 if(d == 0) return irq;
331 return PINT_IRQ_BASE + 8 + pint_map[d];
332 }
333#endif
334 return irq;
335}
336#endif
337
338EXPORT_SYMBOL(make_ipr_irq);
339
diff --git a/arch/sh/kernel/cpu/rtc.c b/arch/sh/kernel/cpu/rtc.c
new file mode 100644
index 000000000000..f8361f5e788b
--- /dev/null
+++ b/arch/sh/kernel/cpu/rtc.c
@@ -0,0 +1,136 @@
1/*
2 * linux/arch/sh/kernel/rtc.c -- SH3 / SH4 on-chip RTC support
3 *
4 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
5 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
6 */
7
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/time.h>
12
13#include <asm/io.h>
14#include <asm/rtc.h>
15
16#ifndef BCD_TO_BIN
17#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
18#endif
19
20#ifndef BIN_TO_BCD
21#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
22#endif
23
24void sh_rtc_gettimeofday(struct timespec *ts)
25{
26 unsigned int sec128, sec, sec2, min, hr, wk, day, mon, yr, yr100, cf_bit;
27 unsigned long flags;
28
29 again:
30 do {
31 local_irq_save(flags);
32 ctrl_outb(0, RCR1); /* Clear CF-bit */
33 sec128 = ctrl_inb(R64CNT);
34 sec = ctrl_inb(RSECCNT);
35 min = ctrl_inb(RMINCNT);
36 hr = ctrl_inb(RHRCNT);
37 wk = ctrl_inb(RWKCNT);
38 day = ctrl_inb(RDAYCNT);
39 mon = ctrl_inb(RMONCNT);
40#if defined(CONFIG_CPU_SH4)
41 yr = ctrl_inw(RYRCNT);
42 yr100 = (yr >> 8);
43 yr &= 0xff;
44#else
45 yr = ctrl_inb(RYRCNT);
46 yr100 = (yr == 0x99) ? 0x19 : 0x20;
47#endif
48 sec2 = ctrl_inb(R64CNT);
49 cf_bit = ctrl_inb(RCR1) & RCR1_CF;
50 local_irq_restore(flags);
51 } while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);
52
53 BCD_TO_BIN(yr100);
54 BCD_TO_BIN(yr);
55 BCD_TO_BIN(mon);
56 BCD_TO_BIN(day);
57 BCD_TO_BIN(hr);
58 BCD_TO_BIN(min);
59 BCD_TO_BIN(sec);
60
61 if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
62 hr > 23 || min > 59 || sec > 59) {
63 printk(KERN_ERR
64 "SH RTC: invalid value, resetting to 1 Jan 2000\n");
65 local_irq_save(flags);
66 ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */
67 ctrl_outb(0, RSECCNT);
68 ctrl_outb(0, RMINCNT);
69 ctrl_outb(0, RHRCNT);
70 ctrl_outb(6, RWKCNT);
71 ctrl_outb(1, RDAYCNT);
72 ctrl_outb(1, RMONCNT);
73#if defined(CONFIG_CPU_SH4)
74 ctrl_outw(0x2000, RYRCNT);
75#else
76 ctrl_outb(0, RYRCNT);
77#endif
78 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */
79 goto again;
80 }
81
82#if RTC_BIT_INVERTED != 0
83 if ((sec128 & RTC_BIT_INVERTED))
84 sec--;
85#endif
86
87 ts->tv_sec = mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
88 ts->tv_nsec = ((sec128 * 1000000) / 128) * 1000;
89}
90
91/*
92 * Changed to only care about tv_sec, and not the full timespec struct
93 * (i.e. tv_nsec). It can easily be switched to timespec for future cpus
94 * that support setting usec or nsec RTC values.
95 */
96int sh_rtc_settimeofday(const time_t secs)
97{
98 int retval = 0;
99 int real_seconds, real_minutes, cmos_minutes;
100 unsigned long flags;
101
102 local_irq_save(flags);
103 ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */
104
105 cmos_minutes = ctrl_inb(RMINCNT);
106 BCD_TO_BIN(cmos_minutes);
107
108 /*
109 * since we're only adjusting minutes and seconds,
110 * don't interfere with hour overflow. This avoids
111 * messing with unknown time zones but requires your
112 * RTC not to be off by more than 15 minutes
113 */
114 real_seconds = secs % 60;
115 real_minutes = secs / 60;
116 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
117 real_minutes += 30; /* correct for half hour time zone */
118 real_minutes %= 60;
119
120 if (abs(real_minutes - cmos_minutes) < 30) {
121 BIN_TO_BCD(real_seconds);
122 BIN_TO_BCD(real_minutes);
123 ctrl_outb(real_seconds, RSECCNT);
124 ctrl_outb(real_minutes, RMINCNT);
125 } else {
126 printk(KERN_WARNING
127 "set_rtc_time: can't update from %d to %d\n",
128 cmos_minutes, real_minutes);
129 retval = -1;
130 }
131
132 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */
133 local_irq_restore(flags);
134
135 return retval;
136}
diff --git a/arch/sh/kernel/cpu/sh2/Makefile b/arch/sh/kernel/cpu/sh2/Makefile
new file mode 100644
index 000000000000..389353fba608
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the Linux/SuperH SH-2 backends.
3#
4
5obj-y := probe.o
6
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
new file mode 100644
index 000000000000..f17a2a0d588e
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2/probe.c
@@ -0,0 +1,39 @@
1/*
2 * arch/sh/kernel/cpu/sh2/probe.c
3 *
4 * CPU Subtype Probing for SH-2.
5 *
6 * Copyright (C) 2002 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13
14#include <linux/init.h>
15#include <asm/processor.h>
16#include <asm/cache.h>
17
18int __init detect_cpu_and_cache_system(void)
19{
20 /*
21 * For now, assume SH7604 .. fix this later.
22 */
23 cpu_data->type = CPU_SH7604;
24 cpu_data->dcache.ways = 4;
25 cpu_data->dcache.way_shift = 6;
26 cpu_data->dcache.sets = 64;
27 cpu_data->dcache.entry_shift = 4;
28 cpu_data->dcache.linesz = L1_CACHE_BYTES;
29 cpu_data->dcache.flags = 0;
30
31 /*
32 * SH-2 doesn't have separate caches
33 */
34 cpu_data->dcache.flags |= SH_CACHE_COMBINED;
35 cpu_data->icache = cpu_data->dcache;
36
37 return 0;
38}
39
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
new file mode 100644
index 000000000000..a64532e4dc63
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the Linux/SuperH SH-3 backends.
3#
4
5obj-y := ex.o probe.o
6
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
new file mode 100644
index 000000000000..966c0858b714
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -0,0 +1,199 @@
1/*
2 * arch/sh/kernel/cpu/sh3/ex.S
3 *
4 * The SH-3 exception vector table.
5
6 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
7 * Copyright (C) 2003 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14#include <linux/linkage.h>
15#include <linux/config.h>
16
17 .align 2
18 .data
19
20ENTRY(exception_handling_table)
21 .long exception_error /* 000 */
22 .long exception_error
23#if defined(CONFIG_MMU)
24 .long tlb_miss_load /* 040 */
25 .long tlb_miss_store
26 .long initial_page_write
27 .long tlb_protection_violation_load
28 .long tlb_protection_violation_store
29 .long address_error_load
30 .long address_error_store /* 100 */
31#else
32 .long exception_error ! tlb miss load /* 040 */
33 .long exception_error ! tlb miss store
34 .long exception_error ! initial page write
35 .long exception_error ! tlb prot violation load
36 .long exception_error ! tlb prot violation store
37 .long exception_error ! address error load
38 .long exception_error ! address error store /* 100 */
39#endif
40 .long exception_error ! fpu_exception /* 120 */
41 .long exception_error /* 140 */
42 .long system_call ! Unconditional Trap /* 160 */
43 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
44 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
45ENTRY(nmi_slot)
46#if defined (CONFIG_KGDB_NMI)
47 .long debug_enter /* 1C0 */ ! Allow trap to debugger
48#else
49 .long exception_none /* 1C0 */ ! Not implemented yet
50#endif
51ENTRY(user_break_point_trap)
52 .long break_point_trap /* 1E0 */
53ENTRY(interrupt_table)
54 ! external hardware
55 .long do_IRQ ! 0000 /* 200 */
56 .long do_IRQ ! 0001
57 .long do_IRQ ! 0010
58 .long do_IRQ ! 0011
59 .long do_IRQ ! 0100
60 .long do_IRQ ! 0101
61 .long do_IRQ ! 0110
62 .long do_IRQ ! 0111
63 .long do_IRQ ! 1000 /* 300 */
64 .long do_IRQ ! 1001
65 .long do_IRQ ! 1010
66 .long do_IRQ ! 1011
67 .long do_IRQ ! 1100
68 .long do_IRQ ! 1101
69 .long do_IRQ ! 1110
70 .long exception_error
71 ! Internal hardware
72 .long do_IRQ ! TMU0 tuni0 /* 400 */
73 .long do_IRQ ! TMU1 tuni1
74 .long do_IRQ ! TMU2 tuni2
75 .long do_IRQ ! ticpi2
76 .long do_IRQ ! RTC ati
77 .long do_IRQ ! pri
78 .long do_IRQ ! cui
79 .long do_IRQ ! SCI eri
80 .long do_IRQ ! rxi /* 500 */
81 .long do_IRQ ! txi
82 .long do_IRQ ! tei
83 .long do_IRQ ! WDT iti /* 560 */
84 .long do_IRQ ! REF rcmi
85 .long do_IRQ ! rovi
86 .long do_IRQ
87 .long do_IRQ /* 5E0 */
88#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
89 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
90 .long do_IRQ ! 32 IRQ irq0 /* 600 */
91 .long do_IRQ ! 33 irq1
92 .long do_IRQ ! 34 irq2
93 .long do_IRQ ! 35 irq3
94 .long do_IRQ ! 36 irq4
95 .long do_IRQ ! 37 irq5
96 .long do_IRQ ! 38
97 .long do_IRQ ! 39
98 .long do_IRQ ! 40 PINT pint0-7 /* 700 */
99 .long do_IRQ ! 41 pint8-15
100 .long do_IRQ ! 42
101 .long do_IRQ ! 43
102 .long do_IRQ ! 44
103 .long do_IRQ ! 45
104 .long do_IRQ ! 46
105 .long do_IRQ ! 47
106 .long do_IRQ ! 48 DMAC dei0 /* 800 */
107 .long do_IRQ ! 49 dei1
108 .long do_IRQ ! 50 dei2
109 .long do_IRQ ! 51 dei3
110 .long do_IRQ ! 52 IrDA eri1
111 .long do_IRQ ! 53 rxi1
112 .long do_IRQ ! 54 bri1
113 .long do_IRQ ! 55 txi1
114 .long do_IRQ ! 56 SCIF eri2
115 .long do_IRQ ! 57 rxi2
116 .long do_IRQ ! 58 bri2
117 .long do_IRQ ! 59 txi2
118 .long do_IRQ ! 60 ADC adi /* 980 */
119#if defined(CONFIG_CPU_SUBTYPE_SH7705)
120 .long exception_none ! 61 /* 9A0 */
121 .long exception_none ! 62
122 .long exception_none ! 63
123 .long exception_none ! 64 /* A00 */
124 .long do_IRQ ! 65 USB usi0
125 .long do_IRQ ! 66 usi1
126 .long exception_none ! 67
127 .long exception_none ! 68
128 .long exception_none ! 69
129 .long exception_none ! 70
130 .long exception_none ! 71
131 .long exception_none ! 72 /* B00 */
132 .long exception_none ! 73
133 .long exception_none ! 74
134 .long exception_none ! 75
135 .long exception_none ! 76
136 .long exception_none ! 77
137 .long exception_none ! 78
138 .long exception_none ! 79
139 .long do_IRQ ! 80 TPU0 tpi0 /* C00 */
140 .long do_IRQ ! 81 TPU1 tpi1
141 .long exception_none ! 82
142 .long exception_none ! 83
143 .long do_IRQ ! 84 TPU2 tpi2
144 .long do_IRQ ! 85 TPU3 tpi3 /* CA0 */
145#endif
146#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300)
147 .long do_IRQ ! 61 LCDC lcdi /* 9A0 */
148 .long do_IRQ ! 62 PCC pcc0i
149 .long do_IRQ ! 63 pcc1i /* 9E0 */
150#endif
151#if defined(CONFIG_CPU_SUBTYPE_SH7300)
152 .long do_IRQ ! 64
153 .long do_IRQ ! 65
154 .long do_IRQ ! 66
155 .long do_IRQ ! 67
156 .long do_IRQ ! 68
157 .long do_IRQ ! 69
158 .long do_IRQ ! 70
159 .long do_IRQ ! 71
160 .long do_IRQ ! 72
161 .long do_IRQ ! 73
162 .long do_IRQ ! 74
163 .long do_IRQ ! 75
164 .long do_IRQ ! 76
165 .long do_IRQ ! 77
166 .long do_IRQ ! 78
167 .long do_IRQ ! 79
168 .long do_IRQ ! 80 SCIF0(SH7300)
169 .long do_IRQ ! 81
170 .long do_IRQ ! 82
171 .long do_IRQ ! 83
172 .long do_IRQ ! 84
173 .long do_IRQ ! 85
174 .long do_IRQ ! 86
175 .long do_IRQ ! 87
176 .long do_IRQ ! 88
177 .long do_IRQ ! 89
178 .long do_IRQ ! 90
179 .long do_IRQ ! 91
180 .long do_IRQ ! 92
181 .long do_IRQ ! 93
182 .long do_IRQ ! 94
183 .long do_IRQ ! 95
184 .long do_IRQ ! 96
185 .long do_IRQ ! 97
186 .long do_IRQ ! 98
187 .long do_IRQ ! 99
188 .long do_IRQ ! 100
189 .long do_IRQ ! 101
190 .long do_IRQ ! 102
191 .long do_IRQ ! 103
192 .long do_IRQ ! 104
193 .long do_IRQ ! 105
194 .long do_IRQ ! 106
195 .long do_IRQ ! 107
196 .long do_IRQ ! 108
197#endif
198#endif
199
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
new file mode 100644
index 000000000000..5cdc88638601
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -0,0 +1,97 @@
1/*
2 * arch/sh/kernel/cpu/sh3/probe.c
3 *
4 * CPU Subtype Probing for SH-3.
5 *
6 * Copyright (C) 1999, 2000 Niibe Yutaka
7 * Copyright (C) 2002 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/init.h>
15#include <asm/processor.h>
16#include <asm/cache.h>
17#include <asm/io.h>
18
19int __init detect_cpu_and_cache_system(void)
20{
21 unsigned long addr0, addr1, data0, data1, data2, data3;
22
23 jump_to_P2();
24 /*
25 * Check if the entry shadows or not.
26 * When shadowed, it's 128-entry system.
27 * Otherwise, it's 256-entry system.
28 */
29 addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
30 addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
31
32 /* First, write back & invalidate */
33 data0 = ctrl_inl(addr0);
34 ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0);
35 data1 = ctrl_inl(addr1);
36 ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1);
37
38 /* Next, check if there's shadow or not */
39 data0 = ctrl_inl(addr0);
40 data0 ^= SH_CACHE_VALID;
41 ctrl_outl(data0, addr0);
42 data1 = ctrl_inl(addr1);
43 data2 = data1 ^ SH_CACHE_VALID;
44 ctrl_outl(data2, addr1);
45 data3 = ctrl_inl(addr0);
46
47 /* Lastly, invaliate them. */
48 ctrl_outl(data0&~SH_CACHE_VALID, addr0);
49 ctrl_outl(data2&~SH_CACHE_VALID, addr1);
50
51 back_to_P1();
52
53 cpu_data->dcache.ways = 4;
54 cpu_data->dcache.entry_shift = 4;
55 cpu_data->dcache.linesz = L1_CACHE_BYTES;
56 cpu_data->dcache.flags = 0;
57
58 /*
59 * 7709A/7729 has 16K cache (256-entry), while 7702 has only
60 * 2K(direct) 7702 is not supported (yet)
61 */
62 if (data0 == data1 && data2 == data3) { /* Shadow */
63 cpu_data->dcache.way_incr = (1 << 11);
64 cpu_data->dcache.entry_mask = 0x7f0;
65 cpu_data->dcache.sets = 128;
66 cpu_data->type = CPU_SH7708;
67
68 cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC;
69 } else { /* 7709A or 7729 */
70 cpu_data->dcache.way_incr = (1 << 12);
71 cpu_data->dcache.entry_mask = 0xff0;
72 cpu_data->dcache.sets = 256;
73 cpu_data->type = CPU_SH7729;
74
75#if defined(CONFIG_CPU_SUBTYPE_SH7705)
76 cpu_data->type = CPU_SH7705;
77
78#if defined(CONFIG_SH7705_CACHE_32KB)
79 cpu_data->dcache.way_incr = (1 << 13);
80 cpu_data->dcache.entry_mask = 0x1ff0;
81 cpu_data->dcache.sets = 512;
82 ctrl_outl(CCR_CACHE_32KB, CCR3);
83#else
84 ctrl_outl(CCR_CACHE_16KB, CCR3);
85#endif
86#endif
87 }
88
89 /*
90 * SH-3 doesn't have separate caches
91 */
92 cpu_data->dcache.flags |= SH_CACHE_COMBINED;
93 cpu_data->icache = cpu_data->dcache;
94
95 return 0;
96}
97
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
new file mode 100644
index 000000000000..ead1071eac73
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for the Linux/SuperH SH-4 backends.
3#
4
5obj-y := ex.o probe.o
6
7obj-$(CONFIG_SH_FPU) += fpu.o
8obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += irq_intc2.o
9obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
10
diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S
new file mode 100644
index 000000000000..8221e9d15515
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/ex.S
@@ -0,0 +1,384 @@
1/*
2 * arch/sh/kernel/cpu/sh4/ex.S
3 *
4 * The SH-4 exception vector table.
5
6 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
7 * Copyright (C) 2003 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14#include <linux/linkage.h>
15#include <linux/config.h>
16
17 .align 2
18 .data
19
20ENTRY(exception_handling_table)
21 .long exception_error /* 000 */
22 .long exception_error
23#if defined(CONFIG_MMU)
24 .long tlb_miss_load /* 040 */
25 .long tlb_miss_store
26 .long initial_page_write
27 .long tlb_protection_violation_load
28 .long tlb_protection_violation_store
29 .long address_error_load
30 .long address_error_store /* 100 */
31#else
32 .long exception_error ! tlb miss load /* 040 */
33 .long exception_error ! tlb miss store
34 .long exception_error ! initial page write
35 .long exception_error ! tlb prot violation load
36 .long exception_error ! tlb prot violation store
37 .long exception_error ! address error load
38 .long exception_error ! address error store /* 100 */
39#endif
40#if defined(CONFIG_SH_FPU)
41 .long do_fpu_error /* 120 */
42#else
43 .long exception_error /* 120 */
44#endif
45 .long exception_error /* 140 */
46 .long system_call ! Unconditional Trap /* 160 */
47 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
48 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
49ENTRY(nmi_slot)
50#if defined (CONFIG_KGDB_NMI)
51 .long debug_enter /* 1C0 */ ! Allow trap to debugger
52#else
53 .long exception_none /* 1C0 */ ! Not implemented yet
54#endif
55ENTRY(user_break_point_trap)
56 .long break_point_trap /* 1E0 */
57ENTRY(interrupt_table)
58 ! external hardware
59 .long do_IRQ ! 0000 /* 200 */
60 .long do_IRQ ! 0001
61 .long do_IRQ ! 0010
62 .long do_IRQ ! 0011
63 .long do_IRQ ! 0100
64 .long do_IRQ ! 0101
65 .long do_IRQ ! 0110
66 .long do_IRQ ! 0111
67 .long do_IRQ ! 1000 /* 300 */
68 .long do_IRQ ! 1001
69 .long do_IRQ ! 1010
70 .long do_IRQ ! 1011
71 .long do_IRQ ! 1100
72 .long do_IRQ ! 1101
73 .long do_IRQ ! 1110
74 .long exception_error
75 ! Internal hardware
76 .long do_IRQ ! TMU0 tuni0 /* 400 */
77 .long do_IRQ ! TMU1 tuni1
78 .long do_IRQ ! TMU2 tuni2
79 .long do_IRQ ! ticpi2
80#if defined(CONFIG_CPU_SUBTYPE_SH7760)
81 .long exception_error
82 .long exception_error
83 .long exception_error
84 .long exception_error
85 .long exception_error /* 500 */
86 .long exception_error
87 .long exception_error
88#else
89 .long do_IRQ ! RTC ati
90 .long do_IRQ ! pri
91 .long do_IRQ ! cui
92 .long do_IRQ ! SCI eri
93 .long do_IRQ ! rxi /* 500 */
94 .long do_IRQ ! txi
95 .long do_IRQ ! tei
96#endif
97 .long do_IRQ ! WDT iti /* 560 */
98 .long do_IRQ ! REF rcmi
99 .long do_IRQ ! rovi
100 .long do_IRQ
101 .long do_IRQ /* 5E0 */
102 .long do_IRQ ! 32 Hitachi UDI /* 600 */
103 .long do_IRQ ! 33 GPIO
104 .long do_IRQ ! 34 DMAC dmte0
105 .long do_IRQ ! 35 dmte1
106 .long do_IRQ ! 36 dmte2
107 .long do_IRQ ! 37 dmte3
108 .long do_IRQ ! 38 dmae
109 .long exception_error ! 39 /* 6E0 */
110#if defined(CONFIG_CPU_SUBTYPE_SH7760)
111 .long exception_error /* 700 */
112 .long exception_error
113 .long exception_error
114 .long exception_error /* 760 */
115#else
116 .long do_IRQ ! 40 SCIF eri /* 700 */
117 .long do_IRQ ! 41 rxi
118 .long do_IRQ ! 42 bri
119 .long do_IRQ ! 43 txi
120#endif
121#if CONFIG_NR_ONCHIP_DMA_CHANNELS == 8
122 .long do_IRQ ! 44 DMAC dmte4 /* 780 */
123 .long do_IRQ ! 45 dmte5
124 .long do_IRQ ! 46 dmte6
125 .long do_IRQ ! 47 dmte7 /* 7E0 */
126#else
127 .long exception_error ! 44 /* 780 */
128 .long exception_error ! 45
129 .long exception_error ! 46
130 .long exception_error ! 47
131#endif
132#if defined(CONFIG_SH_FPU)
133 .long do_fpu_state_restore ! 48 /* 800 */
134 .long do_fpu_state_restore ! 49 /* 820 */
135#else
136 .long exception_error
137 .long exception_error
138#endif
139#if defined(CONFIG_CPU_SUBTYPE_SH7751)
140 .long exception_error /* 840 */
141 .long exception_error
142 .long exception_error
143 .long exception_error
144 .long exception_error
145 .long exception_error
146 .long exception_error /* 900 */
147 .long exception_error
148 .long exception_error
149 .long exception_error
150 .long exception_error
151 .long exception_error
152 .long exception_error
153 .long exception_error
154 .long do_IRQ ! PCI serr /* A00 */
155 .long do_IRQ ! dma3
156 .long do_IRQ ! dma2
157 .long do_IRQ ! dma1
158 .long do_IRQ ! dma0
159 .long do_IRQ ! pwon
160 .long do_IRQ ! pwdwn
161 .long do_IRQ ! err
162 .long do_IRQ ! TMU3 tuni3 /* B00 */
163 .long exception_error
164 .long exception_error
165 .long exception_error
166 .long do_IRQ ! TMU4 tuni4 /* B80 */
167#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
168 .long do_IRQ ! IRQ irq6 /* 840 */
169 .long do_IRQ ! irq7
170 .long do_IRQ ! SCIF eri0
171 .long do_IRQ ! rxi0
172 .long do_IRQ ! bri0
173 .long do_IRQ ! txi0
174 .long do_IRQ ! HCAN2 cani0 /* 900 */
175 .long do_IRQ ! cani1
176 .long do_IRQ ! SSI ssii0
177 .long do_IRQ ! ssii1
178 .long do_IRQ ! HAC haci0
179 .long do_IRQ ! haci1
180 .long do_IRQ ! IIC iici0
181 .long do_IRQ ! iici1
182 .long do_IRQ ! USB usbi /* A00 */
183 .long do_IRQ ! LCDC vint
184 .long exception_error
185 .long exception_error
186 .long do_IRQ ! DMABRG dmabrgi0
187 .long do_IRQ ! dmabrgi1
188 .long do_IRQ ! dmabrgi2
189 .long exception_error
190 .long do_IRQ ! SCIF eri1 /* B00 */
191 .long do_IRQ ! rxi1
192 .long do_IRQ ! bri1
193 .long do_IRQ ! txi1
194 .long do_IRQ ! eri2
195 .long do_IRQ ! rxi2
196 .long do_IRQ ! bri2
197 .long do_IRQ ! txi2
198 .long do_IRQ ! SIM simeri /* C00 */
199 .long do_IRQ ! simrxi
200 .long do_IRQ ! simtxi
201 .long do_IRQ ! simtei
202 .long do_IRQ ! HSPI spii
203 .long exception_error
204 .long exception_error
205 .long exception_error
206 .long do_IRQ ! MMCIF mmci0 /* D00 */
207 .long do_IRQ ! mmci1
208 .long do_IRQ ! mmci2
209 .long do_IRQ ! mmci3
210 .long exception_error
211 .long exception_error
212 .long exception_error
213 .long exception_error
214 .long exception_error /* E00 */
215 .long exception_error
216 .long exception_error
217 .long exception_error
218 .long do_IRQ ! MFI mfii
219 .long exception_error
220 .long exception_error
221 .long exception_error
222 .long exception_error /* F00 */
223 .long exception_error
224 .long exception_error
225 .long exception_error
226 .long do_IRQ ! ADC adi
227 .long do_IRQ ! CMT cmti /* FA0 */
228#elif defined(CONFIG_CPU_SUBTYPE_SH73180)
229 .long do_IRQ ! 50 0x840
230 .long do_IRQ ! 51 0x860
231 .long do_IRQ ! 52 0x880
232 .long do_IRQ ! 53 0x8a0
233 .long do_IRQ ! 54 0x8c0
234 .long do_IRQ ! 55 0x8e0
235 .long do_IRQ ! 56 0x900
236 .long do_IRQ ! 57 0x920
237 .long do_IRQ ! 58 0x940
238 .long do_IRQ ! 59 0x960
239 .long do_IRQ ! 60 0x980
240 .long do_IRQ ! 61 0x9a0
241 .long do_IRQ ! 62 0x9c0
242 .long do_IRQ ! 63 0x9e0
243 .long do_IRQ ! 64 0xa00
244 .long do_IRQ ! 65 0xa20
245 .long do_IRQ ! 66 0xa40
246 .long do_IRQ ! 67 0xa60
247 .long do_IRQ ! 68 0xa80
248 .long do_IRQ ! 69 0xaa0
249 .long do_IRQ ! 70 0xac0
250 .long do_IRQ ! 71 0xae0
251 .long do_IRQ ! 72 0xb00
252 .long do_IRQ ! 73 0xb20
253 .long do_IRQ ! 74 0xb40
254 .long do_IRQ ! 75 0xb60
255 .long do_IRQ ! 76 0xb80
256 .long do_IRQ ! 77 0xba0
257 .long do_IRQ ! 78 0xbc0
258 .long do_IRQ ! 79 0xbe0
259 .long do_IRQ ! 80 0xc00
260 .long do_IRQ ! 81 0xc20
261 .long do_IRQ ! 82 0xc40
262 .long do_IRQ ! 83 0xc60
263 .long do_IRQ ! 84 0xc80
264 .long do_IRQ ! 85 0xca0
265 .long do_IRQ ! 86 0xcc0
266 .long do_IRQ ! 87 0xce0
267 .long do_IRQ ! 88 0xd00
268 .long do_IRQ ! 89 0xd20
269 .long do_IRQ ! 90 0xd40
270 .long do_IRQ ! 91 0xd60
271 .long do_IRQ ! 92 0xd80
272 .long do_IRQ ! 93 0xda0
273 .long do_IRQ ! 94 0xdc0
274 .long do_IRQ ! 95 0xde0
275 .long do_IRQ ! 96 0xe00
276 .long do_IRQ ! 97 0xe20
277 .long do_IRQ ! 98 0xe40
278 .long do_IRQ ! 99 0xe60
279 .long do_IRQ ! 100 0xe80
280 .long do_IRQ ! 101 0xea0
281 .long do_IRQ ! 102 0xec0
282 .long do_IRQ ! 103 0xee0
283 .long do_IRQ ! 104 0xf00
284 .long do_IRQ ! 105 0xf20
285 .long do_IRQ ! 106 0xf40
286 .long do_IRQ ! 107 0xf60
287 .long do_IRQ ! 108 0xf80
288#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
289 .long exception_error ! 50 0x840
290 .long exception_error ! 51 0x860
291 .long exception_error ! 52 0x880
292 .long exception_error ! 53 0x8a0
293 .long exception_error ! 54 0x8c0
294 .long exception_error ! 55 0x8e0
295 .long exception_error ! 56 0x900
296 .long exception_error ! 57 0x920
297 .long exception_error ! 58 0x940
298 .long exception_error ! 59 0x960
299 .long exception_error ! 60 0x980
300 .long exception_error ! 61 0x9a0
301 .long exception_error ! 62 0x9c0
302 .long exception_error ! 63 0x9e0
303 .long do_IRQ ! 64 0xa00 PCI serr
304 .long do_IRQ ! 65 0xa20 err
305 .long do_IRQ ! 66 0xa40 ad
306 .long do_IRQ ! 67 0xa60 pwr_dwn
307 .long exception_error ! 68 0xa80
308 .long exception_error ! 69 0xaa0
309 .long exception_error ! 70 0xac0
310 .long exception_error ! 71 0xae0
311 .long do_IRQ ! 72 0xb00 DMA INT0
312 .long do_IRQ ! 73 0xb20 INT1
313 .long do_IRQ ! 74 0xb40 INT2
314 .long do_IRQ ! 75 0xb60 INT3
315 .long do_IRQ ! 76 0xb80 INT4
316 .long exception_error ! 77 0xba0
317 .long do_IRQ ! 78 0xbc0 DMA ERR
318 .long exception_error ! 79 0xbe0
319 .long do_IRQ ! 80 0xc00 PIO0
320 .long do_IRQ ! 81 0xc20 PIO1
321 .long do_IRQ ! 82 0xc40 PIO2
322 .long exception_error ! 83 0xc60
323 .long exception_error ! 84 0xc80
324 .long exception_error ! 85 0xca0
325 .long exception_error ! 86 0xcc0
326 .long exception_error ! 87 0xce0
327 .long exception_error ! 88 0xd00
328 .long exception_error ! 89 0xd20
329 .long exception_error ! 90 0xd40
330 .long exception_error ! 91 0xd60
331 .long exception_error ! 92 0xd80
332 .long exception_error ! 93 0xda0
333 .long exception_error ! 94 0xdc0
334 .long exception_error ! 95 0xde0
335 .long exception_error ! 96 0xe00
336 .long exception_error ! 97 0xe20
337 .long exception_error ! 98 0xe40
338 .long exception_error ! 99 0xe60
339 .long exception_error ! 100 0xe80
340 .long exception_error ! 101 0xea0
341 .long exception_error ! 102 0xec0
342 .long exception_error ! 103 0xee0
343 .long exception_error ! 104 0xf00
344 .long exception_error ! 105 0xf20
345 .long exception_error ! 106 0xf40
346 .long exception_error ! 107 0xf60
347 .long exception_error ! 108 0xf80
348 .long exception_error ! 109 0xfa0
349 .long exception_error ! 110 0xfc0
350 .long exception_error ! 111 0xfe0
351 .long do_IRQ ! 112 0x1000 Mailbox
352 .long exception_error ! 113 0x1020
353 .long exception_error ! 114 0x1040
354 .long exception_error ! 115 0x1060
355 .long exception_error ! 116 0x1080
356 .long exception_error ! 117 0x10a0
357 .long exception_error ! 118 0x10c0
358 .long exception_error ! 119 0x10e0
359 .long exception_error ! 120 0x1100
360 .long exception_error ! 121 0x1120
361 .long exception_error ! 122 0x1140
362 .long exception_error ! 123 0x1160
363 .long exception_error ! 124 0x1180
364 .long exception_error ! 125 0x11a0
365 .long exception_error ! 126 0x11c0
366 .long exception_error ! 127 0x11e0
367 .long exception_error ! 128 0x1200
368 .long exception_error ! 129 0x1220
369 .long exception_error ! 130 0x1240
370 .long exception_error ! 131 0x1260
371 .long exception_error ! 132 0x1280
372 .long exception_error ! 133 0x12a0
373 .long exception_error ! 134 0x12c0
374 .long exception_error ! 135 0x12e0
375 .long exception_error ! 136 0x1300
376 .long exception_error ! 137 0x1320
377 .long exception_error ! 138 0x1340
378 .long exception_error ! 139 0x1360
379 .long do_IRQ ! 140 0x1380 EMPI INV_ADDR
380 .long exception_error ! 141 0x13a0
381 .long exception_error ! 142 0x13c0
382 .long exception_error ! 143 0x13e0
383#endif
384
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
new file mode 100644
index 000000000000..f486c07e10e2
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -0,0 +1,335 @@
1/* $Id: fpu.c,v 1.4 2004/01/13 05:52:11 kkojima Exp $
2 *
3 * linux/arch/sh/kernel/fpu.c
4 *
5 * Save/restore floating point context for signal handlers.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
12 *
13 * FIXME! These routines can be optimized in big endian case.
14 */
15
16#include <linux/sched.h>
17#include <linux/signal.h>
18#include <asm/processor.h>
19#include <asm/io.h>
20
21/* The PR (precision) bit in the FP Status Register must be clear when
22 * an frchg instruction is executed, otherwise the instruction is undefined.
23 * Executing frchg with PR set causes a trap on some SH4 implementations.
24 */
25
26#define FPSCR_RCHG 0x00000000
27
28
29/*
30 * Save FPU registers onto task structure.
31 * Assume called with FPU enabled (SR.FD=0).
32 */
33void
34save_fpu(struct task_struct *tsk, struct pt_regs *regs)
35{
36 unsigned long dummy;
37
38 clear_tsk_thread_flag(tsk, TIF_USEDFPU);
39 enable_fpu();
40 asm volatile("sts.l fpul, @-%0\n\t"
41 "sts.l fpscr, @-%0\n\t"
42 "lds %2, fpscr\n\t"
43 "frchg\n\t"
44 "fmov.s fr15, @-%0\n\t"
45 "fmov.s fr14, @-%0\n\t"
46 "fmov.s fr13, @-%0\n\t"
47 "fmov.s fr12, @-%0\n\t"
48 "fmov.s fr11, @-%0\n\t"
49 "fmov.s fr10, @-%0\n\t"
50 "fmov.s fr9, @-%0\n\t"
51 "fmov.s fr8, @-%0\n\t"
52 "fmov.s fr7, @-%0\n\t"
53 "fmov.s fr6, @-%0\n\t"
54 "fmov.s fr5, @-%0\n\t"
55 "fmov.s fr4, @-%0\n\t"
56 "fmov.s fr3, @-%0\n\t"
57 "fmov.s fr2, @-%0\n\t"
58 "fmov.s fr1, @-%0\n\t"
59 "fmov.s fr0, @-%0\n\t"
60 "frchg\n\t"
61 "fmov.s fr15, @-%0\n\t"
62 "fmov.s fr14, @-%0\n\t"
63 "fmov.s fr13, @-%0\n\t"
64 "fmov.s fr12, @-%0\n\t"
65 "fmov.s fr11, @-%0\n\t"
66 "fmov.s fr10, @-%0\n\t"
67 "fmov.s fr9, @-%0\n\t"
68 "fmov.s fr8, @-%0\n\t"
69 "fmov.s fr7, @-%0\n\t"
70 "fmov.s fr6, @-%0\n\t"
71 "fmov.s fr5, @-%0\n\t"
72 "fmov.s fr4, @-%0\n\t"
73 "fmov.s fr3, @-%0\n\t"
74 "fmov.s fr2, @-%0\n\t"
75 "fmov.s fr1, @-%0\n\t"
76 "fmov.s fr0, @-%0\n\t"
77 "lds %3, fpscr\n\t"
78 : "=r" (dummy)
79 : "0" ((char *)(&tsk->thread.fpu.hard.status)),
80 "r" (FPSCR_RCHG),
81 "r" (FPSCR_INIT)
82 : "memory");
83
84 disable_fpu();
85 release_fpu(regs);
86}
87
88static void
89restore_fpu(struct task_struct *tsk)
90{
91 unsigned long dummy;
92
93 enable_fpu();
94 asm volatile("lds %2, fpscr\n\t"
95 "fmov.s @%0+, fr0\n\t"
96 "fmov.s @%0+, fr1\n\t"
97 "fmov.s @%0+, fr2\n\t"
98 "fmov.s @%0+, fr3\n\t"
99 "fmov.s @%0+, fr4\n\t"
100 "fmov.s @%0+, fr5\n\t"
101 "fmov.s @%0+, fr6\n\t"
102 "fmov.s @%0+, fr7\n\t"
103 "fmov.s @%0+, fr8\n\t"
104 "fmov.s @%0+, fr9\n\t"
105 "fmov.s @%0+, fr10\n\t"
106 "fmov.s @%0+, fr11\n\t"
107 "fmov.s @%0+, fr12\n\t"
108 "fmov.s @%0+, fr13\n\t"
109 "fmov.s @%0+, fr14\n\t"
110 "fmov.s @%0+, fr15\n\t"
111 "frchg\n\t"
112 "fmov.s @%0+, fr0\n\t"
113 "fmov.s @%0+, fr1\n\t"
114 "fmov.s @%0+, fr2\n\t"
115 "fmov.s @%0+, fr3\n\t"
116 "fmov.s @%0+, fr4\n\t"
117 "fmov.s @%0+, fr5\n\t"
118 "fmov.s @%0+, fr6\n\t"
119 "fmov.s @%0+, fr7\n\t"
120 "fmov.s @%0+, fr8\n\t"
121 "fmov.s @%0+, fr9\n\t"
122 "fmov.s @%0+, fr10\n\t"
123 "fmov.s @%0+, fr11\n\t"
124 "fmov.s @%0+, fr12\n\t"
125 "fmov.s @%0+, fr13\n\t"
126 "fmov.s @%0+, fr14\n\t"
127 "fmov.s @%0+, fr15\n\t"
128 "frchg\n\t"
129 "lds.l @%0+, fpscr\n\t"
130 "lds.l @%0+, fpul\n\t"
131 : "=r" (dummy)
132 : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG)
133 : "memory");
134 disable_fpu();
135}
136
137/*
138 * Load the FPU with signalling NANS. This bit pattern we're using
139 * has the property that no matter wether considered as single or as
140 * double precission represents signaling NANS.
141 */
142
143static void
144fpu_init(void)
145{
146 enable_fpu();
147 asm volatile("lds %0, fpul\n\t"
148 "lds %1, fpscr\n\t"
149 "fsts fpul, fr0\n\t"
150 "fsts fpul, fr1\n\t"
151 "fsts fpul, fr2\n\t"
152 "fsts fpul, fr3\n\t"
153 "fsts fpul, fr4\n\t"
154 "fsts fpul, fr5\n\t"
155 "fsts fpul, fr6\n\t"
156 "fsts fpul, fr7\n\t"
157 "fsts fpul, fr8\n\t"
158 "fsts fpul, fr9\n\t"
159 "fsts fpul, fr10\n\t"
160 "fsts fpul, fr11\n\t"
161 "fsts fpul, fr12\n\t"
162 "fsts fpul, fr13\n\t"
163 "fsts fpul, fr14\n\t"
164 "fsts fpul, fr15\n\t"
165 "frchg\n\t"
166 "fsts fpul, fr0\n\t"
167 "fsts fpul, fr1\n\t"
168 "fsts fpul, fr2\n\t"
169 "fsts fpul, fr3\n\t"
170 "fsts fpul, fr4\n\t"
171 "fsts fpul, fr5\n\t"
172 "fsts fpul, fr6\n\t"
173 "fsts fpul, fr7\n\t"
174 "fsts fpul, fr8\n\t"
175 "fsts fpul, fr9\n\t"
176 "fsts fpul, fr10\n\t"
177 "fsts fpul, fr11\n\t"
178 "fsts fpul, fr12\n\t"
179 "fsts fpul, fr13\n\t"
180 "fsts fpul, fr14\n\t"
181 "fsts fpul, fr15\n\t"
182 "frchg\n\t"
183 "lds %2, fpscr\n\t"
184 : /* no output */
185 : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
186 disable_fpu();
187}
188
189/**
190 * denormal_to_double - Given denormalized float number,
191 * store double float
192 *
193 * @fpu: Pointer to sh_fpu_hard structure
194 * @n: Index to FP register
195 */
196static void
197denormal_to_double (struct sh_fpu_hard_struct *fpu, int n)
198{
199 unsigned long du, dl;
200 unsigned long x = fpu->fpul;
201 int exp = 1023 - 126;
202
203 if (x != 0 && (x & 0x7f800000) == 0) {
204 du = (x & 0x80000000);
205 while ((x & 0x00800000) == 0) {
206 x <<= 1;
207 exp--;
208 }
209 x &= 0x007fffff;
210 du |= (exp << 20) | (x >> 3);
211 dl = x << 29;
212
213 fpu->fp_regs[n] = du;
214 fpu->fp_regs[n+1] = dl;
215 }
216}
217
218/**
219 * ieee_fpe_handler - Handle denormalized number exception
220 *
221 * @regs: Pointer to register structure
222 *
223 * Returns 1 when it's handled (should not cause exception).
224 */
225static int
226ieee_fpe_handler (struct pt_regs *regs)
227{
228 unsigned short insn = *(unsigned short *) regs->pc;
229 unsigned short finsn;
230 unsigned long nextpc;
231 int nib[4] = {
232 (insn >> 12) & 0xf,
233 (insn >> 8) & 0xf,
234 (insn >> 4) & 0xf,
235 insn & 0xf};
236
237 if (nib[0] == 0xb ||
238 (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
239 regs->pr = regs->pc + 4;
240
241 if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
242 nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
243 finsn = *(unsigned short *) (regs->pc + 2);
244 } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */
245 if (regs->sr & 1)
246 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
247 else
248 nextpc = regs->pc + 4;
249 finsn = *(unsigned short *) (regs->pc + 2);
250 } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */
251 if (regs->sr & 1)
252 nextpc = regs->pc + 4;
253 else
254 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
255 finsn = *(unsigned short *) (regs->pc + 2);
256 } else if (nib[0] == 0x4 && nib[3] == 0xb &&
257 (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */
258 nextpc = regs->regs[nib[1]];
259 finsn = *(unsigned short *) (regs->pc + 2);
260 } else if (nib[0] == 0x0 && nib[3] == 0x3 &&
261 (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */
262 nextpc = regs->pc + 4 + regs->regs[nib[1]];
263 finsn = *(unsigned short *) (regs->pc + 2);
264 } else if (insn == 0x000b) { /* rts */
265 nextpc = regs->pr;
266 finsn = *(unsigned short *) (regs->pc + 2);
267 } else {
268 nextpc = regs->pc + 2;
269 finsn = insn;
270 }
271
272 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
273 struct task_struct *tsk = current;
274
275 save_fpu(tsk, regs);
276 if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) {
277 /* FPU error */
278 denormal_to_double (&tsk->thread.fpu.hard,
279 (finsn >> 8) & 0xf);
280 tsk->thread.fpu.hard.fpscr &=
281 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
282 grab_fpu(regs);
283 restore_fpu(tsk);
284 set_tsk_thread_flag(tsk, TIF_USEDFPU);
285 } else {
286 tsk->thread.trap_no = 11;
287 tsk->thread.error_code = 0;
288 force_sig(SIGFPE, tsk);
289 }
290
291 regs->pc = nextpc;
292 return 1;
293 }
294
295 return 0;
296}
297
298asmlinkage void
299do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7,
300 struct pt_regs regs)
301{
302 struct task_struct *tsk = current;
303
304 if (ieee_fpe_handler (&regs))
305 return;
306
307 regs.pc += 2;
308 save_fpu(tsk, &regs);
309 tsk->thread.trap_no = 11;
310 tsk->thread.error_code = 0;
311 force_sig(SIGFPE, tsk);
312}
313
314asmlinkage void
315do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
316 unsigned long r7, struct pt_regs regs)
317{
318 struct task_struct *tsk = current;
319
320 grab_fpu(&regs);
321 if (!user_mode(&regs)) {
322 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
323 return;
324 }
325
326 if (used_math()) {
327 /* Using the FPU again. */
328 restore_fpu(tsk);
329 } else {
330 /* First time FPU user. */
331 fpu_init();
332 set_used_math();
333 }
334 set_tsk_thread_flag(tsk, TIF_USEDFPU);
335}
diff --git a/arch/sh/kernel/cpu/sh4/irq_intc2.c b/arch/sh/kernel/cpu/sh4/irq_intc2.c
new file mode 100644
index 000000000000..099ebbf89745
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/irq_intc2.c
@@ -0,0 +1,222 @@
1/*
2 * linux/arch/sh/kernel/irq_intc2.c
3 *
4 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Interrupt handling for INTC2-based IRQ.
10 *
11 * These are the "new Hitachi style" interrupts, as present on the
12 * Hitachi 7751 and the STM ST40 STB1.
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/irq.h>
18
19#include <asm/system.h>
20#include <asm/io.h>
21#include <asm/machvec.h>
22
23
24struct intc2_data {
25 unsigned char msk_offset;
26 unsigned char msk_shift;
27#ifdef CONFIG_CPU_SUBTYPE_ST40
28 int (*clear_irq) (int);
29#endif
30};
31
32
33static struct intc2_data intc2_data[NR_INTC2_IRQS];
34
35static void enable_intc2_irq(unsigned int irq);
36static void disable_intc2_irq(unsigned int irq);
37
38/* shutdown is same as "disable" */
39#define shutdown_intc2_irq disable_intc2_irq
40
41static void mask_and_ack_intc2(unsigned int);
42static void end_intc2_irq(unsigned int irq);
43
44static unsigned int startup_intc2_irq(unsigned int irq)
45{
46 enable_intc2_irq(irq);
47 return 0; /* never anything pending */
48}
49
50static struct hw_interrupt_type intc2_irq_type = {
51 "INTC2-IRQ",
52 startup_intc2_irq,
53 shutdown_intc2_irq,
54 enable_intc2_irq,
55 disable_intc2_irq,
56 mask_and_ack_intc2,
57 end_intc2_irq
58};
59
60static void disable_intc2_irq(unsigned int irq)
61{
62 int irq_offset = irq - INTC2_FIRST_IRQ;
63 int msk_shift, msk_offset;
64
65 // Sanity check
66 if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS))
67 return;
68
69 msk_shift = intc2_data[irq_offset].msk_shift;
70 msk_offset = intc2_data[irq_offset].msk_offset;
71
72 ctrl_outl(1<<msk_shift,
73 INTC2_BASE+INTC2_INTMSK_OFFSET+msk_offset);
74}
75
76static void enable_intc2_irq(unsigned int irq)
77{
78 int irq_offset = irq - INTC2_FIRST_IRQ;
79 int msk_shift, msk_offset;
80
81 /* Sanity check */
82 if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS))
83 return;
84
85 msk_shift = intc2_data[irq_offset].msk_shift;
86 msk_offset = intc2_data[irq_offset].msk_offset;
87
88 ctrl_outl(1<<msk_shift,
89 INTC2_BASE+INTC2_INTMSKCLR_OFFSET+msk_offset);
90}
91
92static void mask_and_ack_intc2(unsigned int irq)
93{
94 disable_intc2_irq(irq);
95}
96
97static void end_intc2_irq(unsigned int irq)
98{
99 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
100 enable_intc2_irq(irq);
101
102#ifdef CONFIG_CPU_SUBTYPE_ST40
103 if (intc2_data[irq - INTC2_FIRST_IRQ].clear_irq)
104 intc2_data[irq - INTC2_FIRST_IRQ].clear_irq (irq);
105#endif
106}
107
108/*
109 * Setup an INTC2 style interrupt.
110 * NOTE: Unlike IPR interrupts, parameters are not shifted by this code,
111 * allowing the use of the numbers straight out of the datasheet.
112 * For example:
113 * PIO1 which is INTPRI00[19,16] and INTMSK00[13]
114 * would be: ^ ^ ^ ^
115 * | | | |
116 * make_intc2_irq(84, 0, 16, 0, 13);
117 */
118void make_intc2_irq(unsigned int irq,
119 unsigned int ipr_offset, unsigned int ipr_shift,
120 unsigned int msk_offset, unsigned int msk_shift,
121 unsigned int priority)
122{
123 int irq_offset = irq - INTC2_FIRST_IRQ;
124 unsigned int flags;
125 unsigned long ipr;
126
127 if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS))
128 return;
129
130 disable_irq_nosync(irq);
131
132 /* Fill the data we need */
133 intc2_data[irq_offset].msk_offset = msk_offset;
134 intc2_data[irq_offset].msk_shift = msk_shift;
135#ifdef CONFIG_CPU_SUBTYPE_ST40
136 intc2_data[irq_offset].clear_irq = NULL;
137#endif
138
139 /* Set the priority level */
140 local_irq_save(flags);
141
142 ipr=ctrl_inl(INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset);
143 ipr&=~(0xf<<ipr_shift);
144 ipr|=(priority)<<ipr_shift;
145 ctrl_outl(ipr, INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset);
146
147 local_irq_restore(flags);
148
149 irq_desc[irq].handler=&intc2_irq_type;
150
151 disable_intc2_irq(irq);
152}
153
154#ifdef CONFIG_CPU_SUBTYPE_ST40
155
156struct intc2_init {
157 unsigned short irq;
158 unsigned char ipr_offset, ipr_shift;
159 unsigned char msk_offset, msk_shift;
160};
161
162static struct intc2_init intc2_init_data[] __initdata = {
163 {64, 0, 0, 0, 0}, /* PCI serr */
164 {65, 0, 4, 0, 1}, /* PCI err */
165 {66, 0, 4, 0, 2}, /* PCI ad */
166 {67, 0, 4, 0, 3}, /* PCI pwd down */
167 {72, 0, 8, 0, 5}, /* DMAC INT0 */
168 {73, 0, 8, 0, 6}, /* DMAC INT1 */
169 {74, 0, 8, 0, 7}, /* DMAC INT2 */
170 {75, 0, 8, 0, 8}, /* DMAC INT3 */
171 {76, 0, 8, 0, 9}, /* DMAC INT4 */
172 {78, 0, 8, 0, 11}, /* DMAC ERR */
173 {80, 0, 12, 0, 12}, /* PIO0 */
174 {84, 0, 16, 0, 13}, /* PIO1 */
175 {88, 0, 20, 0, 14}, /* PIO2 */
176 {112, 4, 0, 4, 0}, /* Mailbox */
177#ifdef CONFIG_CPU_SUBTYPE_ST40GX1
178 {116, 4, 4, 4, 4}, /* SSC0 */
179 {120, 4, 8, 4, 8}, /* IR Blaster */
180 {124, 4, 12, 4, 12}, /* USB host */
181 {128, 4, 16, 4, 16}, /* Video processor BLITTER */
182 {132, 4, 20, 4, 20}, /* UART0 */
183 {134, 4, 20, 4, 22}, /* UART2 */
184 {136, 4, 24, 4, 24}, /* IO_PIO0 */
185 {140, 4, 28, 4, 28}, /* EMPI */
186 {144, 8, 0, 8, 0}, /* MAFE */
187 {148, 8, 4, 8, 4}, /* PWM */
188 {152, 8, 8, 8, 8}, /* SSC1 */
189 {156, 8, 12, 8, 12}, /* IO_PIO1 */
190 {160, 8, 16, 8, 16}, /* USB target */
191 {164, 8, 20, 8, 20}, /* UART1 */
192 {168, 8, 24, 8, 24}, /* Teletext */
193 {172, 8, 28, 8, 28}, /* VideoSync VTG */
194 {173, 8, 28, 8, 29}, /* VideoSync DVP0 */
195 {174, 8, 28, 8, 30}, /* VideoSync DVP1 */
196#endif
197};
198
199void __init init_IRQ_intc2(void)
200{
201 struct intc2_init *p;
202
203 printk(KERN_ALERT "init_IRQ_intc2\n");
204
205 for (p = intc2_init_data;
206 p<intc2_init_data+ARRAY_SIZE(intc2_init_data);
207 p++) {
208 make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift,
209 p-> msk_offset, p->msk_shift, 13);
210 }
211}
212
213/* Adds a termination callback to the interrupt */
214void intc2_add_clear_irq(int irq, int (*fn)(int))
215{
216 if (irq < INTC2_FIRST_IRQ)
217 return;
218
219 intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn;
220}
221
222#endif /* CONFIG_CPU_SUBTYPE_ST40 */
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
new file mode 100644
index 000000000000..42427b79697b
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -0,0 +1,138 @@
1/*
2 * arch/sh/kernel/cpu/sh4/probe.c
3 *
4 * CPU Subtype Probing for SH-4.
5 *
6 * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt
7 * Copyright (C) 2003 Richard Curnow
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/init.h>
15#include <asm/processor.h>
16#include <asm/cache.h>
17#include <asm/io.h>
18
19int __init detect_cpu_and_cache_system(void)
20{
21 unsigned long pvr, prr, cvr;
22 unsigned long size;
23
24 static unsigned long sizes[16] = {
25 [1] = (1 << 12),
26 [2] = (1 << 13),
27 [4] = (1 << 14),
28 [8] = (1 << 15),
29 [9] = (1 << 16)
30 };
31
32 pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff;
33 prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
34 cvr = (ctrl_inl(CCN_CVR));
35
36 /*
37 * Setup some sane SH-4 defaults for the icache
38 */
39 cpu_data->icache.way_incr = (1 << 13);
40 cpu_data->icache.entry_shift = 5;
41 cpu_data->icache.entry_mask = 0x1fe0;
42 cpu_data->icache.sets = 256;
43 cpu_data->icache.ways = 1;
44 cpu_data->icache.linesz = L1_CACHE_BYTES;
45
46 /*
47 * And again for the dcache ..
48 */
49 cpu_data->dcache.way_incr = (1 << 14);
50 cpu_data->dcache.entry_shift = 5;
51 cpu_data->dcache.entry_mask = 0x3fe0;
52 cpu_data->dcache.sets = 512;
53 cpu_data->dcache.ways = 1;
54 cpu_data->dcache.linesz = L1_CACHE_BYTES;
55
56 /* Set the FPU flag, virtually all SH-4's have one */
57 cpu_data->flags |= CPU_HAS_FPU;
58
59 /*
60 * Probe the underlying processor version/revision and
61 * adjust cpu_data setup accordingly.
62 */
63 switch (pvr) {
64 case 0x205:
65 cpu_data->type = CPU_SH7750;
66 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER;
67 break;
68 case 0x206:
69 cpu_data->type = CPU_SH7750S;
70 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER;
71 break;
72 case 0x1100:
73 cpu_data->type = CPU_SH7751;
74 break;
75 case 0x2000:
76 cpu_data->type = CPU_SH73180;
77 cpu_data->icache.ways = 4;
78 cpu_data->dcache.ways = 4;
79 cpu_data->flags &= ~CPU_HAS_FPU;
80 break;
81 case 0x8000:
82 cpu_data->type = CPU_ST40RA;
83 break;
84 case 0x8100:
85 cpu_data->type = CPU_ST40GX1;
86 break;
87 case 0x700:
88 cpu_data->type = CPU_SH4_501;
89 cpu_data->icache.ways = 2;
90 cpu_data->dcache.ways = 2;
91
92 /* No FPU on the SH4-500 series.. */
93 cpu_data->flags &= ~CPU_HAS_FPU;
94 break;
95 case 0x600:
96 cpu_data->type = CPU_SH4_202;
97 cpu_data->icache.ways = 2;
98 cpu_data->dcache.ways = 2;
99 break;
100 case 0x500 ... 0x501:
101 switch (prr) {
102 case 0x10: cpu_data->type = CPU_SH7750R; break;
103 case 0x11: cpu_data->type = CPU_SH7751R; break;
104 case 0x50: cpu_data->type = CPU_SH7760; break;
105 }
106
107 cpu_data->icache.ways = 2;
108 cpu_data->dcache.ways = 2;
109
110 break;
111 default:
112 cpu_data->type = CPU_SH_NONE;
113 break;
114 }
115
116 /*
117 * On anything that's not a direct-mapped cache, look to the CVR
118 * for I/D-cache specifics.
119 */
120 if (cpu_data->icache.ways > 1) {
121 size = sizes[(cvr >> 20) & 0xf];
122 cpu_data->icache.way_incr = (size >> 1);
123 cpu_data->icache.sets = (size >> 6);
124 cpu_data->icache.entry_mask =
125 (cpu_data->icache.way_incr - (1 << 5));
126 }
127
128 if (cpu_data->dcache.ways > 1) {
129 size = sizes[(cvr >> 16) & 0xf];
130 cpu_data->dcache.way_incr = (size >> 1);
131 cpu_data->dcache.sets = (size >> 6);
132 cpu_data->dcache.entry_mask =
133 (cpu_data->dcache.way_incr - (1 << 5));
134 }
135
136 return 0;
137}
138
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
new file mode 100644
index 000000000000..8437ea7430fe
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -0,0 +1,453 @@
1/*
2 * arch/sh/kernel/cpu/sq.c
3 *
4 * General management API for SH-4 integrated Store Queues
5 *
6 * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt
7 * Copyright (C) 2001, 2002 M. R. Brown
8 *
9 * Some of this code has been adopted directly from the old arch/sh/mm/sq.c
10 * hack that was part of the LinuxDC project. For all intents and purposes,
11 * this is a completely new interface that really doesn't have much in common
12 * with the old zone-based approach at all. In fact, it's only listed here for
13 * general completeness.
14 *
15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file "COPYING" in the main directory of this archive
17 * for more details.
18 */
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/config.h>
23#include <linux/slab.h>
24#include <linux/list.h>
25#include <linux/proc_fs.h>
26#include <linux/miscdevice.h>
27#include <linux/vmalloc.h>
28
29#include <asm/io.h>
30#include <asm/page.h>
31#include <asm/mmu_context.h>
32#include <asm/cpu/sq.h>
33
34static LIST_HEAD(sq_mapping_list);
35static DEFINE_SPINLOCK(sq_mapping_lock);
36
37/**
38 * sq_flush - Flush (prefetch) the store queue cache
39 * @addr: the store queue address to flush
40 *
41 * Executes a prefetch instruction on the specified store queue cache,
42 * so that the cached data is written to physical memory.
43 */
44inline void sq_flush(void *addr)
45{
46 __asm__ __volatile__ ("pref @%0" : : "r" (addr) : "memory");
47}
48
49/**
50 * sq_flush_range - Flush (prefetch) a specific SQ range
51 * @start: the store queue address to start flushing from
52 * @len: the length to flush
53 *
54 * Flushes the store queue cache from @start to @start + @len in a
55 * linear fashion.
56 */
57void sq_flush_range(unsigned long start, unsigned int len)
58{
59 volatile unsigned long *sq = (unsigned long *)start;
60 unsigned long dummy;
61
62 /* Flush the queues */
63 for (len >>= 5; len--; sq += 8)
64 sq_flush((void *)sq);
65
66 /* Wait for completion */
67 dummy = ctrl_inl(P4SEG_STORE_QUE);
68
69 ctrl_outl(0, P4SEG_STORE_QUE + 0);
70 ctrl_outl(0, P4SEG_STORE_QUE + 8);
71}
72
73static struct sq_mapping *__sq_alloc_mapping(unsigned long virt, unsigned long phys, unsigned long size, const char *name)
74{
75 struct sq_mapping *map;
76
77 if (virt + size > SQ_ADDRMAX)
78 return ERR_PTR(-ENOSPC);
79
80 map = kmalloc(sizeof(struct sq_mapping), GFP_KERNEL);
81 if (!map)
82 return ERR_PTR(-ENOMEM);
83
84 INIT_LIST_HEAD(&map->list);
85
86 map->sq_addr = virt;
87 map->addr = phys;
88 map->size = size + 1;
89 map->name = name;
90
91 list_add(&map->list, &sq_mapping_list);
92
93 return map;
94}
95
96static unsigned long __sq_get_next_addr(void)
97{
98 if (!list_empty(&sq_mapping_list)) {
99 struct list_head *pos, *tmp;
100
101 /*
102 * Read one off the list head, as it will have the highest
103 * mapped allocation. Set the next one up right above it.
104 *
105 * This is somewhat sub-optimal, as we don't look at
106 * gaps between allocations or anything lower then the
107 * highest-level allocation.
108 *
109 * However, in the interest of performance and the general
110 * lack of desire to do constant list rebalancing, we don't
111 * worry about it.
112 */
113 list_for_each_safe(pos, tmp, &sq_mapping_list) {
114 struct sq_mapping *entry;
115
116 entry = list_entry(pos, typeof(*entry), list);
117
118 return entry->sq_addr + entry->size;
119 }
120 }
121
122 return P4SEG_STORE_QUE;
123}
124
125/**
126 * __sq_remap - Perform a translation from the SQ to a phys addr
127 * @map: sq mapping containing phys and store queue addresses.
128 *
129 * Maps the store queue address specified in the mapping to the physical
130 * address specified in the mapping.
131 */
132static struct sq_mapping *__sq_remap(struct sq_mapping *map)
133{
134 unsigned long flags, pteh, ptel;
135 struct vm_struct *vma;
136 pgprot_t pgprot;
137
138 /*
139 * Without an MMU (or with it turned off), this is much more
140 * straightforward, as we can just load up each queue's QACR with
141 * the physical address appropriately masked.
142 */
143
144 ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
145 ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
146
147#ifdef CONFIG_MMU
148 /*
149 * With an MMU on the other hand, things are slightly more involved.
150 * Namely, we have to have a direct mapping between the SQ addr and
151 * the associated physical address in the UTLB by way of setting up
152 * a virt<->phys translation by hand. We do this by simply specifying
153 * the SQ addr in UTLB.VPN and the associated physical address in
154 * UTLB.PPN.
155 *
156 * Notably, even though this is a special case translation, and some
157 * of the configuration bits are meaningless, we're still required
158 * to have a valid ASID context in PTEH.
159 *
160 * We could also probably get by without explicitly setting PTEA, but
161 * we do it here just for good measure.
162 */
163 spin_lock_irqsave(&sq_mapping_lock, flags);
164
165 pteh = map->sq_addr;
166 ctrl_outl((pteh & MMU_VPN_MASK) | get_asid(), MMU_PTEH);
167
168 ptel = map->addr & PAGE_MASK;
169 ctrl_outl(((ptel >> 28) & 0xe) | (ptel & 0x1), MMU_PTEA);
170
171 pgprot = pgprot_noncached(PAGE_KERNEL);
172
173 ptel &= _PAGE_FLAGS_HARDWARE_MASK;
174 ptel |= pgprot_val(pgprot);
175 ctrl_outl(ptel, MMU_PTEL);
176
177 __asm__ __volatile__ ("ldtlb" : : : "memory");
178
179 spin_unlock_irqrestore(&sq_mapping_lock, flags);
180
181 /*
182 * Next, we need to map ourselves in the kernel page table, so that
183 * future accesses after a TLB flush will be handled when we take a
184 * page fault.
185 *
186 * Theoretically we could just do this directly and not worry about
187 * setting up the translation by hand ahead of time, but for the
188 * cases where we want a one-shot SQ mapping followed by a quick
189 * writeout before we hit the TLB flush, we do it anyways. This way
190 * we at least save ourselves the initial page fault overhead.
191 */
192 vma = __get_vm_area(map->size, VM_ALLOC, map->sq_addr, SQ_ADDRMAX);
193 if (!vma)
194 return ERR_PTR(-ENOMEM);
195
196 vma->phys_addr = map->addr;
197
198 if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr,
199 map->size, pgprot_val(pgprot))) {
200 vunmap(vma->addr);
201 return NULL;
202 }
203#endif /* CONFIG_MMU */
204
205 return map;
206}
207
208/**
209 * sq_remap - Map a physical address through the Store Queues
210 * @phys: Physical address of mapping.
211 * @size: Length of mapping.
212 * @name: User invoking mapping.
213 *
214 * Remaps the physical address @phys through the next available store queue
215 * address of @size length. @name is logged at boot time as well as through
216 * the procfs interface.
217 *
218 * A pre-allocated and filled sq_mapping pointer is returned, and must be
219 * cleaned up with a call to sq_unmap() when the user is done with the
220 * mapping.
221 */
222struct sq_mapping *sq_remap(unsigned long phys, unsigned int size, const char *name)
223{
224 struct sq_mapping *map;
225 unsigned long virt, end;
226 unsigned int psz;
227
228 /* Don't allow wraparound or zero size */
229 end = phys + size - 1;
230 if (!size || end < phys)
231 return NULL;
232 /* Don't allow anyone to remap normal memory.. */
233 if (phys < virt_to_phys(high_memory))
234 return NULL;
235
236 phys &= PAGE_MASK;
237
238 size = PAGE_ALIGN(end + 1) - phys;
239 virt = __sq_get_next_addr();
240 psz = (size + (PAGE_SIZE - 1)) / PAGE_SIZE;
241 map = __sq_alloc_mapping(virt, phys, size, name);
242
243 printk("sqremap: %15s [%4d page%s] va 0x%08lx pa 0x%08lx\n",
244 map->name ? map->name : "???",
245 psz, psz == 1 ? " " : "s",
246 map->sq_addr, map->addr);
247
248 return __sq_remap(map);
249}
250
251/**
252 * sq_unmap - Unmap a Store Queue allocation
253 * @map: Pre-allocated Store Queue mapping.
254 *
255 * Unmaps the store queue allocation @map that was previously created by
256 * sq_remap(). Also frees up the pte that was previously inserted into
257 * the kernel page table and discards the UTLB translation.
258 */
259void sq_unmap(struct sq_mapping *map)
260{
261 if (map->sq_addr > (unsigned long)high_memory)
262 vfree((void *)(map->sq_addr & PAGE_MASK));
263
264 list_del(&map->list);
265 kfree(map);
266}
267
268/**
269 * sq_clear - Clear a store queue range
270 * @addr: Address to start clearing from.
271 * @len: Length to clear.
272 *
273 * A quick zero-fill implementation for clearing out memory that has been
274 * remapped through the store queues.
275 */
276void sq_clear(unsigned long addr, unsigned int len)
277{
278 int i;
279
280 /* Clear out both queues linearly */
281 for (i = 0; i < 8; i++) {
282 ctrl_outl(0, addr + i + 0);
283 ctrl_outl(0, addr + i + 8);
284 }
285
286 sq_flush_range(addr, len);
287}
288
289/**
290 * sq_vma_unmap - Unmap a VMA range
291 * @area: VMA containing range.
292 * @addr: Start of range.
293 * @len: Length of range.
294 *
295 * Searches the sq_mapping_list for a mapping matching the sq addr @addr,
296 * and subsequently frees up the entry. Further cleanup is done by generic
297 * code.
298 */
299static void sq_vma_unmap(struct vm_area_struct *area,
300 unsigned long addr, size_t len)
301{
302 struct list_head *pos, *tmp;
303
304 list_for_each_safe(pos, tmp, &sq_mapping_list) {
305 struct sq_mapping *entry;
306
307 entry = list_entry(pos, typeof(*entry), list);
308
309 if (entry->sq_addr == addr) {
310 /*
311 * We could probably get away without doing the tlb flush
312 * here, as generic code should take care of most of this
313 * when unmapping the rest of the VMA range for us. Leave
314 * it in for added sanity for the time being..
315 */
316 __flush_tlb_page(get_asid(), entry->sq_addr & PAGE_MASK);
317
318 list_del(&entry->list);
319 kfree(entry);
320
321 return;
322 }
323 }
324}
325
326/**
327 * sq_vma_sync - Sync a VMA range
328 * @area: VMA containing range.
329 * @start: Start of range.
330 * @len: Length of range.
331 * @flags: Additional flags.
332 *
333 * Synchronizes an sq mapped range by flushing the store queue cache for
334 * the duration of the mapping.
335 *
336 * Used internally for user mappings, which must use msync() to prefetch
337 * the store queue cache.
338 */
339static int sq_vma_sync(struct vm_area_struct *area,
340 unsigned long start, size_t len, unsigned int flags)
341{
342 sq_flush_range(start, len);
343
344 return 0;
345}
346
347static struct vm_operations_struct sq_vma_ops = {
348 .unmap = sq_vma_unmap,
349 .sync = sq_vma_sync,
350};
351
352/**
353 * sq_mmap - mmap() for /dev/cpu/sq
354 * @file: unused.
355 * @vma: VMA to remap.
356 *
357 * Remap the specified vma @vma through the store queues, and setup associated
358 * information for the new mapping. Also build up the page tables for the new
359 * area.
360 */
361static int sq_mmap(struct file *file, struct vm_area_struct *vma)
362{
363 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
364 unsigned long size = vma->vm_end - vma->vm_start;
365 struct sq_mapping *map;
366
367 /*
368 * We're not interested in any arbitrary virtual address that has
369 * been stuck in the VMA, as we already know what addresses we
370 * want. Save off the size, and reposition the VMA to begin at
371 * the next available sq address.
372 */
373 vma->vm_start = __sq_get_next_addr();
374 vma->vm_end = vma->vm_start + size;
375
376 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
377
378 vma->vm_flags |= VM_IO | VM_RESERVED;
379
380 map = __sq_alloc_mapping(vma->vm_start, offset, size, "Userspace");
381
382 if (io_remap_pfn_range(vma, map->sq_addr, map->addr >> PAGE_SHIFT,
383 size, vma->vm_page_prot))
384 return -EAGAIN;
385
386 vma->vm_ops = &sq_vma_ops;
387
388 return 0;
389}
390
391#ifdef CONFIG_PROC_FS
392static int sq_mapping_read_proc(char *buf, char **start, off_t off,
393 int len, int *eof, void *data)
394{
395 struct list_head *pos;
396 char *p = buf;
397
398 list_for_each_prev(pos, &sq_mapping_list) {
399 struct sq_mapping *entry;
400
401 entry = list_entry(pos, typeof(*entry), list);
402
403 p += sprintf(p, "%08lx-%08lx [%08lx]: %s\n", entry->sq_addr,
404 entry->sq_addr + entry->size - 1, entry->addr,
405 entry->name);
406 }
407
408 return p - buf;
409}
410#endif
411
412static struct file_operations sq_fops = {
413 .owner = THIS_MODULE,
414 .mmap = sq_mmap,
415};
416
417static struct miscdevice sq_dev = {
418 .minor = STORE_QUEUE_MINOR,
419 .name = "sq",
420 .devfs_name = "cpu/sq",
421 .fops = &sq_fops,
422};
423
424static int __init sq_api_init(void)
425{
426 printk(KERN_NOTICE "sq: Registering store queue API.\n");
427
428#ifdef CONFIG_PROC_FS
429 create_proc_read_entry("sq_mapping", 0, 0, sq_mapping_read_proc, 0);
430#endif
431
432 return misc_register(&sq_dev);
433}
434
435static void __exit sq_api_exit(void)
436{
437 misc_deregister(&sq_dev);
438}
439
440module_init(sq_api_init);
441module_exit(sq_api_exit);
442
443MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>");
444MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues");
445MODULE_LICENSE("GPL");
446MODULE_ALIAS_MISCDEV(STORE_QUEUE_MINOR);
447
448EXPORT_SYMBOL(sq_remap);
449EXPORT_SYMBOL(sq_unmap);
450EXPORT_SYMBOL(sq_clear);
451EXPORT_SYMBOL(sq_flush);
452EXPORT_SYMBOL(sq_flush_range);
453
diff --git a/arch/sh/kernel/cpu/ubc.S b/arch/sh/kernel/cpu/ubc.S
new file mode 100644
index 000000000000..0c569b20e1c1
--- /dev/null
+++ b/arch/sh/kernel/cpu/ubc.S
@@ -0,0 +1,59 @@
1/*
2 * arch/sh/kernel/ubc.S
3 *
4 * Set of management routines for the User Break Controller (UBC)
5 *
6 * Copyright (C) 2002 Paul Mundt
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/linkage.h>
14#include <asm/ubc.h>
15
16#define STBCR2 0xffc00010
17
18ENTRY(ubc_sleep)
19 mov #0, r0
20
21 mov.l 1f, r1 ! Zero out UBC_BBRA ..
22 mov.w r0, @r1
23
24 mov.l 2f, r1 ! .. same for BBRB ..
25 mov.w r0, @r1
26
27 mov.l 3f, r1 ! .. and again for BRCR.
28 mov.w r0, @r1
29
30 mov.w @r1, r0 ! Dummy read BRCR
31
32 mov.l 4f, r1 ! Set MSTP5 in STBCR2
33 mov.b @r1, r0
34 or #0x01, r0
35 mov.b r0, @r1
36
37 mov.b @r1, r0 ! Two dummy reads ..
38 mov.b @r1, r0
39
40 rts
41 nop
42
43ENTRY(ubc_wakeup)
44 mov.l 4f, r1 ! Clear MSTP5
45 mov.b @r1, r0
46 and #0xfe, r0
47 mov.b r0, @r1
48
49 mov.b @r1, r0 ! Two more dummy reads ..
50 mov.b @r1, r0
51
52 rts
53 nop
54
551: .long UBC_BBRA
562: .long UBC_BBRB
573: .long UBC_BRCR
584: .long STBCR2
59
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
new file mode 100644
index 000000000000..e0b384bef55f
--- /dev/null
+++ b/arch/sh/kernel/cpufreq.c
@@ -0,0 +1,218 @@
1/*
2 * arch/sh/kernel/cpufreq.c
3 *
4 * cpufreq driver for the SuperH processors.
5 *
6 * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt
7 * Copyright (C) 2002 M. R. Brown
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/types.h>
15#include <linux/cpufreq.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/cpumask.h>
22#include <linux/smp.h>
23
24#include <asm/processor.h>
25#include <asm/watchdog.h>
26#include <asm/freq.h>
27#include <asm/io.h>
28
29/*
30 * For SuperH, each policy change requires that we change the IFC, BFC, and
31 * PFC at the same time. Here we define sane values that won't trash the
32 * system.
33 *
34 * Note the max set is computed at runtime, we use the divisors that we booted
35 * with to setup our maximum operating frequencies.
36 */
37struct clock_set {
38 unsigned int ifc;
39 unsigned int bfc;
40 unsigned int pfc;
41} clock_sets[] = {
42#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH2)
43 { 0, 0, 0 }, /* not implemented yet */
44#elif defined(CONFIG_CPU_SH4)
45 { 4, 8, 8 }, /* min - IFC: 1/4, BFC: 1/8, PFC: 1/8 */
46 { 1, 2, 2 }, /* max - IFC: 1, BFC: 1/2, PFC: 1/2 */
47#endif
48};
49
50#define MIN_CLOCK_SET 0
51#define MAX_CLOCK_SET (ARRAY_SIZE(clock_sets) - 1)
52
53/*
54 * For the time being, we only support two frequencies, which in turn are
55 * aimed at the POWERSAVE and PERFORMANCE policies, which in turn are derived
56 * directly from the respective min/max clock sets. Technically we could
57 * support a wider range of frequencies, but these vary far too much for each
58 * CPU subtype (and we'd have to construct a frequency table for each subtype).
59 *
60 * Maybe something to implement in the future..
61 */
62#define SH_FREQ_MAX 0
63#define SH_FREQ_MIN 1
64
65static struct cpufreq_frequency_table sh_freqs[] = {
66 { SH_FREQ_MAX, 0 },
67 { SH_FREQ_MIN, 0 },
68 { 0, CPUFREQ_TABLE_END },
69};
70
71static void sh_cpufreq_update_clocks(unsigned int set)
72{
73 current_cpu_data.cpu_clock = current_cpu_data.master_clock / clock_sets[set].ifc;
74 current_cpu_data.bus_clock = current_cpu_data.master_clock / clock_sets[set].bfc;
75 current_cpu_data.module_clock = current_cpu_data.master_clock / clock_sets[set].pfc;
76 current_cpu_data.loops_per_jiffy = loops_per_jiffy;
77}
78
79/* XXX: This needs to be split out per CPU and CPU subtype. */
80/*
81 * Here we notify other drivers of the proposed change and the final change.
82 */
83static int sh_cpufreq_setstate(unsigned int cpu, unsigned int set)
84{
85 unsigned short frqcr = ctrl_inw(FRQCR);
86 cpumask_t cpus_allowed;
87 struct cpufreq_freqs freqs;
88
89 if (!cpu_online(cpu))
90 return -ENODEV;
91
92 cpus_allowed = current->cpus_allowed;
93 set_cpus_allowed(current, cpumask_of_cpu(cpu));
94
95 BUG_ON(smp_processor_id() != cpu);
96
97 freqs.cpu = cpu;
98 freqs.old = current_cpu_data.cpu_clock / 1000;
99 freqs.new = (current_cpu_data.master_clock / clock_sets[set].ifc) / 1000;
100
101 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
102#if defined(CONFIG_CPU_SH3)
103 frqcr |= (newstate & 0x4000) << 14;
104 frqcr |= (newstate & 0x000c) << 2;
105#elif defined(CONFIG_CPU_SH4)
106 /*
107 * FRQCR.PLL2EN is 1, we need to allow the PLL to stabilize by
108 * initializing the WDT.
109 */
110 if (frqcr & (1 << 9)) {
111 __u8 csr;
112
113 /*
114 * Set the overflow period to the highest available,
115 * in this case a 1/4096 division ratio yields a 5.25ms
116 * overflow period. See asm-sh/watchdog.h for more
117 * information and a range of other divisors.
118 */
119 csr = sh_wdt_read_csr();
120 csr |= WTCSR_CKS_4096;
121 sh_wdt_write_csr(csr);
122
123 sh_wdt_write_cnt(0);
124 }
125 frqcr &= 0x0e00; /* Clear ifc, bfc, pfc */
126 frqcr |= get_ifc_value(clock_sets[set].ifc) << 6;
127 frqcr |= get_bfc_value(clock_sets[set].bfc) << 3;
128 frqcr |= get_pfc_value(clock_sets[set].pfc);
129#endif
130 ctrl_outw(frqcr, FRQCR);
131 sh_cpufreq_update_clocks(set);
132
133 set_cpus_allowed(current, cpus_allowed);
134 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
135
136 return 0;
137}
138
139static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
140{
141 unsigned int min_freq, max_freq;
142 unsigned int ifc, bfc, pfc;
143
144 if (!cpu_online(policy->cpu))
145 return -ENODEV;
146
147 /* Update our maximum clock set */
148 get_current_frequency_divisors(&ifc, &bfc, &pfc);
149 clock_sets[MAX_CLOCK_SET].ifc = ifc;
150 clock_sets[MAX_CLOCK_SET].bfc = bfc;
151 clock_sets[MAX_CLOCK_SET].pfc = pfc;
152
153 /* Convert from Hz to kHz */
154 max_freq = current_cpu_data.cpu_clock / 1000;
155 min_freq = (current_cpu_data.master_clock / clock_sets[MIN_CLOCK_SET].ifc) / 1000;
156
157 sh_freqs[SH_FREQ_MAX].frequency = max_freq;
158 sh_freqs[SH_FREQ_MIN].frequency = min_freq;
159
160 /* cpuinfo and default policy values */
161 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
162 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
163 policy->cur = max_freq;
164
165 return cpufreq_frequency_table_cpuinfo(policy, &sh_freqs[0]);
166}
167
168static int sh_cpufreq_verify(struct cpufreq_policy *policy)
169{
170 return cpufreq_frequency_table_verify(policy, &sh_freqs[0]);
171}
172
173static int sh_cpufreq_target(struct cpufreq_policy *policy,
174 unsigned int target_freq,
175 unsigned int relation)
176{
177 unsigned int set, idx = 0;
178
179 if (cpufreq_frequency_table_target(policy, &sh_freqs[0], target_freq, relation, &idx))
180 return -EINVAL;
181
182 set = (idx == SH_FREQ_MIN) ? MIN_CLOCK_SET : MAX_CLOCK_SET;
183
184 sh_cpufreq_setstate(policy->cpu, set);
185
186 return 0;
187}
188
189static struct cpufreq_driver sh_cpufreq_driver = {
190 .owner = THIS_MODULE,
191 .name = "SH cpufreq",
192 .init = sh_cpufreq_cpu_init,
193 .verify = sh_cpufreq_verify,
194 .target = sh_cpufreq_target,
195};
196
197static int __init sh_cpufreq_init(void)
198{
199 if (!current_cpu_data.cpu_clock)
200 return -EINVAL;
201 if (cpufreq_register_driver(&sh_cpufreq_driver))
202 return -EINVAL;
203
204 return 0;
205}
206
207static void __exit sh_cpufreq_exit(void)
208{
209 cpufreq_unregister_driver(&sh_cpufreq_driver);
210}
211
212module_init(sh_cpufreq_init);
213module_exit(sh_cpufreq_exit);
214
215MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
216MODULE_DESCRIPTION("cpufreq driver for SuperH");
217MODULE_LICENSE("GPL");
218
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
new file mode 100644
index 000000000000..1378db375e17
--- /dev/null
+++ b/arch/sh/kernel/early_printk.c
@@ -0,0 +1,137 @@
1/*
2 * arch/sh/kernel/early_printk.c
3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2002 M. R. Brown
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/console.h>
13#include <linux/tty.h>
14#include <linux/init.h>
15#include <asm/io.h>
16
17#ifdef CONFIG_SH_STANDARD_BIOS
18#include <asm/sh_bios.h>
19
20/*
21 * Print a string through the BIOS
22 */
23static void sh_console_write(struct console *co, const char *s,
24 unsigned count)
25{
26 sh_bios_console_write(s, count);
27}
28
29/*
30 * Setup initial baud/bits/parity. We do two things here:
31 * - construct a cflag setting for the first rs_open()
32 * - initialize the serial port
33 * Return non-zero if we didn't find a serial port.
34 */
35static int __init sh_console_setup(struct console *co, char *options)
36{
37 int cflag = CREAD | HUPCL | CLOCAL;
38
39 /*
40 * Now construct a cflag setting.
41 * TODO: this is a totally bogus cflag, as we have
42 * no idea what serial settings the BIOS is using, or
43 * even if its using the serial port at all.
44 */
45 cflag |= B115200 | CS8 | /*no parity*/0;
46
47 co->cflag = cflag;
48
49 return 0;
50}
51
52static struct console early_console = {
53 .name = "bios",
54 .write = sh_console_write,
55 .setup = sh_console_setup,
56 .flags = CON_PRINTBUFFER,
57 .index = -1,
58};
59#endif
60
61#ifdef CONFIG_EARLY_SCIF_CONSOLE
62#define SCIF_REG 0xffe80000
63
64static void scif_sercon_putc(int c)
65{
66 while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ;
67
68 ctrl_outb(c, SCIF_REG + 12);
69 ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10);
70
71 if (c == '\n')
72 scif_sercon_putc('\r');
73}
74
75static void scif_sercon_flush(void)
76{
77 ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10);
78
79 while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ;
80
81 ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10);
82}
83
84static void scif_sercon_write(struct console *con, const char *s, unsigned count)
85{
86 while (count-- > 0)
87 scif_sercon_putc(*s++);
88
89 scif_sercon_flush();
90}
91
92static int __init scif_sercon_setup(struct console *con, char *options)
93{
94 con->cflag = CREAD | HUPCL | CLOCAL | B115200 | CS8;
95
96 return 0;
97}
98
99static struct console early_console = {
100 .name = "sercon",
101 .write = scif_sercon_write,
102 .setup = scif_sercon_setup,
103 .flags = CON_PRINTBUFFER,
104 .index = -1,
105};
106
107void scif_sercon_init(int baud)
108{
109 ctrl_outw(0, SCIF_REG + 8);
110 ctrl_outw(0, SCIF_REG);
111
112 /* Set baud rate */
113 ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) /
114 (32 * baud) - 1, SCIF_REG + 4);
115
116 ctrl_outw(12, SCIF_REG + 24);
117 ctrl_outw(8, SCIF_REG + 24);
118 ctrl_outw(0, SCIF_REG + 32);
119 ctrl_outw(0x60, SCIF_REG + 16);
120 ctrl_outw(0, SCIF_REG + 36);
121 ctrl_outw(0x30, SCIF_REG + 8);
122}
123#endif
124
125void __init enable_early_printk(void)
126{
127#ifdef CONFIG_EARLY_SCIF_CONSOLE
128 scif_sercon_init(115200);
129#endif
130 register_console(&early_console);
131}
132
133void disable_early_printk(void)
134{
135 unregister_console(&early_console);
136}
137
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
new file mode 100644
index 000000000000..6615e4838ee4
--- /dev/null
+++ b/arch/sh/kernel/entry.S
@@ -0,0 +1,1149 @@
1/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $
2 *
3 * linux/arch/sh/entry.S
4 *
5 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
6 * Copyright (C) 2003 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 *
12 */
13
14#include <linux/sys.h>
15#include <linux/linkage.h>
16#include <linux/config.h>
17#include <asm/asm-offsets.h>
18#include <asm/thread_info.h>
19#include <asm/unistd.h>
20
21#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
22#define sys_nfsservctl sys_ni_syscall
23#endif
24
25#if !defined(CONFIG_MMU)
26#define sys_madvise sys_ni_syscall
27#define sys_readahead sys_ni_syscall
28#define sys_mprotect sys_ni_syscall
29#define sys_msync sys_ni_syscall
30#define sys_mlock sys_ni_syscall
31#define sys_munlock sys_ni_syscall
32#define sys_mlockall sys_ni_syscall
33#define sys_munlockall sys_ni_syscall
34#define sys_mremap sys_ni_syscall
35#define sys_mincore sys_ni_syscall
36#define sys_remap_file_pages sys_ni_syscall
37#endif
38
39! NOTE:
40! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
41! to be jumped is too far, but it causes illegal slot exception.
42
43/*
44 * entry.S contains the system-call and fault low-level handling routines.
45 * This also contains the timer-interrupt handler, as well as all interrupts
46 * and faults that can result in a task-switch.
47 *
48 * NOTE: This code handles signal-recognition, which happens every time
49 * after a timer-interrupt and after each system call.
50 *
51 * NOTE: This code uses a convention that instructions in the delay slot
52 * of a transfer-control instruction are indented by an extra space, thus:
53 *
54 * jmp @k0 ! control-transfer instruction
55 * ldc k1, ssr ! delay slot
56 *
57 * Stack layout in 'ret_from_syscall':
58 * ptrace needs to have all regs on the stack.
59 * if the order here is changed, it needs to be
60 * updated in ptrace.c and ptrace.h
61 *
62 * r0
63 * ...
64 * r15 = stack pointer
65 * spc
66 * pr
67 * ssr
68 * gbr
69 * mach
70 * macl
71 * syscall #
72 *
73 */
74
75ENOSYS = 38
76EINVAL = 22
77
78#if defined(CONFIG_CPU_SH3)
79TRA = 0xffffffd0
80EXPEVT = 0xffffffd4
81#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
82 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
83INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000)
84#else
85INTEVT = 0xffffffd8
86#endif
87MMU_TEA = 0xfffffffc ! TLB Exception Address Register
88#elif defined(CONFIG_CPU_SH4)
89TRA = 0xff000020
90EXPEVT = 0xff000024
91INTEVT = 0xff000028
92MMU_TEA = 0xff00000c ! TLB Exception Address Register
93#endif
94
95#if defined(CONFIG_KGDB_NMI)
96NMI_VEC = 0x1c0 ! Must catch early for debounce
97#endif
98
99/* Offsets to the stack */
100OFF_R0 = 0 /* Return value. New ABI also arg4 */
101OFF_R1 = 4 /* New ABI: arg5 */
102OFF_R2 = 8 /* New ABI: arg6 */
103OFF_R3 = 12 /* New ABI: syscall_nr */
104OFF_R4 = 16 /* New ABI: arg0 */
105OFF_R5 = 20 /* New ABI: arg1 */
106OFF_R6 = 24 /* New ABI: arg2 */
107OFF_R7 = 28 /* New ABI: arg3 */
108OFF_SP = (15*4)
109OFF_PC = (16*4)
110OFF_SR = (16*4+8)
111OFF_TRA = (16*4+6*4)
112
113
114#define k0 r0
115#define k1 r1
116#define k2 r2
117#define k3 r3
118#define k4 r4
119
120#define k_ex_code r2_bank /* r2_bank1 */
121#define g_imask r6 /* r6_bank1 */
122#define k_g_imask r6_bank /* r6_bank1 */
123#define current r7 /* r7_bank1 */
124
125/*
126 * Kernel mode register usage:
127 * k0 scratch
128 * k1 scratch
129 * k2 scratch (Exception code)
130 * k3 scratch (Return address)
131 * k4 scratch
132 * k5 reserved
133 * k6 Global Interrupt Mask (0--15 << 4)
134 * k7 CURRENT_THREAD_INFO (pointer to current thread info)
135 */
136
137!
138! TLB Miss / Initial Page write exception handling
139! _and_
140! TLB hits, but the access violate the protection.
141! It can be valid access, such as stack grow and/or C-O-W.
142!
143!
144! Find the pmd/pte entry and loadtlb
145! If it's not found, cause address error (SEGV)
146!
147! Although this could be written in assembly language (and it'd be faster),
148! this first version depends *much* on C implementation.
149!
150
151#define CLI() \
152 stc sr, r0; \
153 or #0xf0, r0; \
154 ldc r0, sr
155
156#define STI() \
157 mov.l __INV_IMASK, r11; \
158 stc sr, r10; \
159 and r11, r10; \
160 stc k_g_imask, r11; \
161 or r11, r10; \
162 ldc r10, sr
163
164#if defined(CONFIG_PREEMPT)
165# define preempt_stop() CLI()
166#else
167# define preempt_stop()
168# define resume_kernel restore_all
169#endif
170
171#if defined(CONFIG_MMU)
172 .align 2
173ENTRY(tlb_miss_load)
174 bra call_dpf
175 mov #0, r5
176
177 .align 2
178ENTRY(tlb_miss_store)
179 bra call_dpf
180 mov #1, r5
181
182 .align 2
183ENTRY(initial_page_write)
184 bra call_dpf
185 mov #1, r5
186
187 .align 2
188ENTRY(tlb_protection_violation_load)
189 bra call_dpf
190 mov #0, r5
191
192 .align 2
193ENTRY(tlb_protection_violation_store)
194 bra call_dpf
195 mov #1, r5
196
197call_dpf:
198 mov.l 1f, r0
199 mov r5, r8
200 mov.l @r0, r6
201 mov r6, r9
202 mov.l 2f, r0
203 sts pr, r10
204 jsr @r0
205 mov r15, r4
206 !
207 tst r0, r0
208 bf/s 0f
209 lds r10, pr
210 rts
211 nop
2120: STI()
213 mov.l 3f, r0
214 mov r9, r6
215 mov r8, r5
216 jmp @r0
217 mov r15, r4
218
219 .align 2
2201: .long MMU_TEA
2212: .long __do_page_fault
2223: .long do_page_fault
223
224 .align 2
225ENTRY(address_error_load)
226 bra call_dae
227 mov #0,r5 ! writeaccess = 0
228
229 .align 2
230ENTRY(address_error_store)
231 bra call_dae
232 mov #1,r5 ! writeaccess = 1
233
234 .align 2
235call_dae:
236 mov.l 1f, r0
237 mov.l @r0, r6 ! address
238 mov.l 2f, r0
239 jmp @r0
240 mov r15, r4 ! regs
241
242 .align 2
2431: .long MMU_TEA
2442: .long do_address_error
245#endif /* CONFIG_MMU */
246
247#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
248! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
249! If both are configured, handle the debug traps (breakpoints) in SW,
250! but still allow BIOS traps to FW.
251
252 .align 2
253debug_kernel:
254#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
255 /* Force BIOS call to FW (debug_trap put TRA in r8) */
256 mov r8,r0
257 shlr2 r0
258 cmp/eq #0x3f,r0
259 bt debug_kernel_fw
260#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
261
262debug_enter:
263#if defined(CONFIG_SH_KGDB)
264 /* Jump to kgdb, pass stacked regs as arg */
265debug_kernel_sw:
266 mov.l 3f, r0
267 jmp @r0
268 mov r15, r4
269 .align 2
2703: .long kgdb_handle_exception
271#endif /* CONFIG_SH_KGDB */
272
273#if defined(CONFIG_SH_STANDARD_BIOS)
274 /* Unwind the stack and jmp to the debug entry */
275debug_kernel_fw:
276 mov.l @r15+, r0
277 mov.l @r15+, r1
278 mov.l @r15+, r2
279 mov.l @r15+, r3
280 mov.l @r15+, r4
281 mov.l @r15+, r5
282 mov.l @r15+, r6
283 mov.l @r15+, r7
284 stc sr, r8
285 mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F
286 or r9, r8
287 ldc r8, sr ! here, change the register bank
288 mov.l @r15+, r8
289 mov.l @r15+, r9
290 mov.l @r15+, r10
291 mov.l @r15+, r11
292 mov.l @r15+, r12
293 mov.l @r15+, r13
294 mov.l @r15+, r14
295 mov.l @r15+, k0
296 ldc.l @r15+, spc
297 lds.l @r15+, pr
298 mov.l @r15+, k1
299 ldc.l @r15+, gbr
300 lds.l @r15+, mach
301 lds.l @r15+, macl
302 mov k0, r15
303 !
304 mov.l 2f, k0
305 mov.l @k0, k0
306 jmp @k0
307 ldc k1, ssr
308 .align 2
3091: .long 0x300000f0
3102: .long gdb_vbr_vector
311#endif /* CONFIG_SH_STANDARD_BIOS */
312
313#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
314
315
316 .align 2
317debug_trap:
318#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
319 mov #OFF_SR, r0
320 mov.l @(r0,r15), r0 ! get status register
321 shll r0
322 shll r0 ! kernel space?
323 bt/s debug_kernel
324#endif
325 mov.l @r15, r0 ! Restore R0 value
326 mov.l 1f, r8
327 jmp @r8
328 nop
329
330 .align 2
331ENTRY(exception_error)
332 !
333 STI()
334 mov.l 2f, r0
335 jmp @r0
336 nop
337
338!
339 .align 2
3401: .long break_point_trap_software
3412: .long do_exception_error
342
343 .align 2
344ret_from_exception:
345 preempt_stop()
346ret_from_irq:
347 !
348 mov #OFF_SR, r0
349 mov.l @(r0,r15), r0 ! get status register
350 shll r0
351 shll r0 ! kernel space?
352 bt/s resume_kernel ! Yes, it's from kernel, go back soon
353 GET_THREAD_INFO(r8)
354
355#ifdef CONFIG_PREEMPT
356 bra resume_userspace
357 nop
358ENTRY(resume_kernel)
359 mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
360 tst r0, r0
361 bf noresched
362need_resched:
363 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
364 tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
365 bt noresched
366
367 mov #OFF_SR, r0
368 mov.l @(r0,r15), r0 ! get status register
369 and #0xf0, r0 ! interrupts off (exception path)?
370 cmp/eq #0xf0, r0
371 bt noresched
372
373 mov.l 1f, r0
374 mov.l r0, @(TI_PRE_COUNT,r8)
375
376 STI()
377 mov.l 2f, r0
378 jsr @r0
379 nop
380 mov #0, r0
381 mov.l r0, @(TI_PRE_COUNT,r8)
382 CLI()
383
384 bra need_resched
385 nop
386noresched:
387 bra restore_all
388 nop
389
390 .align 2
3911: .long PREEMPT_ACTIVE
3922: .long schedule
393#endif
394
395ENTRY(resume_userspace)
396 ! r8: current_thread_info
397 CLI()
398 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
399 tst #_TIF_WORK_MASK, r0
400 bt/s restore_all
401 tst #_TIF_NEED_RESCHED, r0
402
403 .align 2
404work_pending:
405 ! r0: current_thread_info->flags
406 ! r8: current_thread_info
407 ! t: result of "tst #_TIF_NEED_RESCHED, r0"
408 bf/s work_resched
409 tst #_TIF_SIGPENDING, r0
410work_notifysig:
411 bt/s restore_all
412 mov r15, r4
413 mov #0, r5
414 mov.l 2f, r1
415 mova restore_all, r0
416 jmp @r1
417 lds r0, pr
418work_resched:
419#ifndef CONFIG_PREEMPT
420 ! gUSA handling
421 mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
422 mov r0, r1
423 shll r0
424 bf/s 1f
425 shll r0
426 bf/s 1f
427 mov #OFF_PC, r0
428 ! SP >= 0xc0000000 : gUSA mark
429 mov.l @(r0,r15), r2 ! get user space PC (program counter)
430 mov.l @(OFF_R0,r15), r3 ! end point
431 cmp/hs r3, r2 ! r2 >= r3?
432 bt 1f
433 add r3, r1 ! rewind point #2
434 mov.l r1, @(r0,r15) ! reset PC to rewind point #2
435 !
4361:
437#endif
438 mov.l 1f, r1
439 jsr @r1 ! schedule
440 nop
441 CLI()
442 !
443 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
444 tst #_TIF_WORK_MASK, r0
445 bt restore_all
446 bra work_pending
447 tst #_TIF_NEED_RESCHED, r0
448
449 .align 2
4501: .long schedule
4512: .long do_signal
452
453 .align 2
454syscall_exit_work:
455 ! r0: current_thread_info->flags
456 ! r8: current_thread_info
457 tst #_TIF_SYSCALL_TRACE, r0
458 bt/s work_pending
459 tst #_TIF_NEED_RESCHED, r0
460 STI()
461 ! XXX setup arguments...
462 mov.l 4f, r0 ! do_syscall_trace
463 jsr @r0
464 nop
465 bra resume_userspace
466 nop
467
468 .align 2
469syscall_trace_entry:
470 ! Yes it is traced.
471 ! XXX setup arguments...
472 mov.l 4f, r11 ! Call do_syscall_trace which notifies
473 jsr @r11 ! superior (will chomp R[0-7])
474 nop
475 ! Reload R0-R4 from kernel stack, where the
476 ! parent may have modified them using
477 ! ptrace(POKEUSR). (Note that R0-R2 are
478 ! used by the system call handler directly
479 ! from the kernel stack anyway, so don't need
480 ! to be reloaded here.) This allows the parent
481 ! to rewrite system calls and args on the fly.
482 mov.l @(OFF_R4,r15), r4 ! arg0
483 mov.l @(OFF_R5,r15), r5
484 mov.l @(OFF_R6,r15), r6
485 mov.l @(OFF_R7,r15), r7 ! arg3
486 mov.l @(OFF_R3,r15), r3 ! syscall_nr
487 ! Arrange for do_syscall_trace to be called
488 ! again as the system call returns.
489 mov.l 2f, r10 ! Number of syscalls
490 cmp/hs r10, r3
491 bf syscall_call
492 mov #-ENOSYS, r0
493 bra syscall_exit
494 mov.l r0, @(OFF_R0,r15) ! Return value
495
496/*
497 * Syscall interface:
498 *
499 * Syscall #: R3
500 * Arguments #0 to #3: R4--R7
501 * Arguments #4 to #6: R0, R1, R2
502 * TRA: (number of arguments + 0x10) x 4
503 *
504 * This code also handles delegating other traps to the BIOS/gdb stub
505 * according to:
506 *
507 * Trap number
508 * (TRA>>2) Purpose
509 * -------- -------
510 * 0x0-0xf old syscall ABI
511 * 0x10-0x1f new syscall ABI
512 * 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
513 *
514 * Note: When we're first called, the TRA value must be shifted
515 * right 2 bits in order to get the value that was used as the "trapa"
516 * argument.
517 */
518
519 .align 2
520 .globl ret_from_fork
521ret_from_fork:
522 mov.l 1f, r8
523 jsr @r8
524 mov r0, r4
525 bra syscall_exit
526 nop
527 .align 2
5281: .long schedule_tail
529 !
530ENTRY(system_call)
531 mov.l 1f, r9
532 mov.l @r9, r8 ! Read from TRA (Trap Address) Register
533 !
534 ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
535 mov #0x7f, r9
536 cmp/hi r9, r8
537 bt/s 0f
538 mov #OFF_TRA, r9
539 add r15, r9
540 !
541 mov.l r8, @r9 ! set TRA value to tra
542 STI()
543 ! Call the system call handler through the table.
544 ! First check for bad syscall number
545 mov r3, r9
546 mov.l 2f, r8 ! Number of syscalls
547 cmp/hs r8, r9
548 bf/s good_system_call
549 GET_THREAD_INFO(r8)
550syscall_badsys: ! Bad syscall number
551 mov #-ENOSYS, r0
552 bra resume_userspace
553 mov.l r0, @(OFF_R0,r15) ! Return value
554 !
5550:
556 bra debug_trap
557 nop
558 !
559good_system_call: ! Good syscall number
560 mov.l @(TI_FLAGS,r8), r8
561 mov #_TIF_SYSCALL_TRACE, r10
562 tst r10, r8
563 bf syscall_trace_entry
564 !
565syscall_call:
566 shll2 r9 ! x4
567 mov.l 3f, r8 ! Load the address of sys_call_table
568 add r8, r9
569 mov.l @r9, r8
570 jsr @r8 ! jump to specific syscall handler
571 nop
572 mov.l r0, @(OFF_R0,r15) ! save the return value
573 !
574syscall_exit:
575 CLI()
576 !
577 GET_THREAD_INFO(r8)
578 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
579 tst #_TIF_ALLWORK_MASK, r0
580 bf syscall_exit_work
581restore_all:
582 mov.l @r15+, r0
583 mov.l @r15+, r1
584 mov.l @r15+, r2
585 mov.l @r15+, r3
586 mov.l @r15+, r4
587 mov.l @r15+, r5
588 mov.l @r15+, r6
589 mov.l @r15+, r7
590 !
591 stc sr, r8
592 mov.l 7f, r9
593 or r9, r8 ! BL =1, RB=1
594 ldc r8, sr ! here, change the register bank
595 !
596 mov.l @r15+, r8
597 mov.l @r15+, r9
598 mov.l @r15+, r10
599 mov.l @r15+, r11
600 mov.l @r15+, r12
601 mov.l @r15+, r13
602 mov.l @r15+, r14
603 mov.l @r15+, k4 ! original stack pointer
604 ldc.l @r15+, spc
605 lds.l @r15+, pr
606 mov.l @r15+, k3 ! original SR
607 ldc.l @r15+, gbr
608 lds.l @r15+, mach
609 lds.l @r15+, macl
610 add #4, r15 ! Skip syscall number
611 !
612#ifdef CONFIG_SH_DSP
613 mov.l @r15+, k0 ! DSP mode marker
614 mov.l 5f, k1
615 cmp/eq k0, k1 ! Do we have a DSP stack frame?
616 bf skip_restore
617
618 stc sr, k0 ! Enable CPU DSP mode
619 or k1, k0 ! (within kernel it may be disabled)
620 ldc k0, sr
621 mov r2, k0 ! Backup r2
622
623 ! Restore DSP registers from stack
624 mov r15, r2
625 movs.l @r2+, a1
626 movs.l @r2+, a0g
627 movs.l @r2+, a1g
628 movs.l @r2+, m0
629 movs.l @r2+, m1
630 mov r2, r15
631
632 lds.l @r15+, a0
633 lds.l @r15+, x0
634 lds.l @r15+, x1
635 lds.l @r15+, y0
636 lds.l @r15+, y1
637 lds.l @r15+, dsr
638 ldc.l @r15+, rs
639 ldc.l @r15+, re
640 ldc.l @r15+, mod
641
642 mov k0, r2 ! Restore r2
643skip_restore:
644#endif
645 !
646 ! Calculate new SR value
647 mov k3, k2 ! original SR value
648 mov.l 9f, k1
649 and k1, k2 ! Mask orignal SR value
650 !
651 mov k3, k0 ! Calculate IMASK-bits
652 shlr2 k0
653 and #0x3c, k0
654 cmp/eq #0x3c, k0
655 bt/s 6f
656 shll2 k0
657 mov g_imask, k0
658 !
6596: or k0, k2 ! Set the IMASK-bits
660 ldc k2, ssr
661 !
662#if defined(CONFIG_KGDB_NMI)
663 ! Clear in_nmi
664 mov.l 4f, k0
665 mov #0, k1
666 mov.b k1, @k0
667#endif
668 mov.l @r15+, k2 ! restore EXPEVT
669 mov k4, r15
670 rte
671 nop
672
673 .align 2
6741: .long TRA
6752: .long NR_syscalls
6763: .long sys_call_table
6774: .long do_syscall_trace
6785: .long 0x00001000 ! DSP
6797: .long 0x30000000
6809:
681__INV_IMASK:
682 .long 0xffffff0f ! ~(IMASK)
683
684! Exception Vector Base
685!
686! Should be aligned page boundary.
687!
688 .balign 4096,0,4096
689ENTRY(vbr_base)
690 .long 0
691!
692 .balign 256,0,256
693general_exception:
694 mov.l 1f, k2
695 mov.l 2f, k3
696 bra handle_exception
697 mov.l @k2, k2
698 .align 2
6991: .long EXPEVT
7002: .long ret_from_exception
701!
702!
703 .balign 1024,0,1024
704tlb_miss:
705 mov.l 1f, k2
706 mov.l 4f, k3
707 bra handle_exception
708 mov.l @k2, k2
709!
710 .balign 512,0,512
711interrupt:
712 mov.l 2f, k2
713 mov.l 3f, k3
714#if defined(CONFIG_KGDB_NMI)
715 ! Debounce (filter nested NMI)
716 mov.l @k2, k0
717 mov.l 5f, k1
718 cmp/eq k1, k0
719 bf 0f
720 mov.l 6f, k1
721 tas.b @k1
722 bt 0f
723 rte
724 nop
725 .align 2
7265: .long NMI_VEC
7276: .long in_nmi
7280:
729#endif /* defined(CONFIG_KGDB_NMI) */
730 bra handle_exception
731 mov.l @k2, k2
732
733 .align 2
7341: .long EXPEVT
7352: .long INTEVT
7363: .long ret_from_irq
7374: .long ret_from_exception
738
739!
740!
741 .align 2
742handle_exception:
743 ! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
744 ! save all registers onto stack.
745 !
746 stc ssr, k0 ! Is it from kernel space?
747 shll k0 ! Check MD bit (bit30) by shifting it into...
748 shll k0 ! ...the T bit
749 bt/s 1f ! It's a kernel to kernel transition.
750 mov r15, k0 ! save original stack to k0
751 /* User space to kernel */
752 mov #0x20, k1
753 shll8 k1 ! k1 := 8192 (== THREAD_SIZE)
754 add current, k1
755 mov k1, r15 ! change to kernel stack
756 !
7571: mov #-1, k4
758 mov.l 2f, k1
759 !
760#ifdef CONFIG_SH_DSP
761 mov.l r2, @-r15 ! Save r2, we need another reg
762 stc sr, k4
763 mov.l 1f, r2
764 tst r2, k4 ! Check if in DSP mode
765 mov.l @r15+, r2 ! Restore r2 now
766 bt/s skip_save
767 mov #0, k4 ! Set marker for no stack frame
768
769 mov r2, k4 ! Backup r2 (in k4) for later
770
771 ! Save DSP registers on stack
772 stc.l mod, @-r15
773 stc.l re, @-r15
774 stc.l rs, @-r15
775 sts.l dsr, @-r15
776 sts.l y1, @-r15
777 sts.l y0, @-r15
778 sts.l x1, @-r15
779 sts.l x0, @-r15
780 sts.l a0, @-r15
781
782 ! GAS is broken, does not generate correct "movs.l Ds,@-As" instr.
783
784 ! FIXME: Make sure that this is still the case with newer toolchains,
785 ! as we're not at all interested in supporting ancient toolchains at
786 ! this point. -- PFM.
787
788 mov r15, r2
789 .word 0xf653 ! movs.l a1, @-r2
790 .word 0xf6f3 ! movs.l a0g, @-r2
791 .word 0xf6d3 ! movs.l a1g, @-r2
792 .word 0xf6c3 ! movs.l m0, @-r2
793 .word 0xf6e3 ! movs.l m1, @-r2
794 mov r2, r15
795
796 mov k4, r2 ! Restore r2
797 mov.l 1f, k4 ! Force DSP stack frame
798skip_save:
799 mov.l k4, @-r15 ! Push DSP mode marker onto stack
800#endif
801 ! Save the user registers on the stack.
802 mov.l k2, @-r15 ! EXPEVT
803 mov.l k4, @-r15 ! set TRA (default: -1)
804 !
805 sts.l macl, @-r15
806 sts.l mach, @-r15
807 stc.l gbr, @-r15
808 stc.l ssr, @-r15
809 sts.l pr, @-r15
810 stc.l spc, @-r15
811 !
812 lds k3, pr ! Set the return address to pr
813 !
814 mov.l k0, @-r15 ! save orignal stack
815 mov.l r14, @-r15
816 mov.l r13, @-r15
817 mov.l r12, @-r15
818 mov.l r11, @-r15
819 mov.l r10, @-r15
820 mov.l r9, @-r15
821 mov.l r8, @-r15
822 !
823 stc sr, r8 ! Back to normal register bank, and
824 or k1, r8 ! Block all interrupts
825 mov.l 3f, k1
826 and k1, r8 ! ...
827 ldc r8, sr ! ...changed here.
828 !
829 mov.l r7, @-r15
830 mov.l r6, @-r15
831 mov.l r5, @-r15
832 mov.l r4, @-r15
833 mov.l r3, @-r15
834 mov.l r2, @-r15
835 mov.l r1, @-r15
836 mov.l r0, @-r15
837 ! Then, dispatch to the handler, according to the exception code.
838 stc k_ex_code, r8
839 shlr2 r8
840 shlr r8
841 mov.l 4f, r9
842 add r8, r9
843 mov.l @r9, r9
844 jmp @r9
845 nop
846
847 .align 2
8481: .long 0x00001000 ! DSP=1
8492: .long 0x000080f0 ! FD=1, IMASK=15
8503: .long 0xcfffffff ! RB=0, BL=0
8514: .long exception_handling_table
852
853 .align 2
854ENTRY(exception_none)
855 rts
856 nop
857
858 .data
859ENTRY(sys_call_table)
860 .long sys_ni_syscall /* 0 - old "setup()" system call*/
861 .long sys_exit
862 .long sys_fork
863 .long sys_read
864 .long sys_write
865 .long sys_open /* 5 */
866 .long sys_close
867 .long sys_waitpid
868 .long sys_creat
869 .long sys_link
870 .long sys_unlink /* 10 */
871 .long sys_execve
872 .long sys_chdir
873 .long sys_time
874 .long sys_mknod
875 .long sys_chmod /* 15 */
876 .long sys_lchown16
877 .long sys_ni_syscall /* old break syscall holder */
878 .long sys_stat
879 .long sys_lseek
880 .long sys_getpid /* 20 */
881 .long sys_mount
882 .long sys_oldumount
883 .long sys_setuid16
884 .long sys_getuid16
885 .long sys_stime /* 25 */
886 .long sys_ptrace
887 .long sys_alarm
888 .long sys_fstat
889 .long sys_pause
890 .long sys_utime /* 30 */
891 .long sys_ni_syscall /* old stty syscall holder */
892 .long sys_ni_syscall /* old gtty syscall holder */
893 .long sys_access
894 .long sys_nice
895 .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
896 .long sys_sync
897 .long sys_kill
898 .long sys_rename
899 .long sys_mkdir
900 .long sys_rmdir /* 40 */
901 .long sys_dup
902 .long sys_pipe
903 .long sys_times
904 .long sys_ni_syscall /* old prof syscall holder */
905 .long sys_brk /* 45 */
906 .long sys_setgid16
907 .long sys_getgid16
908 .long sys_signal
909 .long sys_geteuid16
910 .long sys_getegid16 /* 50 */
911 .long sys_acct
912 .long sys_umount /* recycled never used phys() */
913 .long sys_ni_syscall /* old lock syscall holder */
914 .long sys_ioctl
915 .long sys_fcntl /* 55 */
916 .long sys_ni_syscall /* old mpx syscall holder */
917 .long sys_setpgid
918 .long sys_ni_syscall /* old ulimit syscall holder */
919 .long sys_ni_syscall /* sys_olduname */
920 .long sys_umask /* 60 */
921 .long sys_chroot
922 .long sys_ustat
923 .long sys_dup2
924 .long sys_getppid
925 .long sys_getpgrp /* 65 */
926 .long sys_setsid
927 .long sys_sigaction
928 .long sys_sgetmask
929 .long sys_ssetmask
930 .long sys_setreuid16 /* 70 */
931 .long sys_setregid16
932 .long sys_sigsuspend
933 .long sys_sigpending
934 .long sys_sethostname
935 .long sys_setrlimit /* 75 */
936 .long sys_old_getrlimit
937 .long sys_getrusage
938 .long sys_gettimeofday
939 .long sys_settimeofday
940 .long sys_getgroups16 /* 80 */
941 .long sys_setgroups16
942 .long sys_ni_syscall /* sys_oldselect */
943 .long sys_symlink
944 .long sys_lstat
945 .long sys_readlink /* 85 */
946 .long sys_uselib
947 .long sys_swapon
948 .long sys_reboot
949 .long old_readdir
950 .long old_mmap /* 90 */
951 .long sys_munmap
952 .long sys_truncate
953 .long sys_ftruncate
954 .long sys_fchmod
955 .long sys_fchown16 /* 95 */
956 .long sys_getpriority
957 .long sys_setpriority
958 .long sys_ni_syscall /* old profil syscall holder */
959 .long sys_statfs
960 .long sys_fstatfs /* 100 */
961 .long sys_ni_syscall /* ioperm */
962 .long sys_socketcall
963 .long sys_syslog
964 .long sys_setitimer
965 .long sys_getitimer /* 105 */
966 .long sys_newstat
967 .long sys_newlstat
968 .long sys_newfstat
969 .long sys_uname
970 .long sys_ni_syscall /* 110 */ /* iopl */
971 .long sys_vhangup
972 .long sys_ni_syscall /* idle */
973 .long sys_ni_syscall /* vm86old */
974 .long sys_wait4
975 .long sys_swapoff /* 115 */
976 .long sys_sysinfo
977 .long sys_ipc
978 .long sys_fsync
979 .long sys_sigreturn
980 .long sys_clone /* 120 */
981 .long sys_setdomainname
982 .long sys_newuname
983 .long sys_ni_syscall /* sys_modify_ldt */
984 .long sys_adjtimex
985 .long sys_mprotect /* 125 */
986 .long sys_sigprocmask
987 .long sys_ni_syscall /* old "create_module" */
988 .long sys_init_module
989 .long sys_delete_module
990 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
991 .long sys_quotactl
992 .long sys_getpgid
993 .long sys_fchdir
994 .long sys_bdflush
995 .long sys_sysfs /* 135 */
996 .long sys_personality
997 .long sys_ni_syscall /* for afs_syscall */
998 .long sys_setfsuid16
999 .long sys_setfsgid16
1000 .long sys_llseek /* 140 */
1001 .long sys_getdents
1002 .long sys_select
1003 .long sys_flock
1004 .long sys_msync
1005 .long sys_readv /* 145 */
1006 .long sys_writev
1007 .long sys_getsid
1008 .long sys_fdatasync
1009 .long sys_sysctl
1010 .long sys_mlock /* 150 */
1011 .long sys_munlock
1012 .long sys_mlockall
1013 .long sys_munlockall
1014 .long sys_sched_setparam
1015 .long sys_sched_getparam /* 155 */
1016 .long sys_sched_setscheduler
1017 .long sys_sched_getscheduler
1018 .long sys_sched_yield
1019 .long sys_sched_get_priority_max
1020 .long sys_sched_get_priority_min /* 160 */
1021 .long sys_sched_rr_get_interval
1022 .long sys_nanosleep
1023 .long sys_mremap
1024 .long sys_setresuid16
1025 .long sys_getresuid16 /* 165 */
1026 .long sys_ni_syscall /* vm86 */
1027 .long sys_ni_syscall /* old "query_module" */
1028 .long sys_poll
1029 .long sys_nfsservctl
1030 .long sys_setresgid16 /* 170 */
1031 .long sys_getresgid16
1032 .long sys_prctl
1033 .long sys_rt_sigreturn
1034 .long sys_rt_sigaction
1035 .long sys_rt_sigprocmask /* 175 */
1036 .long sys_rt_sigpending
1037 .long sys_rt_sigtimedwait
1038 .long sys_rt_sigqueueinfo
1039 .long sys_rt_sigsuspend
1040 .long sys_pread_wrapper /* 180 */
1041 .long sys_pwrite_wrapper
1042 .long sys_chown16
1043 .long sys_getcwd
1044 .long sys_capget
1045 .long sys_capset /* 185 */
1046 .long sys_sigaltstack
1047 .long sys_sendfile
1048 .long sys_ni_syscall /* streams1 */
1049 .long sys_ni_syscall /* streams2 */
1050 .long sys_vfork /* 190 */
1051 .long sys_getrlimit
1052 .long sys_mmap2
1053 .long sys_truncate64
1054 .long sys_ftruncate64
1055 .long sys_stat64 /* 195 */
1056 .long sys_lstat64
1057 .long sys_fstat64
1058 .long sys_lchown
1059 .long sys_getuid
1060 .long sys_getgid /* 200 */
1061 .long sys_geteuid
1062 .long sys_getegid
1063 .long sys_setreuid
1064 .long sys_setregid
1065 .long sys_getgroups /* 205 */
1066 .long sys_setgroups
1067 .long sys_fchown
1068 .long sys_setresuid
1069 .long sys_getresuid
1070 .long sys_setresgid /* 210 */
1071 .long sys_getresgid
1072 .long sys_chown
1073 .long sys_setuid
1074 .long sys_setgid
1075 .long sys_setfsuid /* 215 */
1076 .long sys_setfsgid
1077 .long sys_pivot_root
1078 .long sys_mincore
1079 .long sys_madvise
1080 .long sys_getdents64 /* 220 */
1081 .long sys_fcntl64
1082 .long sys_ni_syscall /* reserved for TUX */
1083 .long sys_ni_syscall /* Reserved for Security */
1084 .long sys_gettid
1085 .long sys_readahead /* 225 */
1086 .long sys_setxattr
1087 .long sys_lsetxattr
1088 .long sys_fsetxattr
1089 .long sys_getxattr
1090 .long sys_lgetxattr /* 230 */
1091 .long sys_fgetxattr
1092 .long sys_listxattr
1093 .long sys_llistxattr
1094 .long sys_flistxattr
1095 .long sys_removexattr /* 235 */
1096 .long sys_lremovexattr
1097 .long sys_fremovexattr
1098 .long sys_tkill
1099 .long sys_sendfile64
1100 .long sys_futex /* 240 */
1101 .long sys_sched_setaffinity
1102 .long sys_sched_getaffinity
1103 .long sys_ni_syscall
1104 .long sys_ni_syscall
1105 .long sys_io_setup /* 245 */
1106 .long sys_io_destroy
1107 .long sys_io_getevents
1108 .long sys_io_submit
1109 .long sys_io_cancel
1110 .long sys_fadvise64 /* 250 */
1111 .long sys_ni_syscall
1112 .long sys_exit_group
1113 .long sys_lookup_dcookie
1114 .long sys_epoll_create
1115 .long sys_epoll_ctl /* 255 */
1116 .long sys_epoll_wait
1117 .long sys_remap_file_pages
1118 .long sys_set_tid_address
1119 .long sys_timer_create
1120 .long sys_timer_settime /* 260 */
1121 .long sys_timer_gettime
1122 .long sys_timer_getoverrun
1123 .long sys_timer_delete
1124 .long sys_clock_settime
1125 .long sys_clock_gettime /* 265 */
1126 .long sys_clock_getres
1127 .long sys_clock_nanosleep
1128 .long sys_statfs64
1129 .long sys_fstatfs64
1130 .long sys_tgkill /* 270 */
1131 .long sys_utimes
1132 .long sys_fadvise64_64_wrapper
1133 .long sys_ni_syscall /* Reserved for vserver */
1134 .long sys_ni_syscall /* Reserved for mbind */
1135 .long sys_ni_syscall /* 275 - get_mempolicy */
1136 .long sys_ni_syscall /* set_mempolicy */
1137 .long sys_mq_open
1138 .long sys_mq_unlink
1139 .long sys_mq_timedsend
1140 .long sys_mq_timedreceive /* 280 */
1141 .long sys_mq_notify
1142 .long sys_mq_getsetattr
1143 .long sys_ni_syscall /* Reserved for kexec */
1144 .long sys_waitid
1145 .long sys_add_key /* 285 */
1146 .long sys_request_key
1147 .long sys_keyctl
1148
1149/* End of entry.S */
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
new file mode 100644
index 000000000000..9b9e6ef626ce
--- /dev/null
+++ b/arch/sh/kernel/head.S
@@ -0,0 +1,76 @@
1/* $Id: head.S,v 1.7 2003/09/01 17:58:19 lethal Exp $
2 *
3 * arch/sh/kernel/head.S
4 *
5 * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Head.S contains the SH exception handlers and startup code.
12 */
13#include <linux/linkage.h>
14
15 .section .empty_zero_page, "aw"
16ENTRY(empty_zero_page)
17 .long 1 /* MOUNT_ROOT_RDONLY */
18 .long 0 /* RAMDISK_FLAGS */
19 .long 0x0200 /* ORIG_ROOT_DEV */
20 .long 1 /* LOADER_TYPE */
21 .long 0x00360000 /* INITRD_START */
22 .long 0x000a0000 /* INITRD_SIZE */
23 .long 0
24 .balign 4096,0,4096
25
26 .text
27/*
28 * Condition at the entry of _stext:
29 *
30 * BSC has already been initialized.
31 * INTC may or may not be initialized.
32 * VBR may or may not be initialized.
33 * MMU may or may not be initialized.
34 * Cache may or may not be initialized.
35 * Hardware (including on-chip modules) may or may not be initialized.
36 *
37 */
38ENTRY(_stext)
39 ! Initialize Status Register
40 mov.l 1f, r0 ! MD=1, RB=0, BL=0, IMASK=0xF
41 ldc r0, sr
42 ! Initialize global interrupt mask
43 mov #0, r0
44 ldc r0, r6_bank
45 !
46 mov.l 2f, r0
47 mov r0, r15 ! Set initial r15 (stack pointer)
48 mov #0x20, r1 !
49 shll8 r1 ! r1 = 8192
50 sub r1, r0 !
51 ldc r0, r7_bank ! ... and initial thread_info
52 !
53 ! Additional CPU initialization
54 mov.l 6f, r0
55 jsr @r0
56 nop
57 ! Clear BSS area
58 mov.l 3f, r1
59 add #4, r1
60 mov.l 4f, r2
61 mov #0, r0
629: cmp/hs r2, r1
63 bf/s 9b ! while (r1 < r2)
64 mov.l r0,@-r2
65 ! Start kernel
66 mov.l 5f, r0
67 jmp @r0
68 nop
69
70 .balign 4
711: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
722: .long stack
733: .long __bss_start
744: .long _end
755: .long start_kernel
766: .long sh_cpu_init
diff --git a/arch/sh/kernel/init_task.c b/arch/sh/kernel/init_task.c
new file mode 100644
index 000000000000..44053ea92936
--- /dev/null
+++ b/arch/sh/kernel/init_task.c
@@ -0,0 +1,36 @@
1#include <linux/mm.h>
2#include <linux/module.h>
3#include <linux/sched.h>
4#include <linux/init_task.h>
5#include <linux/mqueue.h>
6
7#include <asm/uaccess.h>
8#include <asm/pgtable.h>
9
10static struct fs_struct init_fs = INIT_FS;
11static struct files_struct init_files = INIT_FILES;
12static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
13static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
14struct mm_struct init_mm = INIT_MM(init_mm);
15
16EXPORT_SYMBOL(init_mm);
17
18/*
19 * Initial thread structure.
20 *
21 * We need to make sure that this is 8192-byte aligned due to the
22 * way process stacks are handled. This is done by having a special
23 * "init_task" linker map entry..
24 */
25union thread_union init_thread_union
26 __attribute__((__section__(".data.init_task"))) =
27 { INIT_THREAD_INFO(init_task) };
28
29/*
30 * Initial task structure.
31 *
32 * All other task structs will be allocated on slabs in fork.c
33 */
34struct task_struct init_task = INIT_TASK(init_task);
35
36EXPORT_SYMBOL(init_task);
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
new file mode 100644
index 000000000000..d9932f25993b
--- /dev/null
+++ b/arch/sh/kernel/io.c
@@ -0,0 +1,59 @@
1/*
2 * linux/arch/sh/kernel/io.c
3 *
4 * Copyright (C) 2000 Stuart Menefy
5 *
6 * Provide real functions which expand to whatever the header file defined.
7 * Also definitions of machine independent IO functions.
8 */
9
10#include <asm/io.h>
11#include <linux/module.h>
12
13/*
14 * Copy data from IO memory space to "real" memory space.
15 * This needs to be optimized.
16 */
17void memcpy_fromio(void * to, unsigned long from, unsigned long count)
18{
19 char *p = to;
20 while (count) {
21 count--;
22 *p = readb(from);
23 p++;
24 from++;
25 }
26}
27
28/*
29 * Copy data from "real" memory space to IO memory space.
30 * This needs to be optimized.
31 */
32void memcpy_toio(unsigned long to, const void * from, unsigned long count)
33{
34 const char *p = from;
35 while (count) {
36 count--;
37 writeb(*p, to);
38 p++;
39 to++;
40 }
41}
42
43/*
44 * "memset" on IO memory space.
45 * This needs to be optimized.
46 */
47void memset_io(unsigned long dst, int c, unsigned long count)
48{
49 while (count) {
50 count--;
51 writeb(c, dst);
52 dst++;
53 }
54}
55
56EXPORT_SYMBOL(memcpy_fromio);
57EXPORT_SYMBOL(memcpy_toio);
58EXPORT_SYMBOL(memset_io);
59
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
new file mode 100644
index 000000000000..a911b0149d1f
--- /dev/null
+++ b/arch/sh/kernel/io_generic.c
@@ -0,0 +1,243 @@
1/* $Id: io_generic.c,v 1.2 2003/05/04 19:29:53 lethal Exp $
2 *
3 * linux/arch/sh/kernel/io_generic.c
4 *
5 * Copyright (C) 2000 Niibe Yutaka
6 *
7 * Generic I/O routine. These can be used where a machine specific version
8 * is not required.
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 *
14 */
15
16#include <asm/io.h>
17#include <asm/machvec.h>
18#include <linux/module.h>
19
20#if defined(CONFIG_CPU_SH3)
21/* I'm not sure SH7709 has this kind of bug */
22#define SH3_PCMCIA_BUG_WORKAROUND 1
23#define DUMMY_READ_AREA6 0xba000000
24#endif
25
26#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
27
28unsigned long generic_io_base;
29
30static inline void delay(void)
31{
32 ctrl_inw(0xa0000000);
33}
34
35unsigned char generic_inb(unsigned long port)
36{
37 return *(volatile unsigned char*)PORT2ADDR(port);
38}
39
40unsigned short generic_inw(unsigned long port)
41{
42 return *(volatile unsigned short*)PORT2ADDR(port);
43}
44
45unsigned int generic_inl(unsigned long port)
46{
47 return *(volatile unsigned long*)PORT2ADDR(port);
48}
49
50unsigned char generic_inb_p(unsigned long port)
51{
52 unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
53
54 delay();
55 return v;
56}
57
58unsigned short generic_inw_p(unsigned long port)
59{
60 unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
61
62 delay();
63 return v;
64}
65
66unsigned int generic_inl_p(unsigned long port)
67{
68 unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
69
70 delay();
71 return v;
72}
73
74/*
75 * insb/w/l all read a series of bytes/words/longs from a fixed port
76 * address. However as the port address doesn't change we only need to
77 * convert the port address to real address once.
78 */
79
80void generic_insb(unsigned long port, void *buffer, unsigned long count)
81{
82 volatile unsigned char *port_addr;
83 unsigned char *buf=buffer;
84
85 port_addr = (volatile unsigned char *)PORT2ADDR(port);
86
87 while(count--)
88 *buf++ = *port_addr;
89}
90
91void generic_insw(unsigned long port, void *buffer, unsigned long count)
92{
93 volatile unsigned short *port_addr;
94 unsigned short *buf=buffer;
95
96 port_addr = (volatile unsigned short *)PORT2ADDR(port);
97
98 while(count--)
99 *buf++ = *port_addr;
100#ifdef SH3_PCMCIA_BUG_WORKAROUND
101 ctrl_inb (DUMMY_READ_AREA6);
102#endif
103}
104
105void generic_insl(unsigned long port, void *buffer, unsigned long count)
106{
107 volatile unsigned long *port_addr;
108 unsigned long *buf=buffer;
109
110 port_addr = (volatile unsigned long *)PORT2ADDR(port);
111
112 while(count--)
113 *buf++ = *port_addr;
114#ifdef SH3_PCMCIA_BUG_WORKAROUND
115 ctrl_inb (DUMMY_READ_AREA6);
116#endif
117}
118
119void generic_outb(unsigned char b, unsigned long port)
120{
121 *(volatile unsigned char*)PORT2ADDR(port) = b;
122}
123
124void generic_outw(unsigned short b, unsigned long port)
125{
126 *(volatile unsigned short*)PORT2ADDR(port) = b;
127}
128
129void generic_outl(unsigned int b, unsigned long port)
130{
131 *(volatile unsigned long*)PORT2ADDR(port) = b;
132}
133
134void generic_outb_p(unsigned char b, unsigned long port)
135{
136 *(volatile unsigned char*)PORT2ADDR(port) = b;
137 delay();
138}
139
140void generic_outw_p(unsigned short b, unsigned long port)
141{
142 *(volatile unsigned short*)PORT2ADDR(port) = b;
143 delay();
144}
145
146void generic_outl_p(unsigned int b, unsigned long port)
147{
148 *(volatile unsigned long*)PORT2ADDR(port) = b;
149 delay();
150}
151
152/*
153 * outsb/w/l all write a series of bytes/words/longs to a fixed port
154 * address. However as the port address doesn't change we only need to
155 * convert the port address to real address once.
156 */
157
158void generic_outsb(unsigned long port, const void *buffer, unsigned long count)
159{
160 volatile unsigned char *port_addr;
161 const unsigned char *buf=buffer;
162
163 port_addr = (volatile unsigned char *)PORT2ADDR(port);
164
165 while(count--)
166 *port_addr = *buf++;
167}
168
169void generic_outsw(unsigned long port, const void *buffer, unsigned long count)
170{
171 volatile unsigned short *port_addr;
172 const unsigned short *buf=buffer;
173
174 port_addr = (volatile unsigned short *)PORT2ADDR(port);
175
176 while(count--)
177 *port_addr = *buf++;
178
179#ifdef SH3_PCMCIA_BUG_WORKAROUND
180 ctrl_inb (DUMMY_READ_AREA6);
181#endif
182}
183
184void generic_outsl(unsigned long port, const void *buffer, unsigned long count)
185{
186 volatile unsigned long *port_addr;
187 const unsigned long *buf=buffer;
188
189 port_addr = (volatile unsigned long *)PORT2ADDR(port);
190
191 while(count--)
192 *port_addr = *buf++;
193
194#ifdef SH3_PCMCIA_BUG_WORKAROUND
195 ctrl_inb (DUMMY_READ_AREA6);
196#endif
197}
198
199unsigned char generic_readb(unsigned long addr)
200{
201 return *(volatile unsigned char*)addr;
202}
203
204unsigned short generic_readw(unsigned long addr)
205{
206 return *(volatile unsigned short*)addr;
207}
208
209unsigned int generic_readl(unsigned long addr)
210{
211 return *(volatile unsigned long*)addr;
212}
213
214void generic_writeb(unsigned char b, unsigned long addr)
215{
216 *(volatile unsigned char*)addr = b;
217}
218
219void generic_writew(unsigned short b, unsigned long addr)
220{
221 *(volatile unsigned short*)addr = b;
222}
223
224void generic_writel(unsigned int b, unsigned long addr)
225{
226 *(volatile unsigned long*)addr = b;
227}
228
229void * generic_ioremap(unsigned long offset, unsigned long size)
230{
231 return (void *) P2SEGADDR(offset);
232}
233EXPORT_SYMBOL(generic_ioremap);
234
235void generic_iounmap(void *addr)
236{
237}
238EXPORT_SYMBOL(generic_iounmap);
239
240unsigned long generic_isa_port2addr(unsigned long offset)
241{
242 return offset + generic_io_base;
243}
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
new file mode 100644
index 000000000000..54c171225b78
--- /dev/null
+++ b/arch/sh/kernel/irq.c
@@ -0,0 +1,106 @@
1/* $Id: irq.c,v 1.20 2004/01/13 05:52:11 kkojima Exp $
2 *
3 * linux/arch/sh/kernel/irq.c
4 *
5 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
6 *
7 *
8 * SuperH version: Copyright (C) 1999 Niibe Yutaka
9 */
10
11/*
12 * IRQs are in fact implemented a bit like signal handlers for the kernel.
13 * Naturally it's not a 1:1 relation, but there are similarities.
14 */
15
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/ptrace.h>
19#include <linux/errno.h>
20#include <linux/kernel_stat.h>
21#include <linux/signal.h>
22#include <linux/sched.h>
23#include <linux/ioport.h>
24#include <linux/interrupt.h>
25#include <linux/timex.h>
26#include <linux/mm.h>
27#include <linux/slab.h>
28#include <linux/random.h>
29#include <linux/smp.h>
30#include <linux/smp_lock.h>
31#include <linux/init.h>
32#include <linux/seq_file.h>
33#include <linux/kallsyms.h>
34#include <linux/bitops.h>
35
36#include <asm/system.h>
37#include <asm/io.h>
38#include <asm/pgalloc.h>
39#include <asm/delay.h>
40#include <asm/irq.h>
41#include <linux/irq.h>
42
43
44/*
45 * 'what should we do if we get a hw irq event on an illegal vector'.
46 * each architecture has to answer this themselves, it doesn't deserve
47 * a generic callback i think.
48 */
49void ack_bad_irq(unsigned int irq)
50{
51 printk("unexpected IRQ trap at vector %02x\n", irq);
52}
53
54#if defined(CONFIG_PROC_FS)
55int show_interrupts(struct seq_file *p, void *v)
56{
57 int i = *(loff_t *) v, j;
58 struct irqaction * action;
59 unsigned long flags;
60
61 if (i == 0) {
62 seq_puts(p, " ");
63 for (j=0; j<NR_CPUS; j++)
64 if (cpu_online(j))
65 seq_printf(p, "CPU%d ",j);
66 seq_putc(p, '\n');
67 }
68
69 if (i < ACTUAL_NR_IRQS) {
70 spin_lock_irqsave(&irq_desc[i].lock, flags);
71 action = irq_desc[i].action;
72 if (!action)
73 goto unlock;
74 seq_printf(p, "%3d: ",i);
75 seq_printf(p, "%10u ", kstat_irqs(i));
76 seq_printf(p, " %14s", irq_desc[i].handler->typename);
77 seq_printf(p, " %s", action->name);
78
79 for (action=action->next; action; action = action->next)
80 seq_printf(p, ", %s", action->name);
81 seq_putc(p, '\n');
82unlock:
83 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
84 }
85 return 0;
86}
87#endif
88
89asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
90 unsigned long r6, unsigned long r7,
91 struct pt_regs regs)
92{
93 int irq;
94
95 irq_enter();
96 asm volatile("stc r2_bank, %0\n\t"
97 "shlr2 %0\n\t"
98 "shlr2 %0\n\t"
99 "shlr %0\n\t"
100 "add #-16, %0\n\t"
101 :"=z" (irq));
102 irq = irq_demux(irq);
103 __do_IRQ(irq, &regs);
104 irq_exit();
105 return 1;
106}
diff --git a/arch/sh/kernel/kgdb_jmp.S b/arch/sh/kernel/kgdb_jmp.S
new file mode 100644
index 000000000000..339bb1d7ff0b
--- /dev/null
+++ b/arch/sh/kernel/kgdb_jmp.S
@@ -0,0 +1,33 @@
1#include <linux/linkage.h>
2
3ENTRY(setjmp)
4 add #(9*4), r4
5 sts.l pr, @-r4
6 mov.l r15, @-r4
7 mov.l r14, @-r4
8 mov.l r13, @-r4
9 mov.l r12, @-r4
10 mov.l r11, @-r4
11 mov.l r10, @-r4
12 mov.l r9, @-r4
13 mov.l r8, @-r4
14 rts
15 mov #0, r0
16
17ENTRY(longjmp)
18 mov.l @r4+, r8
19 mov.l @r4+, r9
20 mov.l @r4+, r10
21 mov.l @r4+, r11
22 mov.l @r4+, r12
23 mov.l @r4+, r13
24 mov.l @r4+, r14
25 mov.l @r4+, r15
26 lds.l @r4+, pr
27 mov r5, r0
28 tst r0, r0
29 bf 1f
30 mov #1, r0 ! in case val==0
311: rts
32 nop
33
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
new file mode 100644
index 000000000000..42638b92b51c
--- /dev/null
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -0,0 +1,1491 @@
1/*
2 * May be copied or modified under the terms of the GNU General Public
3 * License. See linux/COPYING for more information.
4 *
5 * Containes extracts from code by Glenn Engel, Jim Kingdon,
6 * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
7 * Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
8 * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
9 *
10 * This version by Henry Bell <henry.bell@st.com>
11 * Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
12 *
13 * Contains low-level support for remote debug using GDB.
14 *
15 * To enable debugger support, two things need to happen. A call to
16 * set_debug_traps() is necessary in order to allow any breakpoints
17 * or error conditions to be properly intercepted and reported to gdb.
18 * A breakpoint also needs to be generated to begin communication. This
19 * is most easily accomplished by a call to breakpoint() which does
20 * a trapa if the initialisation phase has been successfully completed.
21 *
22 * In this case, set_debug_traps() is not used to "take over" exceptions;
23 * other kernel code is modified instead to enter the kgdb functions here
24 * when appropriate (see entry.S for breakpoint traps and NMI interrupts,
25 * see traps.c for kernel error exceptions).
26 *
27 * The following gdb commands are supported:
28 *
29 * Command Function Return value
30 *
31 * g return the value of the CPU registers hex data or ENN
32 * G set the value of the CPU registers OK or ENN
33 *
34 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
35 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
36 * XAA..AA,LLLL: Same, but data is binary (not hex) OK or ENN
37 *
38 * c Resume at current address SNN ( signal NN)
39 * cAA..AA Continue at address AA..AA SNN
40 * CNN; Resume at current address with signal SNN
41 * CNN;AA..AA Resume at address AA..AA with signal SNN
42 *
43 * s Step one instruction SNN
44 * sAA..AA Step one instruction from AA..AA SNN
45 * SNN; Step one instruction with signal SNN
46 * SNNAA..AA Step one instruction from AA..AA w/NN SNN
47 *
48 * k kill (Detach GDB)
49 *
50 * d Toggle debug flag
51 * D Detach GDB
52 *
53 * Hct Set thread t for operations, OK or ENN
54 * c = 'c' (step, cont), c = 'g' (other
55 * operations)
56 *
57 * qC Query current thread ID QCpid
58 * qfThreadInfo Get list of current threads (first) m<id>
59 * qsThreadInfo " " " " " (subsequent)
60 * qOffsets Get section offsets Text=x;Data=y;Bss=z
61 *
62 * TXX Find if thread XX is alive OK or ENN
63 * ? What was the last sigval ? SNN (signal NN)
64 * O Output to GDB console
65 *
66 * Remote communication protocol.
67 *
68 * A debug packet whose contents are <data> is encapsulated for
69 * transmission in the form:
70 *
71 * $ <data> # CSUM1 CSUM2
72 *
73 * <data> must be ASCII alphanumeric and cannot include characters
74 * '$' or '#'. If <data> starts with two characters followed by
75 * ':', then the existing stubs interpret this as a sequence number.
76 *
77 * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
78 * checksum of <data>, the most significant nibble is sent first.
79 * the hex digits 0-9,a-f are used.
80 *
81 * Receiver responds with:
82 *
83 * + - if CSUM is correct and ready for next packet
84 * - - if CSUM is incorrect
85 *
86 * Responses can be run-length encoded to save space. A '*' means that
87 * the next character is an ASCII encoding giving a repeat count which
88 * stands for that many repititions of the character preceding the '*'.
89 * The encoding is n+29, yielding a printable character where n >=3
90 * (which is where RLE starts to win). Don't use an n > 126.
91 *
92 * So "0* " means the same as "0000".
93 */
94
95#include <linux/string.h>
96#include <linux/kernel.h>
97#include <linux/sched.h>
98#include <linux/smp.h>
99#include <linux/spinlock.h>
100#include <linux/delay.h>
101#include <linux/linkage.h>
102#include <linux/init.h>
103
104#include <asm/system.h>
105#include <asm/current.h>
106#include <asm/signal.h>
107#include <asm/pgtable.h>
108#include <asm/ptrace.h>
109#include <asm/kgdb.h>
110
111#ifdef CONFIG_SH_KGDB_CONSOLE
112#include <linux/console.h>
113#endif
114
115/* Function pointers for linkage */
116kgdb_debug_hook_t *kgdb_debug_hook;
117kgdb_bus_error_hook_t *kgdb_bus_err_hook;
118
119int (*kgdb_getchar)(void);
120void (*kgdb_putchar)(int);
121
122static void put_debug_char(int c)
123{
124 if (!kgdb_putchar)
125 return;
126 (*kgdb_putchar)(c);
127}
128static int get_debug_char(void)
129{
130 if (!kgdb_getchar)
131 return -1;
132 return (*kgdb_getchar)();
133}
134
135/* Num chars in in/out bound buffers, register packets need NUMREGBYTES * 2 */
136#define BUFMAX 1024
137#define NUMREGBYTES (MAXREG*4)
138#define OUTBUFMAX (NUMREGBYTES*2+512)
139
140enum regs {
141 R0 = 0, R1, R2, R3, R4, R5, R6, R7,
142 R8, R9, R10, R11, R12, R13, R14, R15,
143 PC, PR, GBR, VBR, MACH, MACL, SR,
144 /* */
145 MAXREG
146};
147
148static unsigned int registers[MAXREG];
149struct kgdb_regs trap_registers;
150
151char kgdb_in_gdb_mode;
152char in_nmi; /* Set during NMI to prevent reentry */
153int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
154int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */
155int kgdb_halt;
156
157/* Exposed for user access */
158struct task_struct *kgdb_current;
159unsigned int kgdb_g_imask;
160int kgdb_trapa_val;
161int kgdb_excode;
162
163/* Default values for SCI (can override via kernel args in setup.c) */
164#ifndef CONFIG_KGDB_DEFPORT
165#define CONFIG_KGDB_DEFPORT 1
166#endif
167
168#ifndef CONFIG_KGDB_DEFBAUD
169#define CONFIG_KGDB_DEFBAUD 115200
170#endif
171
172#if defined(CONFIG_KGDB_DEFPARITY_E)
173#define CONFIG_KGDB_DEFPARITY 'E'
174#elif defined(CONFIG_KGDB_DEFPARITY_O)
175#define CONFIG_KGDB_DEFPARITY 'O'
176#else /* CONFIG_KGDB_DEFPARITY_N */
177#define CONFIG_KGDB_DEFPARITY 'N'
178#endif
179
180#ifdef CONFIG_KGDB_DEFBITS_7
181#define CONFIG_KGDB_DEFBITS '7'
182#else /* CONFIG_KGDB_DEFBITS_8 */
183#define CONFIG_KGDB_DEFBITS '8'
184#endif
185
186/* SCI/UART settings, used in kgdb_console_setup() */
187int kgdb_portnum = CONFIG_KGDB_DEFPORT;
188int kgdb_baud = CONFIG_KGDB_DEFBAUD;
189char kgdb_parity = CONFIG_KGDB_DEFPARITY;
190char kgdb_bits = CONFIG_KGDB_DEFBITS;
191
192/* Jump buffer for setjmp/longjmp */
193static jmp_buf rem_com_env;
194
195/* TRA differs sh3/4 */
196#if defined(CONFIG_CPU_SH3)
197#define TRA 0xffffffd0
198#elif defined(CONFIG_CPU_SH4)
199#define TRA 0xff000020
200#endif
201
202/* Macros for single step instruction identification */
203#define OPCODE_BT(op) (((op) & 0xff00) == 0x8900)
204#define OPCODE_BF(op) (((op) & 0xff00) == 0x8b00)
205#define OPCODE_BTF_DISP(op) (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
206 (((op) & 0x7f ) << 1))
207#define OPCODE_BFS(op) (((op) & 0xff00) == 0x8f00)
208#define OPCODE_BTS(op) (((op) & 0xff00) == 0x8d00)
209#define OPCODE_BRA(op) (((op) & 0xf000) == 0xa000)
210#define OPCODE_BRA_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
211 (((op) & 0x7ff) << 1))
212#define OPCODE_BRAF(op) (((op) & 0xf0ff) == 0x0023)
213#define OPCODE_BRAF_REG(op) (((op) & 0x0f00) >> 8)
214#define OPCODE_BSR(op) (((op) & 0xf000) == 0xb000)
215#define OPCODE_BSR_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
216 (((op) & 0x7ff) << 1))
217#define OPCODE_BSRF(op) (((op) & 0xf0ff) == 0x0003)
218#define OPCODE_BSRF_REG(op) (((op) >> 8) & 0xf)
219#define OPCODE_JMP(op) (((op) & 0xf0ff) == 0x402b)
220#define OPCODE_JMP_REG(op) (((op) >> 8) & 0xf)
221#define OPCODE_JSR(op) (((op) & 0xf0ff) == 0x400b)
222#define OPCODE_JSR_REG(op) (((op) >> 8) & 0xf)
223#define OPCODE_RTS(op) ((op) == 0xb)
224#define OPCODE_RTE(op) ((op) == 0x2b)
225
226#define SR_T_BIT_MASK 0x1
227#define STEP_OPCODE 0xc320
228#define BIOS_CALL_TRAP 0x3f
229
230/* Exception codes as per SH-4 core manual */
231#define ADDRESS_ERROR_LOAD_VEC 7
232#define ADDRESS_ERROR_STORE_VEC 8
233#define TRAP_VEC 11
234#define INVALID_INSN_VEC 12
235#define INVALID_SLOT_VEC 13
236#define NMI_VEC 14
237#define USER_BREAK_VEC 15
238#define SERIAL_BREAK_VEC 58
239
240/* Misc static */
241static int stepped_address;
242static short stepped_opcode;
243static const char hexchars[] = "0123456789abcdef";
244static char in_buffer[BUFMAX];
245static char out_buffer[OUTBUFMAX];
246
247static void kgdb_to_gdb(const char *s);
248
249#ifdef CONFIG_KGDB_THREAD
250static struct task_struct *trapped_thread;
251static struct task_struct *current_thread;
252typedef unsigned char threadref[8];
253#define BUF_THREAD_ID_SIZE 16
254#endif
255
256/* Return addr as a real volatile address */
257static inline unsigned int ctrl_inl(const unsigned long addr)
258{
259 return *(volatile unsigned long *) addr;
260}
261
262/* Correctly set *addr using volatile */
263static inline void ctrl_outl(const unsigned int b, unsigned long addr)
264{
265 *(volatile unsigned long *) addr = b;
266}
267
268/* Get high hex bits */
269static char highhex(const int x)
270{
271 return hexchars[(x >> 4) & 0xf];
272}
273
274/* Get low hex bits */
275static char lowhex(const int x)
276{
277 return hexchars[x & 0xf];
278}
279
280/* Convert ch to hex */
281static int hex(const char ch)
282{
283 if ((ch >= 'a') && (ch <= 'f'))
284 return (ch - 'a' + 10);
285 if ((ch >= '0') && (ch <= '9'))
286 return (ch - '0');
287 if ((ch >= 'A') && (ch <= 'F'))
288 return (ch - 'A' + 10);
289 return (-1);
290}
291
292/* Convert the memory pointed to by mem into hex, placing result in buf.
293 Returns a pointer to the last char put in buf (null) */
294static char *mem_to_hex(const char *mem, char *buf, const int count)
295{
296 int i;
297 int ch;
298 unsigned short s_val;
299 unsigned long l_val;
300
301 /* Check for 16 or 32 */
302 if (count == 2 && ((long) mem & 1) == 0) {
303 s_val = *(unsigned short *) mem;
304 mem = (char *) &s_val;
305 } else if (count == 4 && ((long) mem & 3) == 0) {
306 l_val = *(unsigned long *) mem;
307 mem = (char *) &l_val;
308 }
309 for (i = 0; i < count; i++) {
310 ch = *mem++;
311 *buf++ = highhex(ch);
312 *buf++ = lowhex(ch);
313 }
314 *buf = 0;
315 return (buf);
316}
317
318/* Convert the hex array pointed to by buf into binary, to be placed in mem.
319 Return a pointer to the character after the last byte written */
320static char *hex_to_mem(const char *buf, char *mem, const int count)
321{
322 int i;
323 unsigned char ch;
324
325 for (i = 0; i < count; i++) {
326 ch = hex(*buf++) << 4;
327 ch = ch + hex(*buf++);
328 *mem++ = ch;
329 }
330 return (mem);
331}
332
333/* While finding valid hex chars, convert to an integer, then return it */
334static int hex_to_int(char **ptr, int *int_value)
335{
336 int num_chars = 0;
337 int hex_value;
338
339 *int_value = 0;
340
341 while (**ptr) {
342 hex_value = hex(**ptr);
343 if (hex_value >= 0) {
344 *int_value = (*int_value << 4) | hex_value;
345 num_chars++;
346 } else
347 break;
348 (*ptr)++;
349 }
350 return num_chars;
351}
352
353/* Copy the binary array pointed to by buf into mem. Fix $, #,
354 and 0x7d escaped with 0x7d. Return a pointer to the character
355 after the last byte written. */
356static char *ebin_to_mem(const char *buf, char *mem, int count)
357{
358 for (; count > 0; count--, buf++) {
359 if (*buf == 0x7d)
360 *mem++ = *(++buf) ^ 0x20;
361 else
362 *mem++ = *buf;
363 }
364 return mem;
365}
366
367/* Pack a hex byte */
368static char *pack_hex_byte(char *pkt, int byte)
369{
370 *pkt++ = hexchars[(byte >> 4) & 0xf];
371 *pkt++ = hexchars[(byte & 0xf)];
372 return pkt;
373}
374
375#ifdef CONFIG_KGDB_THREAD
376
377/* Pack a thread ID */
378static char *pack_threadid(char *pkt, threadref * id)
379{
380 char *limit;
381 unsigned char *altid;
382
383 altid = (unsigned char *) id;
384
385 limit = pkt + BUF_THREAD_ID_SIZE;
386 while (pkt < limit)
387 pkt = pack_hex_byte(pkt, *altid++);
388 return pkt;
389}
390
391/* Convert an integer into our threadref */
392static void int_to_threadref(threadref * id, const int value)
393{
394 unsigned char *scan = (unsigned char *) id;
395 int i = 4;
396
397 while (i--)
398 *scan++ = 0;
399
400 *scan++ = (value >> 24) & 0xff;
401 *scan++ = (value >> 16) & 0xff;
402 *scan++ = (value >> 8) & 0xff;
403 *scan++ = (value & 0xff);
404}
405
406/* Return a task structure ptr for a particular pid */
407static struct task_struct *get_thread(int pid)
408{
409 struct task_struct *thread;
410
411 /* Use PID_MAX w/gdb for pid 0 */
412 if (pid == PID_MAX) pid = 0;
413
414 /* First check via PID */
415 thread = find_task_by_pid(pid);
416
417 if (thread)
418 return thread;
419
420 /* Start at the start */
421 thread = init_tasks[0];
422
423 /* Walk along the linked list of tasks */
424 do {
425 if (thread->pid == pid)
426 return thread;
427 thread = thread->next_task;
428 } while (thread != init_tasks[0]);
429
430 return NULL;
431}
432
433#endif /* CONFIG_KGDB_THREAD */
434
435/* Scan for the start char '$', read the packet and check the checksum */
436static void get_packet(char *buffer, int buflen)
437{
438 unsigned char checksum;
439 unsigned char xmitcsum;
440 int i;
441 int count;
442 char ch;
443
444 do {
445 /* Ignore everything until the start character */
446 while ((ch = get_debug_char()) != '$');
447
448 checksum = 0;
449 xmitcsum = -1;
450 count = 0;
451
452 /* Now, read until a # or end of buffer is found */
453 while (count < (buflen - 1)) {
454 ch = get_debug_char();
455
456 if (ch == '#')
457 break;
458
459 checksum = checksum + ch;
460 buffer[count] = ch;
461 count = count + 1;
462 }
463
464 buffer[count] = 0;
465
466 /* Continue to read checksum following # */
467 if (ch == '#') {
468 xmitcsum = hex(get_debug_char()) << 4;
469 xmitcsum += hex(get_debug_char());
470
471 /* Checksum */
472 if (checksum != xmitcsum)
473 put_debug_char('-'); /* Failed checksum */
474 else {
475 /* Ack successful transfer */
476 put_debug_char('+');
477
478 /* If a sequence char is present, reply
479 the sequence ID */
480 if (buffer[2] == ':') {
481 put_debug_char(buffer[0]);
482 put_debug_char(buffer[1]);
483
484 /* Remove sequence chars from buffer */
485 count = strlen(buffer);
486 for (i = 3; i <= count; i++)
487 buffer[i - 3] = buffer[i];
488 }
489 }
490 }
491 }
492 while (checksum != xmitcsum); /* Keep trying while we fail */
493}
494
495/* Send the packet in the buffer with run-length encoding */
496static void put_packet(char *buffer)
497{
498 int checksum;
499 char *src;
500 int runlen;
501 int encode;
502
503 do {
504 src = buffer;
505 put_debug_char('$');
506 checksum = 0;
507
508 /* Continue while we still have chars left */
509 while (*src) {
510 /* Check for runs up to 99 chars long */
511 for (runlen = 1; runlen < 99; runlen++) {
512 if (src[0] != src[runlen])
513 break;
514 }
515
516 if (runlen > 3) {
517 /* Got a useful amount, send encoding */
518 encode = runlen + ' ' - 4;
519 put_debug_char(*src); checksum += *src;
520 put_debug_char('*'); checksum += '*';
521 put_debug_char(encode); checksum += encode;
522 src += runlen;
523 } else {
524 /* Otherwise just send the current char */
525 put_debug_char(*src); checksum += *src;
526 src += 1;
527 }
528 }
529
530 /* '#' Separator, put high and low components of checksum */
531 put_debug_char('#');
532 put_debug_char(highhex(checksum));
533 put_debug_char(lowhex(checksum));
534 }
535 while ((get_debug_char()) != '+'); /* While no ack */
536}
537
538/* A bus error has occurred - perform a longjmp to return execution and
539 allow handling of the error */
540static void kgdb_handle_bus_error(void)
541{
542 longjmp(rem_com_env, 1);
543}
544
545/* Translate SH-3/4 exception numbers to unix-like signal values */
546static int compute_signal(const int excep_code)
547{
548 int sigval;
549
550 switch (excep_code) {
551
552 case INVALID_INSN_VEC:
553 case INVALID_SLOT_VEC:
554 sigval = SIGILL;
555 break;
556 case ADDRESS_ERROR_LOAD_VEC:
557 case ADDRESS_ERROR_STORE_VEC:
558 sigval = SIGSEGV;
559 break;
560
561 case SERIAL_BREAK_VEC:
562 case NMI_VEC:
563 sigval = SIGINT;
564 break;
565
566 case USER_BREAK_VEC:
567 case TRAP_VEC:
568 sigval = SIGTRAP;
569 break;
570
571 default:
572 sigval = SIGBUS; /* "software generated" */
573 break;
574 }
575
576 return (sigval);
577}
578
579/* Make a local copy of the registers passed into the handler (bletch) */
580static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs,
581 int *gdb_regs)
582{
583 gdb_regs[R0] = regs->regs[R0];
584 gdb_regs[R1] = regs->regs[R1];
585 gdb_regs[R2] = regs->regs[R2];
586 gdb_regs[R3] = regs->regs[R3];
587 gdb_regs[R4] = regs->regs[R4];
588 gdb_regs[R5] = regs->regs[R5];
589 gdb_regs[R6] = regs->regs[R6];
590 gdb_regs[R7] = regs->regs[R7];
591 gdb_regs[R8] = regs->regs[R8];
592 gdb_regs[R9] = regs->regs[R9];
593 gdb_regs[R10] = regs->regs[R10];
594 gdb_regs[R11] = regs->regs[R11];
595 gdb_regs[R12] = regs->regs[R12];
596 gdb_regs[R13] = regs->regs[R13];
597 gdb_regs[R14] = regs->regs[R14];
598 gdb_regs[R15] = regs->regs[R15];
599 gdb_regs[PC] = regs->pc;
600 gdb_regs[PR] = regs->pr;
601 gdb_regs[GBR] = regs->gbr;
602 gdb_regs[MACH] = regs->mach;
603 gdb_regs[MACL] = regs->macl;
604 gdb_regs[SR] = regs->sr;
605 gdb_regs[VBR] = regs->vbr;
606}
607
608/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
609static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
610 struct kgdb_regs *regs)
611{
612 regs->regs[R0] = gdb_regs[R0];
613 regs->regs[R1] = gdb_regs[R1];
614 regs->regs[R2] = gdb_regs[R2];
615 regs->regs[R3] = gdb_regs[R3];
616 regs->regs[R4] = gdb_regs[R4];
617 regs->regs[R5] = gdb_regs[R5];
618 regs->regs[R6] = gdb_regs[R6];
619 regs->regs[R7] = gdb_regs[R7];
620 regs->regs[R8] = gdb_regs[R8];
621 regs->regs[R9] = gdb_regs[R9];
622 regs->regs[R10] = gdb_regs[R10];
623 regs->regs[R11] = gdb_regs[R11];
624 regs->regs[R12] = gdb_regs[R12];
625 regs->regs[R13] = gdb_regs[R13];
626 regs->regs[R14] = gdb_regs[R14];
627 regs->regs[R15] = gdb_regs[R15];
628 regs->pc = gdb_regs[PC];
629 regs->pr = gdb_regs[PR];
630 regs->gbr = gdb_regs[GBR];
631 regs->mach = gdb_regs[MACH];
632 regs->macl = gdb_regs[MACL];
633 regs->sr = gdb_regs[SR];
634 regs->vbr = gdb_regs[VBR];
635}
636
637#ifdef CONFIG_KGDB_THREAD
638/* Make a local copy of registers from the specified thread */
639asmlinkage void ret_from_fork(void);
640static void thread_regs_to_gdb_regs(const struct task_struct *thread,
641 int *gdb_regs)
642{
643 int regno;
644 int *tregs;
645
646 /* Initialize to zero */
647 for (regno = 0; regno < MAXREG; regno++)
648 gdb_regs[regno] = 0;
649
650 /* Just making sure... */
651 if (thread == NULL)
652 return;
653
654 /* A new fork has pt_regs on the stack from a fork() call */
655 if (thread->thread.pc == (unsigned long)ret_from_fork) {
656
657 int vbr_val;
658 struct pt_regs *kregs;
659 kregs = (struct pt_regs*)thread->thread.sp;
660
661 gdb_regs[R0] = kregs->regs[R0];
662 gdb_regs[R1] = kregs->regs[R1];
663 gdb_regs[R2] = kregs->regs[R2];
664 gdb_regs[R3] = kregs->regs[R3];
665 gdb_regs[R4] = kregs->regs[R4];
666 gdb_regs[R5] = kregs->regs[R5];
667 gdb_regs[R6] = kregs->regs[R6];
668 gdb_regs[R7] = kregs->regs[R7];
669 gdb_regs[R8] = kregs->regs[R8];
670 gdb_regs[R9] = kregs->regs[R9];
671 gdb_regs[R10] = kregs->regs[R10];
672 gdb_regs[R11] = kregs->regs[R11];
673 gdb_regs[R12] = kregs->regs[R12];
674 gdb_regs[R13] = kregs->regs[R13];
675 gdb_regs[R14] = kregs->regs[R14];
676 gdb_regs[R15] = kregs->regs[R15];
677 gdb_regs[PC] = kregs->pc;
678 gdb_regs[PR] = kregs->pr;
679 gdb_regs[GBR] = kregs->gbr;
680 gdb_regs[MACH] = kregs->mach;
681 gdb_regs[MACL] = kregs->macl;
682 gdb_regs[SR] = kregs->sr;
683
684 asm("stc vbr, %0":"=r"(vbr_val));
685 gdb_regs[VBR] = vbr_val;
686 return;
687 }
688
689 /* Otherwise, we have only some registers from switch_to() */
690 tregs = (int *)thread->thread.sp;
691 gdb_regs[R15] = (int)tregs;
692 gdb_regs[R14] = *tregs++;
693 gdb_regs[R13] = *tregs++;
694 gdb_regs[R12] = *tregs++;
695 gdb_regs[R11] = *tregs++;
696 gdb_regs[R10] = *tregs++;
697 gdb_regs[R9] = *tregs++;
698 gdb_regs[R8] = *tregs++;
699 gdb_regs[PR] = *tregs++;
700 gdb_regs[GBR] = *tregs++;
701 gdb_regs[PC] = thread->thread.pc;
702}
703#endif /* CONFIG_KGDB_THREAD */
704
705/* Calculate the new address for after a step */
706static short *get_step_address(void)
707{
708 short op = *(short *) trap_registers.pc;
709 long addr;
710
711 /* BT */
712 if (OPCODE_BT(op)) {
713 if (trap_registers.sr & SR_T_BIT_MASK)
714 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
715 else
716 addr = trap_registers.pc + 2;
717 }
718
719 /* BTS */
720 else if (OPCODE_BTS(op)) {
721 if (trap_registers.sr & SR_T_BIT_MASK)
722 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
723 else
724 addr = trap_registers.pc + 4; /* Not in delay slot */
725 }
726
727 /* BF */
728 else if (OPCODE_BF(op)) {
729 if (!(trap_registers.sr & SR_T_BIT_MASK))
730 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
731 else
732 addr = trap_registers.pc + 2;
733 }
734
735 /* BFS */
736 else if (OPCODE_BFS(op)) {
737 if (!(trap_registers.sr & SR_T_BIT_MASK))
738 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
739 else
740 addr = trap_registers.pc + 4; /* Not in delay slot */
741 }
742
743 /* BRA */
744 else if (OPCODE_BRA(op))
745 addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op);
746
747 /* BRAF */
748 else if (OPCODE_BRAF(op))
749 addr = trap_registers.pc + 4
750 + trap_registers.regs[OPCODE_BRAF_REG(op)];
751
752 /* BSR */
753 else if (OPCODE_BSR(op))
754 addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op);
755
756 /* BSRF */
757 else if (OPCODE_BSRF(op))
758 addr = trap_registers.pc + 4
759 + trap_registers.regs[OPCODE_BSRF_REG(op)];
760
761 /* JMP */
762 else if (OPCODE_JMP(op))
763 addr = trap_registers.regs[OPCODE_JMP_REG(op)];
764
765 /* JSR */
766 else if (OPCODE_JSR(op))
767 addr = trap_registers.regs[OPCODE_JSR_REG(op)];
768
769 /* RTS */
770 else if (OPCODE_RTS(op))
771 addr = trap_registers.pr;
772
773 /* RTE */
774 else if (OPCODE_RTE(op))
775 addr = trap_registers.regs[15];
776
777 /* Other */
778 else
779 addr = trap_registers.pc + 2;
780
781 kgdb_flush_icache_range(addr, addr + 2);
782 return (short *) addr;
783}
784
785/* Set up a single-step. Replace the instruction immediately after the
786 current instruction (i.e. next in the expected flow of control) with a
787 trap instruction, so that returning will cause only a single instruction
788 to be executed. Note that this model is slightly broken for instructions
789 with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch
790 and the instruction in the delay slot will be executed. */
791static void do_single_step(void)
792{
793 unsigned short *addr = 0;
794
795 /* Determine where the target instruction will send us to */
796 addr = get_step_address();
797 stepped_address = (int)addr;
798
799 /* Replace it */
800 stepped_opcode = *(short *)addr;
801 *addr = STEP_OPCODE;
802
803 /* Flush and return */
804 kgdb_flush_icache_range((long) addr, (long) addr + 2);
805 return;
806}
807
808/* Undo a single step */
809static void undo_single_step(void)
810{
811 /* If we have stepped, put back the old instruction */
812 /* Use stepped_address in case we stopped elsewhere */
813 if (stepped_opcode != 0) {
814 *(short*)stepped_address = stepped_opcode;
815 kgdb_flush_icache_range(stepped_address, stepped_address + 2);
816 }
817 stepped_opcode = 0;
818}
819
820/* Send a signal message */
821static void send_signal_msg(const int signum)
822{
823#ifndef CONFIG_KGDB_THREAD
824 out_buffer[0] = 'S';
825 out_buffer[1] = highhex(signum);
826 out_buffer[2] = lowhex(signum);
827 out_buffer[3] = 0;
828 put_packet(out_buffer);
829#else /* CONFIG_KGDB_THREAD */
830 int threadid;
831 threadref thref;
832 char *out = out_buffer;
833 const char *tstring = "thread";
834
835 *out++ = 'T';
836 *out++ = highhex(signum);
837 *out++ = lowhex(signum);
838
839 while (*tstring) {
840 *out++ = *tstring++;
841 }
842 *out++ = ':';
843
844 threadid = trapped_thread->pid;
845 if (threadid == 0) threadid = PID_MAX;
846 int_to_threadref(&thref, threadid);
847 pack_threadid(out, &thref);
848 out += BUF_THREAD_ID_SIZE;
849 *out++ = ';';
850
851 *out = 0;
852 put_packet(out_buffer);
853#endif /* CONFIG_KGDB_THREAD */
854}
855
856/* Reply that all was well */
857static void send_ok_msg(void)
858{
859 strcpy(out_buffer, "OK");
860 put_packet(out_buffer);
861}
862
863/* Reply that an error occurred */
864static void send_err_msg(void)
865{
866 strcpy(out_buffer, "E01");
867 put_packet(out_buffer);
868}
869
870/* Empty message indicates unrecognised command */
871static void send_empty_msg(void)
872{
873 put_packet("");
874}
875
876/* Read memory due to 'm' message */
877static void read_mem_msg(void)
878{
879 char *ptr;
880 int addr;
881 int length;
882
883 /* Jmp, disable bus error handler */
884 if (setjmp(rem_com_env) == 0) {
885
886 kgdb_nofault = 1;
887
888 /* Walk through, have m<addr>,<length> */
889 ptr = &in_buffer[1];
890 if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
891 if (hex_to_int(&ptr, &length)) {
892 ptr = 0;
893 if (length * 2 > OUTBUFMAX)
894 length = OUTBUFMAX / 2;
895 mem_to_hex((char *) addr, out_buffer, length);
896 }
897 if (ptr)
898 send_err_msg();
899 else
900 put_packet(out_buffer);
901 } else
902 send_err_msg();
903
904 /* Restore bus error handler */
905 kgdb_nofault = 0;
906}
907
908/* Write memory due to 'M' or 'X' message */
909static void write_mem_msg(int binary)
910{
911 char *ptr;
912 int addr;
913 int length;
914
915 if (setjmp(rem_com_env) == 0) {
916
917 kgdb_nofault = 1;
918
919 /* Walk through, have M<addr>,<length>:<data> */
920 ptr = &in_buffer[1];
921 if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
922 if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) {
923 if (binary)
924 ebin_to_mem(ptr, (char*)addr, length);
925 else
926 hex_to_mem(ptr, (char*)addr, length);
927 kgdb_flush_icache_range(addr, addr + length);
928 ptr = 0;
929 send_ok_msg();
930 }
931 if (ptr)
932 send_err_msg();
933 } else
934 send_err_msg();
935
936 /* Restore bus error handler */
937 kgdb_nofault = 0;
938}
939
940/* Continue message */
941static void continue_msg(void)
942{
943 /* Try to read optional parameter, PC unchanged if none */
944 char *ptr = &in_buffer[1];
945 int addr;
946
947 if (hex_to_int(&ptr, &addr))
948 trap_registers.pc = addr;
949}
950
951/* Continue message with signal */
952static void continue_with_sig_msg(void)
953{
954 int signal;
955 char *ptr = &in_buffer[1];
956 int addr;
957
958 /* Report limitation */
959 kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n");
960
961 /* Signal */
962 hex_to_int(&ptr, &signal);
963 if (*ptr == ';')
964 ptr++;
965
966 /* Optional address */
967 if (hex_to_int(&ptr, &addr))
968 trap_registers.pc = addr;
969}
970
971/* Step message */
972static void step_msg(void)
973{
974 continue_msg();
975 do_single_step();
976}
977
978/* Step message with signal */
979static void step_with_sig_msg(void)
980{
981 continue_with_sig_msg();
982 do_single_step();
983}
984
985/* Send register contents */
986static void send_regs_msg(void)
987{
988#ifdef CONFIG_KGDB_THREAD
989 if (!current_thread)
990 kgdb_regs_to_gdb_regs(&trap_registers, registers);
991 else
992 thread_regs_to_gdb_regs(current_thread, registers);
993#else
994 kgdb_regs_to_gdb_regs(&trap_registers, registers);
995#endif
996
997 mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
998 put_packet(out_buffer);
999}
1000
1001/* Set register contents - currently can't set other thread's registers */
1002static void set_regs_msg(void)
1003{
1004#ifdef CONFIG_KGDB_THREAD
1005 if (!current_thread) {
1006#endif
1007 kgdb_regs_to_gdb_regs(&trap_registers, registers);
1008 hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
1009 gdb_regs_to_kgdb_regs(registers, &trap_registers);
1010 send_ok_msg();
1011#ifdef CONFIG_KGDB_THREAD
1012 } else
1013 send_err_msg();
1014#endif
1015}
1016
1017
1018#ifdef CONFIG_KGDB_THREAD
1019
1020/* Set the status for a thread */
1021void set_thread_msg(void)
1022{
1023 int threadid;
1024 struct task_struct *thread = NULL;
1025 char *ptr;
1026
1027 switch (in_buffer[1]) {
1028
1029 /* To select which thread for gG etc messages, i.e. supported */
1030 case 'g':
1031
1032 ptr = &in_buffer[2];
1033 hex_to_int(&ptr, &threadid);
1034 thread = get_thread(threadid);
1035
1036 /* If we haven't found it */
1037 if (!thread) {
1038 send_err_msg();
1039 break;
1040 }
1041
1042 /* Set current_thread (or not) */
1043 if (thread == trapped_thread)
1044 current_thread = NULL;
1045 else
1046 current_thread = thread;
1047 send_ok_msg();
1048 break;
1049
1050 /* To select which thread for cCsS messages, i.e. unsupported */
1051 case 'c':
1052 send_ok_msg();
1053 break;
1054
1055 default:
1056 send_empty_msg();
1057 break;
1058 }
1059}
1060
1061/* Is a thread alive? */
1062static void thread_status_msg(void)
1063{
1064 char *ptr;
1065 int threadid;
1066 struct task_struct *thread = NULL;
1067
1068 ptr = &in_buffer[1];
1069 hex_to_int(&ptr, &threadid);
1070 thread = get_thread(threadid);
1071 if (thread)
1072 send_ok_msg();
1073 else
1074 send_err_msg();
1075}
1076/* Send the current thread ID */
1077static void thread_id_msg(void)
1078{
1079 int threadid;
1080 threadref thref;
1081
1082 out_buffer[0] = 'Q';
1083 out_buffer[1] = 'C';
1084
1085 if (current_thread)
1086 threadid = current_thread->pid;
1087 else if (trapped_thread)
1088 threadid = trapped_thread->pid;
1089 else /* Impossible, but just in case! */
1090 {
1091 send_err_msg();
1092 return;
1093 }
1094
1095 /* Translate pid 0 to PID_MAX for gdb */
1096 if (threadid == 0) threadid = PID_MAX;
1097
1098 int_to_threadref(&thref, threadid);
1099 pack_threadid(out_buffer + 2, &thref);
1100 out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0';
1101 put_packet(out_buffer);
1102}
1103
1104/* Send thread info */
1105static void thread_info_msg(void)
1106{
1107 struct task_struct *thread = NULL;
1108 int threadid;
1109 char *pos;
1110 threadref thref;
1111
1112 /* Start with 'm' */
1113 out_buffer[0] = 'm';
1114 pos = &out_buffer[1];
1115
1116 /* For all possible thread IDs - this will overrun if > 44 threads! */
1117 /* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */
1118 for (threadid = 1; threadid <= PID_MAX; threadid++) {
1119
1120 read_lock(&tasklist_lock);
1121 thread = get_thread(threadid);
1122 read_unlock(&tasklist_lock);
1123
1124 /* If it's a valid thread */
1125 if (thread) {
1126 int_to_threadref(&thref, threadid);
1127 pack_threadid(pos, &thref);
1128 pos += BUF_THREAD_ID_SIZE;
1129 *pos++ = ',';
1130 }
1131 }
1132 *--pos = 0; /* Lose final comma */
1133 put_packet(out_buffer);
1134
1135}
1136
1137/* Return printable info for gdb's 'info threads' command */
1138static void thread_extra_info_msg(void)
1139{
1140 int threadid;
1141 struct task_struct *thread = NULL;
1142 char buffer[20], *ptr;
1143 int i;
1144
1145 /* Extract thread ID */
1146 ptr = &in_buffer[17];
1147 hex_to_int(&ptr, &threadid);
1148 thread = get_thread(threadid);
1149
1150 /* If we don't recognise it, say so */
1151 if (thread == NULL)
1152 strcpy(buffer, "(unknown)");
1153 else
1154 strcpy(buffer, thread->comm);
1155
1156 /* Construct packet */
1157 for (i = 0, ptr = out_buffer; buffer[i]; i++)
1158 ptr = pack_hex_byte(ptr, buffer[i]);
1159
1160 if (thread->thread.pc == (unsigned long)ret_from_fork) {
1161 strcpy(buffer, "<new fork>");
1162 for (i = 0; buffer[i]; i++)
1163 ptr = pack_hex_byte(ptr, buffer[i]);
1164 }
1165
1166 *ptr = '\0';
1167 put_packet(out_buffer);
1168}
1169
1170/* Handle all qFooBarBaz messages - have to use an if statement as
1171 opposed to a switch because q messages can have > 1 char id. */
1172static void query_msg(void)
1173{
1174 const char *q_start = &in_buffer[1];
1175
1176 /* qC = return current thread ID */
1177 if (strncmp(q_start, "C", 1) == 0)
1178 thread_id_msg();
1179
1180 /* qfThreadInfo = query all threads (first) */
1181 else if (strncmp(q_start, "fThreadInfo", 11) == 0)
1182 thread_info_msg();
1183
1184 /* qsThreadInfo = query all threads (subsequent). We know we have sent
1185 them all after the qfThreadInfo message, so there are no to send */
1186 else if (strncmp(q_start, "sThreadInfo", 11) == 0)
1187 put_packet("l"); /* el = last */
1188
1189 /* qThreadExtraInfo = supply printable information per thread */
1190 else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0)
1191 thread_extra_info_msg();
1192
1193 /* Unsupported - empty message as per spec */
1194 else
1195 send_empty_msg();
1196}
1197#endif /* CONFIG_KGDB_THREAD */
1198
1199/*
1200 * Bring up the ports..
1201 */
1202static int kgdb_serial_setup(void)
1203{
1204 extern int kgdb_console_setup(struct console *co, char *options);
1205 struct console dummy;
1206
1207 kgdb_console_setup(&dummy, 0);
1208
1209 return 0;
1210}
1211
1212/* The command loop, read and act on requests */
1213static void kgdb_command_loop(const int excep_code, const int trapa_value)
1214{
1215 int sigval;
1216
1217 if (excep_code == NMI_VEC) {
1218#ifndef CONFIG_KGDB_NMI
1219 KGDB_PRINTK("Ignoring unexpected NMI?\n");
1220 return;
1221#else /* CONFIG_KGDB_NMI */
1222 if (!kgdb_enabled) {
1223 kgdb_enabled = 1;
1224 kgdb_init();
1225 }
1226#endif /* CONFIG_KGDB_NMI */
1227 }
1228
1229 /* Ignore if we're disabled */
1230 if (!kgdb_enabled)
1231 return;
1232
1233#ifdef CONFIG_KGDB_THREAD
1234 /* Until GDB specifies a thread */
1235 current_thread = NULL;
1236 trapped_thread = current;
1237#endif
1238
1239 /* Enter GDB mode (e.g. after detach) */
1240 if (!kgdb_in_gdb_mode) {
1241 /* Do serial setup, notify user, issue preemptive ack */
1242 kgdb_serial_setup();
1243 KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",
1244 (kgdb_porttype ? kgdb_porttype->name : ""),
1245 kgdb_portnum, kgdb_baud);
1246 kgdb_in_gdb_mode = 1;
1247 put_debug_char('+');
1248 }
1249
1250 /* Reply to host that an exception has occurred */
1251 sigval = compute_signal(excep_code);
1252 send_signal_msg(sigval);
1253
1254 /* TRAP_VEC exception indicates a software trap inserted in place of
1255 code by GDB so back up PC by one instruction, as this instruction
1256 will later be replaced by its original one. Do NOT do this for
1257 trap 0xff, since that indicates a compiled-in breakpoint which
1258 will not be replaced (and we would retake the trap forever) */
1259 if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) {
1260 trap_registers.pc -= 2;
1261 }
1262
1263 /* Undo any stepping we may have done */
1264 undo_single_step();
1265
1266 while (1) {
1267
1268 out_buffer[0] = 0;
1269 get_packet(in_buffer, BUFMAX);
1270
1271 /* Examine first char of buffer to see what we need to do */
1272 switch (in_buffer[0]) {
1273
1274 case '?': /* Send which signal we've received */
1275 send_signal_msg(sigval);
1276 break;
1277
1278 case 'g': /* Return the values of the CPU registers */
1279 send_regs_msg();
1280 break;
1281
1282 case 'G': /* Set the value of the CPU registers */
1283 set_regs_msg();
1284 break;
1285
1286 case 'm': /* Read LLLL bytes address AA..AA */
1287 read_mem_msg();
1288 break;
1289
1290 case 'M': /* Write LLLL bytes address AA..AA, ret OK */
1291 write_mem_msg(0); /* 0 = data in hex */
1292 break;
1293
1294 case 'X': /* Write LLLL bytes esc bin address AA..AA */
1295 if (kgdb_bits == '8')
1296 write_mem_msg(1); /* 1 = data in binary */
1297 else
1298 send_empty_msg();
1299 break;
1300
1301 case 'C': /* Continue, signum included, we ignore it */
1302 continue_with_sig_msg();
1303 return;
1304
1305 case 'c': /* Continue at address AA..AA (optional) */
1306 continue_msg();
1307 return;
1308
1309 case 'S': /* Step, signum included, we ignore it */
1310 step_with_sig_msg();
1311 return;
1312
1313 case 's': /* Step one instruction from AA..AA */
1314 step_msg();
1315 return;
1316
1317#ifdef CONFIG_KGDB_THREAD
1318
1319 case 'H': /* Task related */
1320 set_thread_msg();
1321 break;
1322
1323 case 'T': /* Query thread status */
1324 thread_status_msg();
1325 break;
1326
1327 case 'q': /* Handle query - currently thread-related */
1328 query_msg();
1329 break;
1330#endif
1331
1332 case 'k': /* 'Kill the program' with a kernel ? */
1333 break;
1334
1335 case 'D': /* Detach from program, send reply OK */
1336 kgdb_in_gdb_mode = 0;
1337 send_ok_msg();
1338 get_debug_char();
1339 return;
1340
1341 default:
1342 send_empty_msg();
1343 break;
1344 }
1345 }
1346}
1347
1348/* There has been an exception, most likely a breakpoint. */
1349void kgdb_handle_exception(struct pt_regs *regs)
1350{
1351 int excep_code, vbr_val;
1352 int count;
1353 int trapa_value = ctrl_inl(TRA);
1354
1355 /* Copy kernel regs (from stack) */
1356 for (count = 0; count < 16; count++)
1357 trap_registers.regs[count] = regs->regs[count];
1358 trap_registers.pc = regs->pc;
1359 trap_registers.pr = regs->pr;
1360 trap_registers.sr = regs->sr;
1361 trap_registers.gbr = regs->gbr;
1362 trap_registers.mach = regs->mach;
1363 trap_registers.macl = regs->macl;
1364
1365 asm("stc vbr, %0":"=r"(vbr_val));
1366 trap_registers.vbr = vbr_val;
1367
1368 /* Get excode for command loop call, user access */
1369 asm("stc r2_bank, %0":"=r"(excep_code));
1370 kgdb_excode = excep_code;
1371
1372 /* Other interesting environment items for reference */
1373 asm("stc r6_bank, %0":"=r"(kgdb_g_imask));
1374 kgdb_current = current;
1375 kgdb_trapa_val = trapa_value;
1376
1377 /* Act on the exception */
1378 kgdb_command_loop(excep_code >> 5, trapa_value);
1379
1380 kgdb_current = NULL;
1381
1382 /* Copy back the (maybe modified) registers */
1383 for (count = 0; count < 16; count++)
1384 regs->regs[count] = trap_registers.regs[count];
1385 regs->pc = trap_registers.pc;
1386 regs->pr = trap_registers.pr;
1387 regs->sr = trap_registers.sr;
1388 regs->gbr = trap_registers.gbr;
1389 regs->mach = trap_registers.mach;
1390 regs->macl = trap_registers.macl;
1391
1392 vbr_val = trap_registers.vbr;
1393 asm("ldc %0, vbr": :"r"(vbr_val));
1394
1395 return;
1396}
1397
1398/* Trigger a breakpoint by function */
1399void breakpoint(void)
1400{
1401 if (!kgdb_enabled) {
1402 kgdb_enabled = 1;
1403 kgdb_init();
1404 }
1405 BREAKPOINT();
1406}
1407
1408/* Initialise the KGDB data structures and serial configuration */
1409int kgdb_init(void)
1410{
1411 if (!kgdb_enabled)
1412 return 1;
1413
1414 in_nmi = 0;
1415 kgdb_nofault = 0;
1416 stepped_opcode = 0;
1417 kgdb_in_gdb_mode = 0;
1418
1419 if (kgdb_serial_setup() != 0) {
1420 KGDB_PRINTK("serial setup error\n");
1421 return -1;
1422 }
1423
1424 /* Init ptr to exception handler */
1425 kgdb_debug_hook = kgdb_handle_exception;
1426 kgdb_bus_err_hook = kgdb_handle_bus_error;
1427
1428 /* Enter kgdb now if requested, or just report init done */
1429 if (kgdb_halt) {
1430 kgdb_in_gdb_mode = 1;
1431 put_debug_char('+');
1432 breakpoint();
1433 }
1434 else
1435 {
1436 KGDB_PRINTK("stub is initialized.\n");
1437 }
1438
1439 return 0;
1440}
1441
1442/* Make function available for "user messages"; console will use it too. */
1443
1444char gdbmsgbuf[BUFMAX];
1445#define MAXOUT ((BUFMAX-2)/2)
1446
1447static void kgdb_msg_write(const char *s, unsigned count)
1448{
1449 int i;
1450 int wcount;
1451 char *bufptr;
1452
1453 /* 'O'utput */
1454 gdbmsgbuf[0] = 'O';
1455
1456 /* Fill and send buffers... */
1457 while (count > 0) {
1458 bufptr = gdbmsgbuf + 1;
1459
1460 /* Calculate how many this time */
1461 wcount = (count > MAXOUT) ? MAXOUT : count;
1462
1463 /* Pack in hex chars */
1464 for (i = 0; i < wcount; i++)
1465 bufptr = pack_hex_byte(bufptr, s[i]);
1466 *bufptr = '\0';
1467
1468 /* Move up */
1469 s += wcount;
1470 count -= wcount;
1471
1472 /* Write packet */
1473 put_packet(gdbmsgbuf);
1474 }
1475}
1476
1477static void kgdb_to_gdb(const char *s)
1478{
1479 kgdb_msg_write(s, strlen(s));
1480}
1481
1482#ifdef CONFIG_SH_KGDB_CONSOLE
1483void kgdb_console_write(struct console *co, const char *s, unsigned count)
1484{
1485 /* Bail if we're not talking to GDB */
1486 if (!kgdb_in_gdb_mode)
1487 return;
1488
1489 kgdb_msg_write(s, count);
1490}
1491#endif
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
new file mode 100644
index 000000000000..142a4e5b7ebc
--- /dev/null
+++ b/arch/sh/kernel/module.c
@@ -0,0 +1,146 @@
1/* Kernel module help for SH.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16*/
17#include <linux/moduleloader.h>
18#include <linux/elf.h>
19#include <linux/vmalloc.h>
20#include <linux/fs.h>
21#include <linux/string.h>
22#include <linux/kernel.h>
23
24#if 0
25#define DEBUGP printk
26#else
27#define DEBUGP(fmt...)
28#endif
29
30void *module_alloc(unsigned long size)
31{
32 if (size == 0)
33 return NULL;
34 return vmalloc(size);
35}
36
37
38/* Free memory returned from module_alloc */
39void module_free(struct module *mod, void *module_region)
40{
41 vfree(module_region);
42 /* FIXME: If module_region == mod->init_region, trim exception
43 table entries. */
44}
45
46/* We don't need anything special. */
47int module_frob_arch_sections(Elf_Ehdr *hdr,
48 Elf_Shdr *sechdrs,
49 char *secstrings,
50 struct module *mod)
51{
52 return 0;
53}
54
55#define COPY_UNALIGNED_WORD(sw, tw, align) \
56{ \
57 void *__s = &(sw), *__t = &(tw); \
58 unsigned short *__s2 = __s, *__t2 = __t; \
59 unsigned char *__s1 = __s, *__t1 = __t; \
60 switch ((align)) \
61 { \
62 case 0: \
63 *(unsigned long *) __t = *(unsigned long *) __s; \
64 break; \
65 case 2: \
66 *__t2++ = *__s2++; \
67 *__t2 = *__s2; \
68 break; \
69 default: \
70 *__t1++ = *__s1++; \
71 *__t1++ = *__s1++; \
72 *__t1++ = *__s1++; \
73 *__t1 = *__s1; \
74 break; \
75 } \
76}
77
78int apply_relocate_add(Elf32_Shdr *sechdrs,
79 const char *strtab,
80 unsigned int symindex,
81 unsigned int relsec,
82 struct module *me)
83{
84 unsigned int i;
85 Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
86 Elf32_Sym *sym;
87 Elf32_Addr relocation;
88 uint32_t *location;
89 uint32_t value;
90 int align;
91
92 DEBUGP("Applying relocate section %u to %u\n", relsec,
93 sechdrs[relsec].sh_info);
94 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
95 /* This is where to make the change */
96 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
97 + rel[i].r_offset;
98 /* This is the symbol it is referring to. Note that all
99 undefined symbols have been resolved. */
100 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
101 + ELF32_R_SYM(rel[i].r_info);
102 relocation = sym->st_value + rel[i].r_addend;
103 align = (int)location & 3;
104
105 switch (ELF32_R_TYPE(rel[i].r_info)) {
106 case R_SH_DIR32:
107 COPY_UNALIGNED_WORD (*location, value, align);
108 value += relocation;
109 COPY_UNALIGNED_WORD (value, *location, align);
110 break;
111 case R_SH_REL32:
112 relocation = (relocation - (Elf32_Addr) location);
113 COPY_UNALIGNED_WORD (*location, value, align);
114 value += relocation;
115 COPY_UNALIGNED_WORD (value, *location, align);
116 break;
117 default:
118 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
119 me->name, ELF32_R_TYPE(rel[i].r_info));
120 return -ENOEXEC;
121 }
122 }
123 return 0;
124}
125
126int apply_relocate(Elf32_Shdr *sechdrs,
127 const char *strtab,
128 unsigned int symindex,
129 unsigned int relsec,
130 struct module *me)
131{
132 printk(KERN_ERR "module %s: REL RELOCATION unsupported\n",
133 me->name);
134 return -ENOEXEC;
135}
136
137int module_finalize(const Elf_Ehdr *hdr,
138 const Elf_Shdr *sechdrs,
139 struct module *me)
140{
141 return 0;
142}
143
144void module_arch_cleanup(struct module *mod)
145{
146}
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
new file mode 100644
index 000000000000..3d024590c24e
--- /dev/null
+++ b/arch/sh/kernel/process.c
@@ -0,0 +1,531 @@
1/* $Id: process.c,v 1.28 2004/05/05 16:54:23 lethal Exp $
2 *
3 * linux/arch/sh/kernel/process.c
4 *
5 * Copyright (C) 1995 Linus Torvalds
6 *
7 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
8 */
9
10/*
11 * This file handles the architecture-dependent parts of process handling..
12 */
13
14#include <linux/module.h>
15#include <linux/unistd.h>
16#include <linux/mm.h>
17#include <linux/elfcore.h>
18#include <linux/slab.h>
19#include <linux/a.out.h>
20#include <linux/ptrace.h>
21#include <linux/platform.h>
22#include <linux/kallsyms.h>
23
24#include <asm/io.h>
25#include <asm/uaccess.h>
26#include <asm/mmu_context.h>
27#include <asm/elf.h>
28#if defined(CONFIG_SH_HS7751RVOIP)
29#include <asm/hs7751rvoip/hs7751rvoip.h>
30#elif defined(CONFIG_SH_RTS7751R2D)
31#include <asm/rts7751r2d/rts7751r2d.h>
32#endif
33
34static int hlt_counter=0;
35
36int ubc_usercnt = 0;
37
38#define HARD_IDLE_TIMEOUT (HZ / 3)
39
40void disable_hlt(void)
41{
42 hlt_counter++;
43}
44
45EXPORT_SYMBOL(disable_hlt);
46
47void enable_hlt(void)
48{
49 hlt_counter--;
50}
51
52EXPORT_SYMBOL(enable_hlt);
53
54void default_idle(void)
55{
56 /* endless idle loop with no priority at all */
57 while (1) {
58 if (hlt_counter) {
59 while (1)
60 if (need_resched())
61 break;
62 } else {
63 while (!need_resched())
64 cpu_sleep();
65 }
66
67 schedule();
68 }
69}
70
71void cpu_idle(void)
72{
73 default_idle();
74}
75
76void machine_restart(char * __unused)
77{
78 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
79 asm volatile("ldc %0, sr\n\t"
80 "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
81}
82
83EXPORT_SYMBOL(machine_restart);
84
85void machine_halt(void)
86{
87#if defined(CONFIG_SH_HS7751RVOIP)
88 unsigned short value;
89
90 value = ctrl_inw(PA_OUTPORTR);
91 ctrl_outw((value & 0xffdf), PA_OUTPORTR);
92#elif defined(CONFIG_SH_RTS7751R2D)
93 ctrl_outw(0x0001, PA_POWOFF);
94#endif
95 while (1)
96 cpu_sleep();
97}
98
99EXPORT_SYMBOL(machine_halt);
100
101void machine_power_off(void)
102{
103#if defined(CONFIG_SH_HS7751RVOIP)
104 unsigned short value;
105
106 value = ctrl_inw(PA_OUTPORTR);
107 ctrl_outw((value & 0xffdf), PA_OUTPORTR);
108#elif defined(CONFIG_SH_RTS7751R2D)
109 ctrl_outw(0x0001, PA_POWOFF);
110#endif
111}
112
113EXPORT_SYMBOL(machine_power_off);
114
115void show_regs(struct pt_regs * regs)
116{
117 printk("\n");
118 printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
119 print_symbol("PC is at %s\n", regs->pc);
120 printk("PC : %08lx SP : %08lx SR : %08lx ",
121 regs->pc, regs->regs[15], regs->sr);
122#ifdef CONFIG_MMU
123 printk("TEA : %08x ", ctrl_inl(MMU_TEA));
124#else
125 printk(" ");
126#endif
127 printk("%s\n", print_tainted());
128
129 printk("R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n",
130 regs->regs[0],regs->regs[1],
131 regs->regs[2],regs->regs[3]);
132 printk("R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n",
133 regs->regs[4],regs->regs[5],
134 regs->regs[6],regs->regs[7]);
135 printk("R8 : %08lx R9 : %08lx R10 : %08lx R11 : %08lx\n",
136 regs->regs[8],regs->regs[9],
137 regs->regs[10],regs->regs[11]);
138 printk("R12 : %08lx R13 : %08lx R14 : %08lx\n",
139 regs->regs[12],regs->regs[13],
140 regs->regs[14]);
141 printk("MACH: %08lx MACL: %08lx GBR : %08lx PR : %08lx\n",
142 regs->mach, regs->macl, regs->gbr, regs->pr);
143
144 /*
145 * If we're in kernel mode, dump the stack too..
146 */
147 if (!user_mode(regs)) {
148 extern void show_task(unsigned long *sp);
149 unsigned long sp = regs->regs[15];
150
151 show_task((unsigned long *)sp);
152 }
153}
154
155/*
156 * Create a kernel thread
157 */
158
159/*
160 * This is the mechanism for creating a new kernel thread.
161 *
162 */
163extern void kernel_thread_helper(void);
164__asm__(".align 5\n"
165 "kernel_thread_helper:\n\t"
166 "jsr @r5\n\t"
167 " nop\n\t"
168 "mov.l 1f, r1\n\t"
169 "jsr @r1\n\t"
170 " mov r0, r4\n\t"
171 ".align 2\n\t"
172 "1:.long do_exit");
173
174int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
175{ /* Don't use this in BL=1(cli). Or else, CPU resets! */
176 struct pt_regs regs;
177
178 memset(&regs, 0, sizeof(regs));
179 regs.regs[4] = (unsigned long) arg;
180 regs.regs[5] = (unsigned long) fn;
181
182 regs.pc = (unsigned long) kernel_thread_helper;
183 regs.sr = (1 << 30);
184
185 /* Ok, create the new process.. */
186 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
187}
188
189/*
190 * Free current thread data structures etc..
191 */
192void exit_thread(void)
193{
194 if (current->thread.ubc_pc) {
195 current->thread.ubc_pc = 0;
196 ubc_usercnt -= 1;
197 }
198}
199
200void flush_thread(void)
201{
202#if defined(CONFIG_SH_FPU)
203 struct task_struct *tsk = current;
204 struct pt_regs *regs = (struct pt_regs *)
205 ((unsigned long)tsk->thread_info
206 + THREAD_SIZE - sizeof(struct pt_regs)
207 - sizeof(unsigned long));
208
209 /* Forget lazy FPU state */
210 clear_fpu(tsk, regs);
211 clear_used_math();
212#endif
213}
214
215void release_thread(struct task_struct *dead_task)
216{
217 /* do nothing */
218}
219
220/* Fill in the fpu structure for a core dump.. */
221int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
222{
223 int fpvalid = 0;
224
225#if defined(CONFIG_SH_FPU)
226 struct task_struct *tsk = current;
227
228 fpvalid = !!tsk_used_math(tsk);
229 if (fpvalid) {
230 unlazy_fpu(tsk, regs);
231 memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
232 }
233#endif
234
235 return fpvalid;
236}
237
238/*
239 * Capture the user space registers if the task is not running (in user space)
240 */
241int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
242{
243 struct pt_regs ptregs;
244
245 ptregs = *(struct pt_regs *)
246 ((unsigned long)tsk->thread_info + THREAD_SIZE
247 - sizeof(struct pt_regs)
248#ifdef CONFIG_SH_DSP
249 - sizeof(struct pt_dspregs)
250#endif
251 - sizeof(unsigned long));
252 elf_core_copy_regs(regs, &ptregs);
253
254 return 1;
255}
256
257int
258dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *fpu)
259{
260 int fpvalid = 0;
261
262#if defined(CONFIG_SH_FPU)
263 fpvalid = !!tsk_used_math(tsk);
264 if (fpvalid) {
265 struct pt_regs *regs = (struct pt_regs *)
266 ((unsigned long)tsk->thread_info
267 + THREAD_SIZE - sizeof(struct pt_regs)
268 - sizeof(unsigned long));
269 unlazy_fpu(tsk, regs);
270 memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
271 }
272#endif
273
274 return fpvalid;
275}
276
277asmlinkage void ret_from_fork(void);
278
279int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
280 unsigned long unused,
281 struct task_struct *p, struct pt_regs *regs)
282{
283 struct pt_regs *childregs;
284#if defined(CONFIG_SH_FPU)
285 struct task_struct *tsk = current;
286
287 unlazy_fpu(tsk, regs);
288 p->thread.fpu = tsk->thread.fpu;
289 copy_to_stopped_child_used_math(p);
290#endif
291
292 childregs = ((struct pt_regs *)
293 (THREAD_SIZE + (unsigned long) p->thread_info)
294#ifdef CONFIG_SH_DSP
295 - sizeof(struct pt_dspregs)
296#endif
297 - sizeof(unsigned long)) - 1;
298 *childregs = *regs;
299
300 if (user_mode(regs)) {
301 childregs->regs[15] = usp;
302 } else {
303 childregs->regs[15] = (unsigned long)p->thread_info + THREAD_SIZE;
304 }
305 if (clone_flags & CLONE_SETTLS) {
306 childregs->gbr = childregs->regs[0];
307 }
308 childregs->regs[0] = 0; /* Set return value for child */
309
310 p->thread.sp = (unsigned long) childregs;
311 p->thread.pc = (unsigned long) ret_from_fork;
312
313 p->thread.ubc_pc = 0;
314
315 return 0;
316}
317
318/*
319 * fill in the user structure for a core dump..
320 */
321void dump_thread(struct pt_regs * regs, struct user * dump)
322{
323 dump->magic = CMAGIC;
324 dump->start_code = current->mm->start_code;
325 dump->start_data = current->mm->start_data;
326 dump->start_stack = regs->regs[15] & ~(PAGE_SIZE - 1);
327 dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT;
328 dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT;
329 dump->u_ssize = (current->mm->start_stack - dump->start_stack +
330 PAGE_SIZE - 1) >> PAGE_SHIFT;
331 /* Debug registers will come here. */
332
333 dump->regs = *regs;
334
335 dump->u_fpvalid = dump_fpu(regs, &dump->fpu);
336}
337
338/* Tracing by user break controller. */
339static void
340ubc_set_tracing(int asid, unsigned long pc)
341{
342 ctrl_outl(pc, UBC_BARA);
343
344 /* We don't have any ASID settings for the SH-2! */
345 if (cpu_data->type != CPU_SH7604)
346 ctrl_outb(asid, UBC_BASRA);
347
348 ctrl_outl(0, UBC_BAMRA);
349
350 if (cpu_data->type == CPU_SH7729) {
351 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
352 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
353 } else {
354 ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
355 ctrl_outw(BRCR_PCBA, UBC_BRCR);
356 }
357}
358
359/*
360 * switch_to(x,y) should switch tasks from x to y.
361 *
362 */
363struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next)
364{
365#if defined(CONFIG_SH_FPU)
366 struct pt_regs *regs = (struct pt_regs *)
367 ((unsigned long)prev->thread_info
368 + THREAD_SIZE - sizeof(struct pt_regs)
369 - sizeof(unsigned long));
370 unlazy_fpu(prev, regs);
371#endif
372
373#ifdef CONFIG_PREEMPT
374 {
375 unsigned long flags;
376 struct pt_regs *regs;
377
378 local_irq_save(flags);
379 regs = (struct pt_regs *)
380 ((unsigned long)prev->thread_info
381 + THREAD_SIZE - sizeof(struct pt_regs)
382#ifdef CONFIG_SH_DSP
383 - sizeof(struct pt_dspregs)
384#endif
385 - sizeof(unsigned long));
386 if (user_mode(regs) && regs->regs[15] >= 0xc0000000) {
387 int offset = (int)regs->regs[15];
388
389 /* Reset stack pointer: clear critical region mark */
390 regs->regs[15] = regs->regs[1];
391 if (regs->pc < regs->regs[0])
392 /* Go to rewind point */
393 regs->pc = regs->regs[0] + offset;
394 }
395 local_irq_restore(flags);
396 }
397#endif
398
399 /*
400 * Restore the kernel mode register
401 * k7 (r7_bank1)
402 */
403 asm volatile("ldc %0, r7_bank"
404 : /* no output */
405 : "r" (next->thread_info));
406
407#ifdef CONFIG_MMU
408 /* If no tasks are using the UBC, we're done */
409 if (ubc_usercnt == 0)
410 /* If no tasks are using the UBC, we're done */;
411 else if (next->thread.ubc_pc && next->mm) {
412 ubc_set_tracing(next->mm->context & MMU_CONTEXT_ASID_MASK,
413 next->thread.ubc_pc);
414 } else {
415 ctrl_outw(0, UBC_BBRA);
416 ctrl_outw(0, UBC_BBRB);
417 }
418#endif
419
420 return prev;
421}
422
423asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
424 unsigned long r6, unsigned long r7,
425 struct pt_regs regs)
426{
427#ifdef CONFIG_MMU
428 return do_fork(SIGCHLD, regs.regs[15], &regs, 0, NULL, NULL);
429#else
430 /* fork almost works, enough to trick you into looking elsewhere :-( */
431 return -EINVAL;
432#endif
433}
434
435asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
436 unsigned long parent_tidptr,
437 unsigned long child_tidptr,
438 struct pt_regs regs)
439{
440 if (!newsp)
441 newsp = regs.regs[15];
442 return do_fork(clone_flags, newsp, &regs, 0,
443 (int __user *)parent_tidptr, (int __user *)child_tidptr);
444}
445
446/*
447 * This is trivial, and on the face of it looks like it
448 * could equally well be done in user mode.
449 *
450 * Not so, for quite unobvious reasons - register pressure.
451 * In user mode vfork() cannot have a stack frame, and if
452 * done by calling the "clone()" system call directly, you
453 * do not have enough call-clobbered registers to hold all
454 * the information you need.
455 */
456asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
457 unsigned long r6, unsigned long r7,
458 struct pt_regs regs)
459{
460 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], &regs,
461 0, NULL, NULL);
462}
463
464/*
465 * sys_execve() executes a new program.
466 */
467asmlinkage int sys_execve(char *ufilename, char **uargv,
468 char **uenvp, unsigned long r7,
469 struct pt_regs regs)
470{
471 int error;
472 char *filename;
473
474 filename = getname((char __user *)ufilename);
475 error = PTR_ERR(filename);
476 if (IS_ERR(filename))
477 goto out;
478
479 error = do_execve(filename,
480 (char __user * __user *)uargv,
481 (char __user * __user *)uenvp,
482 &regs);
483 if (error == 0) {
484 task_lock(current);
485 current->ptrace &= ~PT_DTRACE;
486 task_unlock(current);
487 }
488 putname(filename);
489out:
490 return error;
491}
492
493unsigned long get_wchan(struct task_struct *p)
494{
495 unsigned long schedule_frame;
496 unsigned long pc;
497
498 if (!p || p == current || p->state == TASK_RUNNING)
499 return 0;
500
501 /*
502 * The same comment as on the Alpha applies here, too ...
503 */
504 pc = thread_saved_pc(p);
505 if (in_sched_functions(pc)) {
506 schedule_frame = ((unsigned long *)(long)p->thread.sp)[1];
507 return (unsigned long)((unsigned long *)schedule_frame)[1];
508 }
509 return pc;
510}
511
512asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
513 unsigned long r6, unsigned long r7,
514 struct pt_regs regs)
515{
516 /* Clear tracing. */
517 ctrl_outw(0, UBC_BBRA);
518 ctrl_outw(0, UBC_BBRB);
519 current->thread.ubc_pc = 0;
520 ubc_usercnt -= 1;
521
522 force_sig(SIGTRAP, current);
523}
524
525asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5,
526 unsigned long r6, unsigned long r7,
527 struct pt_regs regs)
528{
529 regs.pc -= 2;
530 force_sig(SIGTRAP, current);
531}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
new file mode 100644
index 000000000000..1b0dfb4d8ea4
--- /dev/null
+++ b/arch/sh/kernel/ptrace.c
@@ -0,0 +1,320 @@
1/*
2 * linux/arch/sh/kernel/ptrace.c
3 *
4 * Original x86 implementation:
5 * By Ross Biro 1/23/92
6 * edited by Linus Torvalds
7 *
8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
9 *
10 */
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/mm.h>
16#include <linux/smp.h>
17#include <linux/smp_lock.h>
18#include <linux/errno.h>
19#include <linux/ptrace.h>
20#include <linux/user.h>
21#include <linux/slab.h>
22#include <linux/security.h>
23
24#include <asm/io.h>
25#include <asm/uaccess.h>
26#include <asm/pgtable.h>
27#include <asm/system.h>
28#include <asm/processor.h>
29#include <asm/mmu_context.h>
30
31/*
32 * does not yet catch signals sent when the child dies.
33 * in exit.c or in signal.c.
34 */
35
36/*
37 * This routine will get a word off of the process kernel stack.
38 */
39static inline int get_stack_long(struct task_struct *task, int offset)
40{
41 unsigned char *stack;
42
43 stack = (unsigned char *)
44 task->thread_info + THREAD_SIZE - sizeof(struct pt_regs)
45#ifdef CONFIG_SH_DSP
46 - sizeof(struct pt_dspregs)
47#endif
48 - sizeof(unsigned long);
49 stack += offset;
50 return (*((int *)stack));
51}
52
53/*
54 * This routine will put a word on the process kernel stack.
55 */
56static inline int put_stack_long(struct task_struct *task, int offset,
57 unsigned long data)
58{
59 unsigned char *stack;
60
61 stack = (unsigned char *)
62 task->thread_info + THREAD_SIZE - sizeof(struct pt_regs)
63#ifdef CONFIG_SH_DSP
64 - sizeof(struct pt_dspregs)
65#endif
66 - sizeof(unsigned long);
67 stack += offset;
68 *(unsigned long *) stack = data;
69 return 0;
70}
71
72/*
73 * Called by kernel/ptrace.c when detaching..
74 *
75 * Make sure single step bits etc are not set.
76 */
77void ptrace_disable(struct task_struct *child)
78{
79 /* nothing to do.. */
80}
81
82asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
83{
84 struct task_struct *child;
85 struct user * dummy = NULL;
86 int ret;
87
88 lock_kernel();
89 ret = -EPERM;
90 if (request == PTRACE_TRACEME) {
91 /* are we already being traced? */
92 if (current->ptrace & PT_PTRACED)
93 goto out;
94 ret = security_ptrace(current->parent, current);
95 if (ret)
96 goto out;
97 /* set the ptrace bit in the process flags. */
98 current->ptrace |= PT_PTRACED;
99 ret = 0;
100 goto out;
101 }
102 ret = -ESRCH;
103 read_lock(&tasklist_lock);
104 child = find_task_by_pid(pid);
105 if (child)
106 get_task_struct(child);
107 read_unlock(&tasklist_lock);
108 if (!child)
109 goto out;
110
111 ret = -EPERM;
112 if (pid == 1) /* you may not mess with init */
113 goto out_tsk;
114
115 if (request == PTRACE_ATTACH) {
116 ret = ptrace_attach(child);
117 goto out_tsk;
118 }
119
120 ret = ptrace_check_attach(child, request == PTRACE_KILL);
121 if (ret < 0)
122 goto out_tsk;
123
124 switch (request) {
125 /* when I and D space are separate, these will need to be fixed. */
126 case PTRACE_PEEKTEXT: /* read word at location addr. */
127 case PTRACE_PEEKDATA: {
128 unsigned long tmp;
129 int copied;
130
131 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
132 ret = -EIO;
133 if (copied != sizeof(tmp))
134 break;
135 ret = put_user(tmp,(unsigned long *) data);
136 break;
137 }
138
139 /* read the word at location addr in the USER area. */
140 case PTRACE_PEEKUSR: {
141 unsigned long tmp;
142
143 ret = -EIO;
144 if ((addr & 3) || addr < 0 ||
145 addr > sizeof(struct user) - 3)
146 break;
147
148 if (addr < sizeof(struct pt_regs))
149 tmp = get_stack_long(child, addr);
150 else if (addr >= (long) &dummy->fpu &&
151 addr < (long) &dummy->u_fpvalid) {
152 if (!tsk_used_math(child)) {
153 if (addr == (long)&dummy->fpu.fpscr)
154 tmp = FPSCR_INIT;
155 else
156 tmp = 0;
157 } else
158 tmp = ((long *)&child->thread.fpu)
159 [(addr - (long)&dummy->fpu) >> 2];
160 } else if (addr == (long) &dummy->u_fpvalid)
161 tmp = !!tsk_used_math(child);
162 else
163 tmp = 0;
164 ret = put_user(tmp, (unsigned long *)data);
165 break;
166 }
167
168 /* when I and D space are separate, this will have to be fixed. */
169 case PTRACE_POKETEXT: /* write the word at location addr. */
170 case PTRACE_POKEDATA:
171 ret = 0;
172 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
173 break;
174 ret = -EIO;
175 break;
176
177 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
178 ret = -EIO;
179 if ((addr & 3) || addr < 0 ||
180 addr > sizeof(struct user) - 3)
181 break;
182
183 if (addr < sizeof(struct pt_regs))
184 ret = put_stack_long(child, addr, data);
185 else if (addr >= (long) &dummy->fpu &&
186 addr < (long) &dummy->u_fpvalid) {
187 set_stopped_child_used_math(child);
188 ((long *)&child->thread.fpu)
189 [(addr - (long)&dummy->fpu) >> 2] = data;
190 ret = 0;
191 } else if (addr == (long) &dummy->u_fpvalid) {
192 conditional_stopped_child_used_math(data, child);
193 ret = 0;
194 }
195 break;
196
197 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
198 case PTRACE_CONT: { /* restart after signal. */
199 ret = -EIO;
200 if ((unsigned long) data > _NSIG)
201 break;
202 if (request == PTRACE_SYSCALL)
203 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
204 else
205 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
206 child->exit_code = data;
207 wake_up_process(child);
208 ret = 0;
209 break;
210 }
211
212/*
213 * make the child exit. Best I can do is send it a sigkill.
214 * perhaps it should be put in the status that it wants to
215 * exit.
216 */
217 case PTRACE_KILL: {
218 ret = 0;
219 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
220 break;
221 child->exit_code = SIGKILL;
222 wake_up_process(child);
223 break;
224 }
225
226 case PTRACE_SINGLESTEP: { /* set the trap flag. */
227 long pc;
228 struct pt_regs *dummy = NULL;
229
230 ret = -EIO;
231 if ((unsigned long) data > _NSIG)
232 break;
233 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
234 if ((child->ptrace & PT_DTRACE) == 0) {
235 /* Spurious delayed TF traps may occur */
236 child->ptrace |= PT_DTRACE;
237 }
238
239 pc = get_stack_long(child, (long)&dummy->pc);
240
241 /* Next scheduling will set up UBC */
242 if (child->thread.ubc_pc == 0)
243 ubc_usercnt += 1;
244 child->thread.ubc_pc = pc;
245
246 child->exit_code = data;
247 /* give it a chance to run. */
248 wake_up_process(child);
249 ret = 0;
250 break;
251 }
252
253 case PTRACE_DETACH: /* detach a process that was attached. */
254 ret = ptrace_detach(child, data);
255 break;
256
257#ifdef CONFIG_SH_DSP
258 case PTRACE_GETDSPREGS: {
259 unsigned long dp;
260
261 ret = -EIO;
262 dp = ((unsigned long) child) + THREAD_SIZE -
263 sizeof(struct pt_dspregs);
264 if (*((int *) (dp - 4)) == SR_FD) {
265 copy_to_user(addr, (void *) dp,
266 sizeof(struct pt_dspregs));
267 ret = 0;
268 }
269 break;
270 }
271
272 case PTRACE_SETDSPREGS: {
273 unsigned long dp;
274 int i;
275
276 ret = -EIO;
277 dp = ((unsigned long) child) + THREAD_SIZE -
278 sizeof(struct pt_dspregs);
279 if (*((int *) (dp - 4)) == SR_FD) {
280 copy_from_user((void *) dp, addr,
281 sizeof(struct pt_dspregs));
282 ret = 0;
283 }
284 break;
285 }
286#endif
287 default:
288 ret = ptrace_request(child, request, addr, data);
289 break;
290 }
291out_tsk:
292 put_task_struct(child);
293out:
294 unlock_kernel();
295 return ret;
296}
297
298asmlinkage void do_syscall_trace(void)
299{
300 struct task_struct *tsk = current;
301
302 if (!test_thread_flag(TIF_SYSCALL_TRACE))
303 return;
304 if (!(tsk->ptrace & PT_PTRACED))
305 return;
306 /* the 0x80 provides a way for the tracing parent to distinguish
307 between a syscall stop and SIGTRAP delivery */
308 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
309 ? 0x80 : 0));
310
311 /*
312 * this isn't the same as continuing with a signal, but it will do
313 * for normal use. strace only continues with a signal if the
314 * stopping signal is not SIGTRAP. -brl
315 */
316 if (tsk->exit_code) {
317 send_sig(tsk->exit_code, tsk, 1);
318 tsk->exit_code = 0;
319 }
320}
diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c
new file mode 100644
index 000000000000..a3c24dcbf01d
--- /dev/null
+++ b/arch/sh/kernel/semaphore.c
@@ -0,0 +1,139 @@
1/*
2 * Just taken from alpha implementation.
3 * This can't work well, perhaps.
4 */
5/*
6 * Generic semaphore code. Buyer beware. Do your own
7 * specific changes in <asm/semaphore-helper.h>
8 */
9
10#include <linux/errno.h>
11#include <linux/sched.h>
12#include <linux/wait.h>
13#include <linux/init.h>
14#include <asm/semaphore.h>
15#include <asm/semaphore-helper.h>
16
17spinlock_t semaphore_wake_lock;
18
19/*
20 * Semaphores are implemented using a two-way counter:
21 * The "count" variable is decremented for each process
22 * that tries to sleep, while the "waking" variable is
23 * incremented when the "up()" code goes to wake up waiting
24 * processes.
25 *
26 * Notably, the inline "up()" and "down()" functions can
27 * efficiently test if they need to do any extra work (up
28 * needs to do something only if count was negative before
29 * the increment operation.
30 *
31 * waking_non_zero() (from asm/semaphore.h) must execute
32 * atomically.
33 *
34 * When __up() is called, the count was negative before
35 * incrementing it, and we need to wake up somebody.
36 *
37 * This routine adds one to the count of processes that need to
38 * wake up and exit. ALL waiting processes actually wake up but
39 * only the one that gets to the "waking" field first will gate
40 * through and acquire the semaphore. The others will go back
41 * to sleep.
42 *
43 * Note that these functions are only called when there is
44 * contention on the lock, and as such all this is the
45 * "non-critical" part of the whole semaphore business. The
46 * critical part is the inline stuff in <asm/semaphore.h>
47 * where we want to avoid any extra jumps and calls.
48 */
49void __up(struct semaphore *sem)
50{
51 wake_one_more(sem);
52 wake_up(&sem->wait);
53}
54
55/*
56 * Perform the "down" function. Return zero for semaphore acquired,
57 * return negative for signalled out of the function.
58 *
59 * If called from __down, the return is ignored and the wait loop is
60 * not interruptible. This means that a task waiting on a semaphore
61 * using "down()" cannot be killed until someone does an "up()" on
62 * the semaphore.
63 *
64 * If called from __down_interruptible, the return value gets checked
65 * upon return. If the return value is negative then the task continues
66 * with the negative value in the return register (it can be tested by
67 * the caller).
68 *
69 * Either form may be used in conjunction with "up()".
70 *
71 */
72
73#define DOWN_VAR \
74 struct task_struct *tsk = current; \
75 wait_queue_t wait; \
76 init_waitqueue_entry(&wait, tsk);
77
78#define DOWN_HEAD(task_state) \
79 \
80 \
81 tsk->state = (task_state); \
82 add_wait_queue(&sem->wait, &wait); \
83 \
84 /* \
85 * Ok, we're set up. sem->count is known to be less than zero \
86 * so we must wait. \
87 * \
88 * We can let go the lock for purposes of waiting. \
89 * We re-acquire it after awaking so as to protect \
90 * all semaphore operations. \
91 * \
92 * If "up()" is called before we call waking_non_zero() then \
93 * we will catch it right away. If it is called later then \
94 * we will have to go through a wakeup cycle to catch it. \
95 * \
96 * Multiple waiters contend for the semaphore lock to see \
97 * who gets to gate through and who has to wait some more. \
98 */ \
99 for (;;) {
100
101#define DOWN_TAIL(task_state) \
102 tsk->state = (task_state); \
103 } \
104 tsk->state = TASK_RUNNING; \
105 remove_wait_queue(&sem->wait, &wait);
106
107void __sched __down(struct semaphore * sem)
108{
109 DOWN_VAR
110 DOWN_HEAD(TASK_UNINTERRUPTIBLE)
111 if (waking_non_zero(sem))
112 break;
113 schedule();
114 DOWN_TAIL(TASK_UNINTERRUPTIBLE)
115}
116
117int __sched __down_interruptible(struct semaphore * sem)
118{
119 int ret = 0;
120 DOWN_VAR
121 DOWN_HEAD(TASK_INTERRUPTIBLE)
122
123 ret = waking_non_zero_interruptible(sem, tsk);
124 if (ret)
125 {
126 if (ret == 1)
127 /* ret != 0 only if we get interrupted -arca */
128 ret = 0;
129 break;
130 }
131 schedule();
132 DOWN_TAIL(TASK_INTERRUPTIBLE)
133 return ret;
134}
135
136int __down_trylock(struct semaphore * sem)
137{
138 return waking_non_zero_trylock(sem);
139}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
new file mode 100644
index 000000000000..25b9d9ebe858
--- /dev/null
+++ b/arch/sh/kernel/setup.c
@@ -0,0 +1,649 @@
1/* $Id: setup.c,v 1.30 2003/10/13 07:21:19 lethal Exp $
2 *
3 * linux/arch/sh/kernel/setup.c
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2002, 2003 Paul Mundt
7 */
8
9/*
10 * This file handles the architecture-dependent parts of initialization
11 */
12
13#include <linux/tty.h>
14#include <linux/ioport.h>
15#include <linux/init.h>
16#include <linux/initrd.h>
17#include <linux/bootmem.h>
18#include <linux/console.h>
19#include <linux/seq_file.h>
20#include <linux/root_dev.h>
21#include <linux/utsname.h>
22#include <linux/cpu.h>
23#include <asm/uaccess.h>
24#include <asm/io.h>
25#include <asm/io_generic.h>
26#include <asm/sections.h>
27#include <asm/irq.h>
28#include <asm/setup.h>
29
30#ifdef CONFIG_SH_KGDB
31#include <asm/kgdb.h>
32static int kgdb_parse_options(char *options);
33#endif
34extern void * __rd_start, * __rd_end;
35/*
36 * Machine setup..
37 */
38
39/*
40 * Initialize loops_per_jiffy as 10000000 (1000MIPS).
41 * This value will be used at the very early stage of serial setup.
42 * The bigger value means no problem.
43 */
44struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 10000000, };
45struct screen_info screen_info;
46
47#if defined(CONFIG_SH_UNKNOWN)
48struct sh_machine_vector sh_mv;
49#endif
50
51/* We need this to satisfy some external references. */
52struct screen_info screen_info = {
53 0, 25, /* orig-x, orig-y */
54 0, /* unused */
55 0, /* orig-video-page */
56 0, /* orig-video-mode */
57 80, /* orig-video-cols */
58 0,0,0, /* ega_ax, ega_bx, ega_cx */
59 25, /* orig-video-lines */
60 0, /* orig-video-isVGA */
61 16 /* orig-video-points */
62};
63
64extern void platform_setup(void);
65extern char *get_system_type(void);
66extern int root_mountflags;
67
68#define MV_NAME_SIZE 32
69
70static struct sh_machine_vector* __init get_mv_byname(const char* name);
71
72/*
73 * This is set up by the setup-routine at boot-time
74 */
75#define PARAM ((unsigned char *)empty_zero_page)
76
77#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000))
78#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004))
79#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008))
80#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c))
81#define INITRD_START (*(unsigned long *) (PARAM+0x010))
82#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014))
83/* ... */
84#define COMMAND_LINE ((char *) (PARAM+0x100))
85
86#define RAMDISK_IMAGE_START_MASK 0x07FF
87#define RAMDISK_PROMPT_FLAG 0x8000
88#define RAMDISK_LOAD_FLAG 0x4000
89
90static char command_line[COMMAND_LINE_SIZE] = { 0, };
91
92struct resource standard_io_resources[] = {
93 { "dma1", 0x00, 0x1f },
94 { "pic1", 0x20, 0x3f },
95 { "timer", 0x40, 0x5f },
96 { "keyboard", 0x60, 0x6f },
97 { "dma page reg", 0x80, 0x8f },
98 { "pic2", 0xa0, 0xbf },
99 { "dma2", 0xc0, 0xdf },
100 { "fpu", 0xf0, 0xff }
101};
102
103#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
104
105/* System RAM - interrupted by the 640kB-1M hole */
106#define code_resource (ram_resources[3])
107#define data_resource (ram_resources[4])
108static struct resource ram_resources[] = {
109 { "System RAM", 0x000000, 0x09ffff, IORESOURCE_BUSY },
110 { "System RAM", 0x100000, 0x100000, IORESOURCE_BUSY },
111 { "Video RAM area", 0x0a0000, 0x0bffff },
112 { "Kernel code", 0x100000, 0 },
113 { "Kernel data", 0, 0 }
114};
115
116unsigned long memory_start, memory_end;
117
118static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
119 struct sh_machine_vector** mvp,
120 unsigned long *mv_io_base,
121 int *mv_mmio_enable)
122{
123 char c = ' ', *to = command_line, *from = COMMAND_LINE;
124 int len = 0;
125
126 /* Save unparsed command line copy for /proc/cmdline */
127 memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
128 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
129
130 memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
131 memory_end = memory_start + __MEMORY_SIZE;
132
133 for (;;) {
134 /*
135 * "mem=XXX[kKmM]" defines a size of memory.
136 */
137 if (c == ' ' && !memcmp(from, "mem=", 4)) {
138 if (to != command_line)
139 to--;
140 {
141 unsigned long mem_size;
142
143 mem_size = memparse(from+4, &from);
144 memory_end = memory_start + mem_size;
145 }
146 }
147 if (c == ' ' && !memcmp(from, "sh_mv=", 6)) {
148 char* mv_end;
149 char* mv_comma;
150 int mv_len;
151 if (to != command_line)
152 to--;
153 from += 6;
154 mv_end = strchr(from, ' ');
155 if (mv_end == NULL)
156 mv_end = from + strlen(from);
157
158 mv_comma = strchr(from, ',');
159 if ((mv_comma != NULL) && (mv_comma < mv_end)) {
160 int ints[3];
161 get_options(mv_comma+1, ARRAY_SIZE(ints), ints);
162 *mv_io_base = ints[1];
163 *mv_mmio_enable = ints[2];
164 mv_len = mv_comma - from;
165 } else {
166 mv_len = mv_end - from;
167 }
168 if (mv_len > (MV_NAME_SIZE-1))
169 mv_len = MV_NAME_SIZE-1;
170 memcpy(mv_name, from, mv_len);
171 mv_name[mv_len] = '\0';
172 from = mv_end;
173
174 *mvp = get_mv_byname(mv_name);
175 }
176 c = *(from++);
177 if (!c)
178 break;
179 if (COMMAND_LINE_SIZE <= ++len)
180 break;
181 *(to++) = c;
182 }
183 *to = '\0';
184 *cmdline_p = command_line;
185}
186
187static int __init sh_mv_setup(char **cmdline_p)
188{
189#if defined(CONFIG_SH_UNKNOWN)
190 extern struct sh_machine_vector mv_unknown;
191#endif
192 struct sh_machine_vector *mv = NULL;
193 char mv_name[MV_NAME_SIZE] = "";
194 unsigned long mv_io_base = 0;
195 int mv_mmio_enable = 0;
196
197 parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);
198
199#ifdef CONFIG_SH_GENERIC
200 if (mv == NULL) {
201 mv = &mv_unknown;
202 if (*mv_name != '\0') {
203 printk("Warning: Unsupported machine %s, using unknown\n",
204 mv_name);
205 }
206 }
207 sh_mv = *mv;
208#endif
209#ifdef CONFIG_SH_UNKNOWN
210 sh_mv = mv_unknown;
211#endif
212
213 /*
214 * Manually walk the vec, fill in anything that the board hasn't yet
215 * by hand, wrapping to the generic implementation.
216 */
217#define mv_set(elem) do { \
218 if (!sh_mv.mv_##elem) \
219 sh_mv.mv_##elem = generic_##elem; \
220} while (0)
221
222 mv_set(inb); mv_set(inw); mv_set(inl);
223 mv_set(outb); mv_set(outw); mv_set(outl);
224
225 mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
226 mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
227
228 mv_set(insb); mv_set(insw); mv_set(insl);
229 mv_set(outsb); mv_set(outsw); mv_set(outsl);
230
231 mv_set(readb); mv_set(readw); mv_set(readl);
232 mv_set(writeb); mv_set(writew); mv_set(writel);
233
234 mv_set(ioremap);
235 mv_set(iounmap);
236
237 mv_set(isa_port2addr);
238 mv_set(irq_demux);
239
240#ifdef CONFIG_SH_UNKNOWN
241 __set_io_port_base(mv_io_base);
242#endif
243
244 return 0;
245}
246
247void __init setup_arch(char **cmdline_p)
248{
249 unsigned long bootmap_size;
250 unsigned long start_pfn, max_pfn, max_low_pfn;
251
252#ifdef CONFIG_EARLY_PRINTK
253 extern void enable_early_printk(void);
254
255 enable_early_printk();
256#endif
257#ifdef CONFIG_CMDLINE_BOOL
258 strcpy(COMMAND_LINE, CONFIG_CMDLINE);
259#endif
260
261 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
262
263#ifdef CONFIG_BLK_DEV_RAM
264 rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
265 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
266 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
267#endif
268
269 if (!MOUNT_ROOT_RDONLY)
270 root_mountflags &= ~MS_RDONLY;
271 init_mm.start_code = (unsigned long) _text;
272 init_mm.end_code = (unsigned long) _etext;
273 init_mm.end_data = (unsigned long) _edata;
274 init_mm.brk = (unsigned long) _end;
275
276 code_resource.start = virt_to_bus(_text);
277 code_resource.end = virt_to_bus(_etext)-1;
278 data_resource.start = virt_to_bus(_etext);
279 data_resource.end = virt_to_bus(_edata)-1;
280
281 sh_mv_setup(cmdline_p);
282
283#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
284#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
285#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
286
287#ifdef CONFIG_DISCONTIGMEM
288 NODE_DATA(0)->bdata = &discontig_node_bdata[0];
289 NODE_DATA(1)->bdata = &discontig_node_bdata[1];
290
291 bootmap_size = init_bootmem_node(NODE_DATA(1),
292 PFN_UP(__MEMORY_START_2ND),
293 PFN_UP(__MEMORY_START_2ND),
294 PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
295 free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
296 reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
297#endif
298
299 /*
300 * Find the highest page frame number we have available
301 */
302 max_pfn = PFN_DOWN(__pa(memory_end));
303
304 /*
305 * Determine low and high memory ranges:
306 */
307 max_low_pfn = max_pfn;
308
309 /*
310 * Partially used pages are not usable - thus
311 * we are rounding upwards:
312 */
313 start_pfn = PFN_UP(__pa(_end));
314
315 /*
316 * Find a proper area for the bootmem bitmap. After this
317 * bootstrap step all allocations (until the page allocator
318 * is intact) must be done via bootmem_alloc().
319 */
320 bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
321 __MEMORY_START>>PAGE_SHIFT,
322 max_low_pfn);
323 /*
324 * Register fully available low RAM pages with the bootmem allocator.
325 */
326 {
327 unsigned long curr_pfn, last_pfn, pages;
328
329 /*
330 * We are rounding up the start address of usable memory:
331 */
332 curr_pfn = PFN_UP(__MEMORY_START);
333 /*
334 * ... and at the end of the usable range downwards:
335 */
336 last_pfn = PFN_DOWN(__pa(memory_end));
337
338 if (last_pfn > max_low_pfn)
339 last_pfn = max_low_pfn;
340
341 pages = last_pfn - curr_pfn;
342 free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
343 PFN_PHYS(pages));
344 }
345
346 /*
347 * Reserve the kernel text and
348 * Reserve the bootmem bitmap. We do this in two steps (first step
349 * was init_bootmem()), because this catches the (definitely buggy)
350 * case of us accidentally initializing the bootmem allocator with
351 * an invalid RAM area.
352 */
353 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
354 (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
355
356 /*
357 * reserve physical page 0 - it's a special BIOS page on many boxes,
358 * enabling clean reboots, SMP operation, laptop functions.
359 */
360 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
361
362#ifdef CONFIG_BLK_DEV_INITRD
363 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
364 if (&__rd_start != &__rd_end) {
365 LOADER_TYPE = 1;
366 INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
367 INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
368 }
369
370 if (LOADER_TYPE && INITRD_START) {
371 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
372 reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
373 initrd_start =
374 INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
375 initrd_end = initrd_start + INITRD_SIZE;
376 } else {
377 printk("initrd extends beyond end of memory "
378 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
379 INITRD_START + INITRD_SIZE,
380 max_low_pfn << PAGE_SHIFT);
381 initrd_start = 0;
382 }
383 }
384#endif
385
386#ifdef CONFIG_DUMMY_CONSOLE
387 conswitchp = &dummy_con;
388#endif
389
390 /* Perform the machine specific initialisation */
391 platform_setup();
392
393 paging_init();
394}
395
396struct sh_machine_vector* __init get_mv_byname(const char* name)
397{
398 extern int strcasecmp(const char *, const char *);
399 extern long __machvec_start, __machvec_end;
400 struct sh_machine_vector *all_vecs =
401 (struct sh_machine_vector *)&__machvec_start;
402
403 int i, n = ((unsigned long)&__machvec_end
404 - (unsigned long)&__machvec_start)/
405 sizeof(struct sh_machine_vector);
406
407 for (i = 0; i < n; ++i) {
408 struct sh_machine_vector *mv = &all_vecs[i];
409 if (mv == NULL)
410 continue;
411 if (strcasecmp(name, get_system_type()) == 0) {
412 return mv;
413 }
414 }
415 return NULL;
416}
417
418static struct cpu cpu[NR_CPUS];
419
420static int __init topology_init(void)
421{
422 int cpu_id;
423
424 for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++)
425 if (cpu_possible(cpu_id))
426 register_cpu(&cpu[cpu_id], cpu_id, NULL);
427
428 return 0;
429}
430
431subsys_initcall(topology_init);
432
433static const char *cpu_name[] = {
434 [CPU_SH7604] = "SH7604",
435 [CPU_SH7705] = "SH7705",
436 [CPU_SH7708] = "SH7708",
437 [CPU_SH7729] = "SH7729",
438 [CPU_SH7300] = "SH7300",
439 [CPU_SH7750] = "SH7750",
440 [CPU_SH7750S] = "SH7750S",
441 [CPU_SH7750R] = "SH7750R",
442 [CPU_SH7751] = "SH7751",
443 [CPU_SH7751R] = "SH7751R",
444 [CPU_SH7760] = "SH7760",
445 [CPU_SH73180] = "SH73180",
446 [CPU_ST40RA] = "ST40RA",
447 [CPU_ST40GX1] = "ST40GX1",
448 [CPU_SH4_202] = "SH4-202",
449 [CPU_SH4_501] = "SH4-501",
450 [CPU_SH_NONE] = "Unknown"
451};
452
453const char *get_cpu_subtype(void)
454{
455 return cpu_name[boot_cpu_data.type];
456}
457
458#ifdef CONFIG_PROC_FS
459static const char *cpu_flags[] = {
460 "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
461};
462
463static void show_cpuflags(struct seq_file *m)
464{
465 unsigned long i;
466
467 seq_printf(m, "cpu flags\t:");
468
469 if (!cpu_data->flags) {
470 seq_printf(m, " %s\n", cpu_flags[0]);
471 return;
472 }
473
474 for (i = 0; i < cpu_data->flags; i++)
475 if ((cpu_data->flags & (1 << i)))
476 seq_printf(m, " %s", cpu_flags[i+1]);
477
478 seq_printf(m, "\n");
479}
480
481static void show_cacheinfo(struct seq_file *m, const char *type, struct cache_info info)
482{
483 unsigned int cache_size;
484
485 cache_size = info.ways * info.sets * info.linesz;
486
487 seq_printf(m, "%s size\t: %dKiB\n", type, cache_size >> 10);
488}
489
490/*
491 * Get CPU information for use by the procfs.
492 */
493static int show_cpuinfo(struct seq_file *m, void *v)
494{
495 unsigned int cpu = smp_processor_id();
496
497 if (!cpu && cpu_online(cpu))
498 seq_printf(m, "machine\t\t: %s\n", get_system_type());
499
500 seq_printf(m, "processor\t: %d\n", cpu);
501 seq_printf(m, "cpu family\t: %s\n", system_utsname.machine);
502 seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
503
504 show_cpuflags(m);
505
506 seq_printf(m, "cache type\t: ");
507
508 /*
509 * Check for what type of cache we have, we support both the
510 * unified cache on the SH-2 and SH-3, as well as the harvard
511 * style cache on the SH-4.
512 */
513 if (test_bit(SH_CACHE_COMBINED, &(boot_cpu_data.icache.flags))) {
514 seq_printf(m, "unified\n");
515 show_cacheinfo(m, "cache", boot_cpu_data.icache);
516 } else {
517 seq_printf(m, "split (harvard)\n");
518 show_cacheinfo(m, "icache", boot_cpu_data.icache);
519 show_cacheinfo(m, "dcache", boot_cpu_data.dcache);
520 }
521
522 seq_printf(m, "bogomips\t: %lu.%02lu\n",
523 boot_cpu_data.loops_per_jiffy/(500000/HZ),
524 (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100);
525
526#define PRINT_CLOCK(name, value) \
527 seq_printf(m, name " clock\t: %d.%02dMHz\n", \
528 ((value) / 1000000), ((value) % 1000000)/10000)
529
530 PRINT_CLOCK("cpu", boot_cpu_data.cpu_clock);
531 PRINT_CLOCK("bus", boot_cpu_data.bus_clock);
532#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
533 PRINT_CLOCK("memory", boot_cpu_data.memory_clock);
534#endif
535 PRINT_CLOCK("module", boot_cpu_data.module_clock);
536
537 return 0;
538}
539
540
541static void *c_start(struct seq_file *m, loff_t *pos)
542{
543 return *pos < NR_CPUS ? cpu_data + *pos : NULL;
544}
545static void *c_next(struct seq_file *m, void *v, loff_t *pos)
546{
547 ++*pos;
548 return c_start(m, pos);
549}
550static void c_stop(struct seq_file *m, void *v)
551{
552}
553struct seq_operations cpuinfo_op = {
554 .start = c_start,
555 .next = c_next,
556 .stop = c_stop,
557 .show = show_cpuinfo,
558};
559#endif /* CONFIG_PROC_FS */
560
561#ifdef CONFIG_SH_KGDB
562/*
563 * Parse command-line kgdb options. By default KGDB is enabled,
564 * entered on error (or other action) using default serial info.
565 * The command-line option can include a serial port specification
566 * and an action to override default or configured behavior.
567 */
568struct kgdb_sermap kgdb_sci_sermap =
569{ "ttySC", 5, kgdb_sci_setup, NULL };
570
571struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
572struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
573
574void kgdb_register_sermap(struct kgdb_sermap *map)
575{
576 struct kgdb_sermap *last;
577
578 for (last = kgdb_serlist; last->next; last = last->next)
579 ;
580 last->next = map;
581 if (!map->namelen) {
582 map->namelen = strlen(map->name);
583 }
584}
585
586static int __init kgdb_parse_options(char *options)
587{
588 char c;
589 int baud;
590
591 /* Check for port spec (or use default) */
592
593 /* Determine port type and instance */
594 if (!memcmp(options, "tty", 3)) {
595 struct kgdb_sermap *map = kgdb_serlist;
596
597 while (map && memcmp(options, map->name, map->namelen))
598 map = map->next;
599
600 if (!map) {
601 KGDB_PRINTK("unknown port spec in %s\n", options);
602 return -1;
603 }
604
605 kgdb_porttype = map;
606 kgdb_serial_setup = map->setup_fn;
607 kgdb_portnum = options[map->namelen] - '0';
608 options += map->namelen + 1;
609
610 options = (*options == ',') ? options+1 : options;
611
612 /* Read optional parameters (baud/parity/bits) */
613 baud = simple_strtoul(options, &options, 10);
614 if (baud != 0) {
615 kgdb_baud = baud;
616
617 c = toupper(*options);
618 if (c == 'E' || c == 'O' || c == 'N') {
619 kgdb_parity = c;
620 options++;
621 }
622
623 c = *options;
624 if (c == '7' || c == '8') {
625 kgdb_bits = c;
626 options++;
627 }
628 options = (*options == ',') ? options+1 : options;
629 }
630 }
631
632 /* Check for action specification */
633 if (!memcmp(options, "halt", 4)) {
634 kgdb_halt = 1;
635 options += 4;
636 } else if (!memcmp(options, "disabled", 8)) {
637 kgdb_enabled = 0;
638 options += 8;
639 }
640
641 if (*options) {
642 KGDB_PRINTK("ignored unknown options: %s\n", options);
643 return 0;
644 }
645 return 1;
646}
647__setup("kgdb=", kgdb_parse_options);
648#endif /* CONFIG_SH_KGDB */
649
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
new file mode 100644
index 000000000000..5b53e10bb9cd
--- /dev/null
+++ b/arch/sh/kernel/sh_bios.c
@@ -0,0 +1,75 @@
1/*
2 * linux/arch/sh/kernel/sh_bios.c
3 * C interface for trapping into the standard LinuxSH BIOS.
4 *
5 * Copyright (C) 2000 Greg Banks, Mitch Davis
6 *
7 */
8
9#include <asm/sh_bios.h>
10
11#define BIOS_CALL_CONSOLE_WRITE 0
12#define BIOS_CALL_READ_BLOCK 1
13#define BIOS_CALL_ETH_NODE_ADDR 10
14#define BIOS_CALL_SHUTDOWN 11
15#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
16#define BIOS_CALL_GDB_GET_MODE_PTR 0xfe
17#define BIOS_CALL_GDB_DETACH 0xff
18
19static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3)
20{
21 register long r0 __asm__("r0") = func;
22 register long r4 __asm__("r4") = arg0;
23 register long r5 __asm__("r5") = arg1;
24 register long r6 __asm__("r6") = arg2;
25 register long r7 __asm__("r7") = arg3;
26 __asm__ __volatile__("trapa #0x3f"
27 : "=z" (r0)
28 : "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7)
29 : "memory");
30 return r0;
31}
32
33
34void sh_bios_console_write(const char *buf, unsigned int len)
35{
36 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
37}
38
39
40void sh_bios_char_out(char ch)
41{
42 sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
43}
44
45
46int sh_bios_in_gdb_mode(void)
47{
48 static char queried = 0;
49 static char *gdb_mode_p = 0;
50
51 if (!queried)
52 {
53 /* Query the gdb stub for address of its gdb mode variable */
54 long r = sh_bios_call(BIOS_CALL_GDB_GET_MODE_PTR, 0, 0, 0, 0);
55 if (r != ~0) /* BIOS returns -1 for unknown function */
56 gdb_mode_p = (char *)r;
57 queried = 1;
58 }
59 return (gdb_mode_p != 0 ? *gdb_mode_p : 0);
60}
61
62void sh_bios_gdb_detach(void)
63{
64 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
65}
66
67void sh_bios_get_node_addr (unsigned char *node_addr)
68{
69 sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0);
70}
71
72void sh_bios_shutdown(unsigned int how)
73{
74 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
75}
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
new file mode 100644
index 000000000000..6954fd62470a
--- /dev/null
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -0,0 +1,126 @@
1#include <linux/config.h>
2#include <linux/module.h>
3#include <linux/smp.h>
4#include <linux/user.h>
5#include <linux/elfcore.h>
6#include <linux/sched.h>
7#include <linux/in6.h>
8#include <linux/interrupt.h>
9#include <linux/smp_lock.h>
10#include <linux/vmalloc.h>
11#include <linux/pci.h>
12#include <linux/irq.h>
13
14#include <asm/semaphore.h>
15#include <asm/processor.h>
16#include <asm/uaccess.h>
17#include <asm/checksum.h>
18#include <asm/io.h>
19#include <asm/delay.h>
20#include <asm/tlbflush.h>
21#include <asm/cacheflush.h>
22#include <asm/checksum.h>
23
24extern void dump_thread(struct pt_regs *, struct user *);
25extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
26extern struct hw_interrupt_type no_irq_type;
27
28EXPORT_SYMBOL(sh_mv);
29
30/* platform dependent support */
31EXPORT_SYMBOL(dump_thread);
32EXPORT_SYMBOL(dump_fpu);
33EXPORT_SYMBOL(iounmap);
34EXPORT_SYMBOL(enable_irq);
35EXPORT_SYMBOL(disable_irq);
36EXPORT_SYMBOL(probe_irq_mask);
37EXPORT_SYMBOL(kernel_thread);
38EXPORT_SYMBOL(disable_irq_nosync);
39EXPORT_SYMBOL(irq_desc);
40EXPORT_SYMBOL(no_irq_type);
41
42EXPORT_SYMBOL(strpbrk);
43EXPORT_SYMBOL(strstr);
44EXPORT_SYMBOL(strlen);
45EXPORT_SYMBOL(strnlen);
46EXPORT_SYMBOL(strchr);
47EXPORT_SYMBOL(strcat);
48EXPORT_SYMBOL(strncat);
49
50/* PCI exports */
51#ifdef CONFIG_PCI
52EXPORT_SYMBOL(pci_alloc_consistent);
53EXPORT_SYMBOL(pci_free_consistent);
54#endif
55
56/* mem exports */
57EXPORT_SYMBOL(memchr);
58EXPORT_SYMBOL(memcpy);
59EXPORT_SYMBOL(memcpy_fromio);
60EXPORT_SYMBOL(memcpy_toio);
61EXPORT_SYMBOL(memset);
62EXPORT_SYMBOL(memset_io);
63EXPORT_SYMBOL(memmove);
64EXPORT_SYMBOL(memcmp);
65EXPORT_SYMBOL(memscan);
66EXPORT_SYMBOL(__copy_user);
67EXPORT_SYMBOL(boot_cpu_data);
68
69#ifdef CONFIG_MMU
70EXPORT_SYMBOL(get_vm_area);
71#endif
72
73/* semaphore exports */
74EXPORT_SYMBOL(__up);
75EXPORT_SYMBOL(__down);
76EXPORT_SYMBOL(__down_interruptible);
77
78EXPORT_SYMBOL(__udelay);
79EXPORT_SYMBOL(__ndelay);
80EXPORT_SYMBOL(__const_udelay);
81
82EXPORT_SYMBOL(__div64_32);
83
84#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
85
86/* These symbols are generated by the compiler itself */
87DECLARE_EXPORT(__udivsi3);
88DECLARE_EXPORT(__udivdi3);
89DECLARE_EXPORT(__sdivsi3);
90DECLARE_EXPORT(__ashrdi3);
91DECLARE_EXPORT(__ashldi3);
92DECLARE_EXPORT(__lshrdi3);
93DECLARE_EXPORT(__movstr);
94
95EXPORT_SYMBOL(strcpy);
96
97#ifdef CONFIG_CPU_SH4
98DECLARE_EXPORT(__movstr_i4_even);
99DECLARE_EXPORT(__movstr_i4_odd);
100DECLARE_EXPORT(__movstrSI12_i4);
101
102/* needed by some modules */
103EXPORT_SYMBOL(flush_cache_all);
104EXPORT_SYMBOL(flush_cache_range);
105EXPORT_SYMBOL(flush_dcache_page);
106EXPORT_SYMBOL(__flush_purge_region);
107#endif
108
109#if defined(CONFIG_SH7705_CACHE_32KB)
110EXPORT_SYMBOL(flush_cache_all);
111EXPORT_SYMBOL(flush_cache_range);
112EXPORT_SYMBOL(flush_dcache_page);
113EXPORT_SYMBOL(__flush_purge_region);
114#endif
115
116EXPORT_SYMBOL(flush_tlb_page);
117EXPORT_SYMBOL(__down_trylock);
118
119#ifdef CONFIG_SMP
120EXPORT_SYMBOL(synchronize_irq);
121#endif
122
123EXPORT_SYMBOL(csum_partial);
124EXPORT_SYMBOL(csum_ipv6_magic);
125EXPORT_SYMBOL(consistent_sync);
126EXPORT_SYMBOL(clear_page);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
new file mode 100644
index 000000000000..06f1b47eded9
--- /dev/null
+++ b/arch/sh/kernel/signal.c
@@ -0,0 +1,607 @@
1/*
2 * linux/arch/sh/kernel/signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 *
8 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
9 *
10 */
11
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/kernel.h>
17#include <linux/signal.h>
18#include <linux/errno.h>
19#include <linux/wait.h>
20#include <linux/ptrace.h>
21#include <linux/unistd.h>
22#include <linux/stddef.h>
23#include <linux/tty.h>
24#include <linux/personality.h>
25#include <linux/binfmts.h>
26
27#include <asm/ucontext.h>
28#include <asm/uaccess.h>
29#include <asm/pgtable.h>
30#include <asm/cacheflush.h>
31
32#define DEBUG_SIG 0
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
37
38/*
39 * Atomically swap in the new signal mask, and wait for a signal.
40 */
41asmlinkage int
42sys_sigsuspend(old_sigset_t mask,
43 unsigned long r5, unsigned long r6, unsigned long r7,
44 struct pt_regs regs)
45{
46 sigset_t saveset;
47
48 mask &= _BLOCKABLE;
49 spin_lock_irq(&current->sighand->siglock);
50 saveset = current->blocked;
51 siginitset(&current->blocked, mask);
52 recalc_sigpending();
53 spin_unlock_irq(&current->sighand->siglock);
54
55 regs.regs[0] = -EINTR;
56 while (1) {
57 current->state = TASK_INTERRUPTIBLE;
58 schedule();
59 if (do_signal(&regs, &saveset))
60 return -EINTR;
61 }
62}
63
64asmlinkage int
65sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
66 unsigned long r6, unsigned long r7,
67 struct pt_regs regs)
68{
69 sigset_t saveset, newset;
70
71 /* XXX: Don't preclude handling different sized sigset_t's. */
72 if (sigsetsize != sizeof(sigset_t))
73 return -EINVAL;
74
75 if (copy_from_user(&newset, unewset, sizeof(newset)))
76 return -EFAULT;
77 sigdelsetmask(&newset, ~_BLOCKABLE);
78 spin_lock_irq(&current->sighand->siglock);
79 saveset = current->blocked;
80 current->blocked = newset;
81 recalc_sigpending();
82 spin_unlock_irq(&current->sighand->siglock);
83
84 regs.regs[0] = -EINTR;
85 while (1) {
86 current->state = TASK_INTERRUPTIBLE;
87 schedule();
88 if (do_signal(&regs, &saveset))
89 return -EINTR;
90 }
91}
92
93asmlinkage int
94sys_sigaction(int sig, const struct old_sigaction __user *act,
95 struct old_sigaction __user *oact)
96{
97 struct k_sigaction new_ka, old_ka;
98 int ret;
99
100 if (act) {
101 old_sigset_t mask;
102 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
103 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
104 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
105 return -EFAULT;
106 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
107 __get_user(mask, &act->sa_mask);
108 siginitset(&new_ka.sa.sa_mask, mask);
109 }
110
111 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
112
113 if (!ret && oact) {
114 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
115 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
116 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
117 return -EFAULT;
118 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
119 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
120 }
121
122 return ret;
123}
124
125asmlinkage int
126sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
127 unsigned long r6, unsigned long r7,
128 struct pt_regs regs)
129{
130 return do_sigaltstack(uss, uoss, regs.regs[15]);
131}
132
133
134/*
135 * Do a signal return; undo the signal stack.
136 */
137
138#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
139#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */
140#define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */
141
142struct sigframe
143{
144 struct sigcontext sc;
145 unsigned long extramask[_NSIG_WORDS-1];
146 u16 retcode[8];
147};
148
149struct rt_sigframe
150{
151 struct siginfo info;
152 struct ucontext uc;
153 u16 retcode[8];
154};
155
156#ifdef CONFIG_SH_FPU
157static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
158{
159 struct task_struct *tsk = current;
160
161 if (!(cpu_data->flags & CPU_HAS_FPU))
162 return 0;
163
164 set_used_math();
165 return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0],
166 sizeof(long)*(16*2+2));
167}
168
169static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
170 struct pt_regs *regs)
171{
172 struct task_struct *tsk = current;
173
174 if (!(cpu_data->flags & CPU_HAS_FPU))
175 return 0;
176
177 if (!used_math()) {
178 __put_user(0, &sc->sc_ownedfp);
179 return 0;
180 }
181
182 __put_user(1, &sc->sc_ownedfp);
183
184 /* This will cause a "finit" to be triggered by the next
185 attempted FPU operation by the 'current' process.
186 */
187 clear_used_math();
188
189 unlazy_fpu(tsk, regs);
190 return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard,
191 sizeof(long)*(16*2+2));
192}
193#endif /* CONFIG_SH_FPU */
194
195static int
196restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p)
197{
198 unsigned int err = 0;
199
200#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
201 COPY(regs[1]);
202 COPY(regs[2]); COPY(regs[3]);
203 COPY(regs[4]); COPY(regs[5]);
204 COPY(regs[6]); COPY(regs[7]);
205 COPY(regs[8]); COPY(regs[9]);
206 COPY(regs[10]); COPY(regs[11]);
207 COPY(regs[12]); COPY(regs[13]);
208 COPY(regs[14]); COPY(regs[15]);
209 COPY(gbr); COPY(mach);
210 COPY(macl); COPY(pr);
211 COPY(sr); COPY(pc);
212#undef COPY
213
214#ifdef CONFIG_SH_FPU
215 if (cpu_data->flags & CPU_HAS_FPU) {
216 int owned_fp;
217 struct task_struct *tsk = current;
218
219 regs->sr |= SR_FD; /* Release FPU */
220 clear_fpu(tsk, regs);
221 clear_used_math();
222 __get_user (owned_fp, &sc->sc_ownedfp);
223 if (owned_fp)
224 err |= restore_sigcontext_fpu(sc);
225 }
226#endif
227
228 regs->tra = -1; /* disable syscall checks */
229 err |= __get_user(*r0_p, &sc->sc_regs[0]);
230 return err;
231}
232
233asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
234 unsigned long r6, unsigned long r7,
235 struct pt_regs regs)
236{
237 struct sigframe __user *frame = (struct sigframe __user *)regs.regs[15];
238 sigset_t set;
239 int r0;
240
241 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
242 goto badframe;
243
244 if (__get_user(set.sig[0], &frame->sc.oldmask)
245 || (_NSIG_WORDS > 1
246 && __copy_from_user(&set.sig[1], &frame->extramask,
247 sizeof(frame->extramask))))
248 goto badframe;
249
250 sigdelsetmask(&set, ~_BLOCKABLE);
251
252 spin_lock_irq(&current->sighand->siglock);
253 current->blocked = set;
254 recalc_sigpending();
255 spin_unlock_irq(&current->sighand->siglock);
256
257 if (restore_sigcontext(&regs, &frame->sc, &r0))
258 goto badframe;
259 return r0;
260
261badframe:
262 force_sig(SIGSEGV, current);
263 return 0;
264}
265
266asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
267 unsigned long r6, unsigned long r7,
268 struct pt_regs regs)
269{
270 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs.regs[15];
271 sigset_t set;
272 stack_t st;
273 int r0;
274
275 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
276 goto badframe;
277
278 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
279 goto badframe;
280
281 sigdelsetmask(&set, ~_BLOCKABLE);
282 spin_lock_irq(&current->sighand->siglock);
283 current->blocked = set;
284 recalc_sigpending();
285 spin_unlock_irq(&current->sighand->siglock);
286
287 if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &r0))
288 goto badframe;
289
290 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
291 goto badframe;
292 /* It is more difficult to avoid calling this function than to
293 call it and ignore errors. */
294 do_sigaltstack(&st, NULL, regs.regs[15]);
295
296 return r0;
297
298badframe:
299 force_sig(SIGSEGV, current);
300 return 0;
301}
302
303/*
304 * Set up a signal frame.
305 */
306
307static int
308setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
309 unsigned long mask)
310{
311 int err = 0;
312
313#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
314 COPY(regs[0]); COPY(regs[1]);
315 COPY(regs[2]); COPY(regs[3]);
316 COPY(regs[4]); COPY(regs[5]);
317 COPY(regs[6]); COPY(regs[7]);
318 COPY(regs[8]); COPY(regs[9]);
319 COPY(regs[10]); COPY(regs[11]);
320 COPY(regs[12]); COPY(regs[13]);
321 COPY(regs[14]); COPY(regs[15]);
322 COPY(gbr); COPY(mach);
323 COPY(macl); COPY(pr);
324 COPY(sr); COPY(pc);
325#undef COPY
326
327#ifdef CONFIG_SH_FPU
328 err |= save_sigcontext_fpu(sc, regs);
329#endif
330
331 /* non-iBCS2 extensions.. */
332 err |= __put_user(mask, &sc->oldmask);
333
334 return err;
335}
336
337/*
338 * Determine which stack to use..
339 */
340static inline void __user *
341get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
342{
343 if (ka->sa.sa_flags & SA_ONSTACK) {
344 if (sas_ss_flags(sp) == 0)
345 sp = current->sas_ss_sp + current->sas_ss_size;
346 }
347
348 return (void __user *)((sp - frame_size) & -8ul);
349}
350
351static void setup_frame(int sig, struct k_sigaction *ka,
352 sigset_t *set, struct pt_regs *regs)
353{
354 struct sigframe __user *frame;
355 int err = 0;
356 int signal;
357
358 frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
359
360 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
361 goto give_sigsegv;
362
363 signal = current_thread_info()->exec_domain
364 && current_thread_info()->exec_domain->signal_invmap
365 && sig < 32
366 ? current_thread_info()->exec_domain->signal_invmap[sig]
367 : sig;
368
369 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
370
371 if (_NSIG_WORDS > 1) {
372 err |= __copy_to_user(frame->extramask, &set->sig[1],
373 sizeof(frame->extramask));
374 }
375
376 /* Set up to return from userspace. If provided, use a stub
377 already in userspace. */
378 if (ka->sa.sa_flags & SA_RESTORER) {
379 regs->pr = (unsigned long) ka->sa.sa_restorer;
380 } else {
381 /* Generate return code (system call to sigreturn) */
382 err |= __put_user(MOVW(7), &frame->retcode[0]);
383 err |= __put_user(TRAP16, &frame->retcode[1]);
384 err |= __put_user(OR_R0_R0, &frame->retcode[2]);
385 err |= __put_user(OR_R0_R0, &frame->retcode[3]);
386 err |= __put_user(OR_R0_R0, &frame->retcode[4]);
387 err |= __put_user(OR_R0_R0, &frame->retcode[5]);
388 err |= __put_user(OR_R0_R0, &frame->retcode[6]);
389 err |= __put_user((__NR_sigreturn), &frame->retcode[7]);
390 regs->pr = (unsigned long) frame->retcode;
391 }
392
393 if (err)
394 goto give_sigsegv;
395
396 /* Set up registers for signal handler */
397 regs->regs[15] = (unsigned long) frame;
398 regs->regs[4] = signal; /* Arg for signal handler */
399 regs->regs[5] = 0;
400 regs->regs[6] = (unsigned long) &frame->sc;
401 regs->pc = (unsigned long) ka->sa.sa_handler;
402
403 set_fs(USER_DS);
404
405#if DEBUG_SIG
406 printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
407 current->comm, current->pid, frame, regs->pc, regs->pr);
408#endif
409
410 flush_cache_sigtramp(regs->pr);
411 if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode))
412 flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES);
413 return;
414
415give_sigsegv:
416 force_sigsegv(sig, current);
417}
418
419static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
420 sigset_t *set, struct pt_regs *regs)
421{
422 struct rt_sigframe __user *frame;
423 int err = 0;
424 int signal;
425
426 frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
427
428 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
429 goto give_sigsegv;
430
431 signal = current_thread_info()->exec_domain
432 && current_thread_info()->exec_domain->signal_invmap
433 && sig < 32
434 ? current_thread_info()->exec_domain->signal_invmap[sig]
435 : sig;
436
437 err |= copy_siginfo_to_user(&frame->info, info);
438
439 /* Create the ucontext. */
440 err |= __put_user(0, &frame->uc.uc_flags);
441 err |= __put_user(0, &frame->uc.uc_link);
442 err |= __put_user((void *)current->sas_ss_sp,
443 &frame->uc.uc_stack.ss_sp);
444 err |= __put_user(sas_ss_flags(regs->regs[15]),
445 &frame->uc.uc_stack.ss_flags);
446 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
447 err |= setup_sigcontext(&frame->uc.uc_mcontext,
448 regs, set->sig[0]);
449 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
450
451 /* Set up to return from userspace. If provided, use a stub
452 already in userspace. */
453 if (ka->sa.sa_flags & SA_RESTORER) {
454 regs->pr = (unsigned long) ka->sa.sa_restorer;
455 } else {
456 /* Generate return code (system call to rt_sigreturn) */
457 err |= __put_user(MOVW(7), &frame->retcode[0]);
458 err |= __put_user(TRAP16, &frame->retcode[1]);
459 err |= __put_user(OR_R0_R0, &frame->retcode[2]);
460 err |= __put_user(OR_R0_R0, &frame->retcode[3]);
461 err |= __put_user(OR_R0_R0, &frame->retcode[4]);
462 err |= __put_user(OR_R0_R0, &frame->retcode[5]);
463 err |= __put_user(OR_R0_R0, &frame->retcode[6]);
464 err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
465 regs->pr = (unsigned long) frame->retcode;
466 }
467
468 if (err)
469 goto give_sigsegv;
470
471 /* Set up registers for signal handler */
472 regs->regs[15] = (unsigned long) frame;
473 regs->regs[4] = signal; /* Arg for signal handler */
474 regs->regs[5] = (unsigned long) &frame->info;
475 regs->regs[6] = (unsigned long) &frame->uc;
476 regs->pc = (unsigned long) ka->sa.sa_handler;
477
478 set_fs(USER_DS);
479
480#if DEBUG_SIG
481 printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
482 current->comm, current->pid, frame, regs->pc, regs->pr);
483#endif
484
485 flush_cache_sigtramp(regs->pr);
486 if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode))
487 flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES);
488 return;
489
490give_sigsegv:
491 force_sigsegv(sig, current);
492}
493
494/*
495 * OK, we're invoking a handler
496 */
497
498static void
499handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
500 sigset_t *oldset, struct pt_regs *regs)
501{
502 /* Are we from a system call? */
503 if (regs->tra >= 0) {
504 /* If so, check system call restarting.. */
505 switch (regs->regs[0]) {
506 case -ERESTARTNOHAND:
507 regs->regs[0] = -EINTR;
508 break;
509
510 case -ERESTARTSYS:
511 if (!(ka->sa.sa_flags & SA_RESTART)) {
512 regs->regs[0] = -EINTR;
513 break;
514 }
515 /* fallthrough */
516 case -ERESTARTNOINTR:
517 regs->pc -= 2;
518 }
519 } else {
520 /* gUSA handling */
521#ifdef CONFIG_PREEMPT
522 unsigned long flags;
523
524 local_irq_save(flags);
525#endif
526 if (regs->regs[15] >= 0xc0000000) {
527 int offset = (int)regs->regs[15];
528
529 /* Reset stack pointer: clear critical region mark */
530 regs->regs[15] = regs->regs[1];
531 if (regs->pc < regs->regs[0])
532 /* Go to rewind point #1 */
533 regs->pc = regs->regs[0] + offset - 2;
534 }
535#ifdef CONFIG_PREEMPT
536 local_irq_restore(flags);
537#endif
538 }
539
540 /* Set up the stack frame */
541 if (ka->sa.sa_flags & SA_SIGINFO)
542 setup_rt_frame(sig, ka, info, oldset, regs);
543 else
544 setup_frame(sig, ka, oldset, regs);
545
546 if (ka->sa.sa_flags & SA_ONESHOT)
547 ka->sa.sa_handler = SIG_DFL;
548
549 if (!(ka->sa.sa_flags & SA_NODEFER)) {
550 spin_lock_irq(&current->sighand->siglock);
551 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
552 sigaddset(&current->blocked,sig);
553 recalc_sigpending();
554 spin_unlock_irq(&current->sighand->siglock);
555 }
556}
557
558/*
559 * Note that 'init' is a special process: it doesn't get signals it doesn't
560 * want to handle. Thus you cannot kill init even with a SIGKILL even by
561 * mistake.
562 *
563 * Note that we go through the signals twice: once to check the signals that
564 * the kernel can handle, and then we build all the user-level signal handling
565 * stack-frames in one go after that.
566 */
567int do_signal(struct pt_regs *regs, sigset_t *oldset)
568{
569 siginfo_t info;
570 int signr;
571 struct k_sigaction ka;
572
573 /*
574 * We want the common case to go fast, which
575 * is why we may in certain cases get here from
576 * kernel mode. Just return without doing anything
577 * if so.
578 */
579 if (!user_mode(regs))
580 return 1;
581
582 if (try_to_freeze(0))
583 goto no_signal;
584
585 if (!oldset)
586 oldset = &current->blocked;
587
588 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
589 if (signr > 0) {
590 /* Whee! Actually deliver the signal. */
591 handle_signal(signr, &ka, &info, oldset, regs);
592 return 1;
593 }
594
595 no_signal:
596 /* Did we come from a system call? */
597 if (regs->tra >= 0) {
598 /* Restart the system call - no handlers present */
599 if (regs->regs[0] == -ERESTARTNOHAND ||
600 regs->regs[0] == -ERESTARTSYS ||
601 regs->regs[0] == -ERESTARTNOINTR ||
602 regs->regs[0] == -ERESTART_RESTARTBLOCK) {
603 regs->pc -= 2;
604 }
605 }
606 return 0;
607}
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
new file mode 100644
index 000000000000..56a39d69e080
--- /dev/null
+++ b/arch/sh/kernel/smp.c
@@ -0,0 +1,199 @@
1/*
2 * arch/sh/kernel/smp.c
3 *
4 * SMP support for the SuperH processors.
5 *
6 * Copyright (C) 2002, 2003 Paul Mundt
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13#include <linux/config.h>
14#include <linux/cache.h>
15#include <linux/cpumask.h>
16#include <linux/delay.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19#include <linux/spinlock.h>
20#include <linux/threads.h>
21#include <linux/module.h>
22#include <linux/time.h>
23#include <linux/timex.h>
24#include <linux/sched.h>
25
26#include <asm/atomic.h>
27#include <asm/processor.h>
28#include <asm/system.h>
29#include <asm/mmu_context.h>
30#include <asm/smp.h>
31
32/*
33 * This was written with the Sega Saturn (SMP SH-2 7604) in mind,
34 * but is designed to be usable regardless if there's an MMU
35 * present or not.
36 */
37struct sh_cpuinfo cpu_data[NR_CPUS];
38
39extern void per_cpu_trap_init(void);
40
41cpumask_t cpu_possible_map;
42cpumask_t cpu_online_map;
43static atomic_t cpus_booted = ATOMIC_INIT(0);
44
45/* These are defined by the board-specific code. */
46
47/*
48 * Cause the function described by call_data to be executed on the passed
49 * cpu. When the function has finished, increment the finished field of
50 * call_data.
51 */
52void __smp_send_ipi(unsigned int cpu, unsigned int action);
53
54/*
55 * Find the number of available processors
56 */
57unsigned int __smp_probe_cpus(void);
58
59/*
60 * Start a particular processor
61 */
62void __smp_slave_init(unsigned int cpu);
63
64/*
65 * Run specified function on a particular processor.
66 */
67void __smp_call_function(unsigned int cpu);
68
69static inline void __init smp_store_cpu_info(unsigned int cpu)
70{
71 cpu_data[cpu].loops_per_jiffy = loops_per_jiffy;
72}
73
74void __init smp_prepare_cpus(unsigned int max_cpus)
75{
76 unsigned int cpu = smp_processor_id();
77 int i;
78
79 atomic_set(&cpus_booted, 1);
80 smp_store_cpu_info(cpu);
81
82 for (i = 0; i < __smp_probe_cpus(); i++)
83 cpu_set(i, cpu_possible_map);
84}
85
86void __devinit smp_prepare_boot_cpu(void)
87{
88 unsigned int cpu = smp_processor_id();
89
90 cpu_set(cpu, cpu_online_map);
91 cpu_set(cpu, cpu_possible_map);
92}
93
94int __cpu_up(unsigned int cpu)
95{
96 struct task_struct *tsk;
97
98 tsk = fork_idle(cpu);
99
100 if (IS_ERR(tsk))
101 panic("Failed forking idle task for cpu %d\n", cpu);
102
103 tsk->thread_info->cpu = cpu;
104
105 cpu_set(cpu, cpu_online_map);
106
107 return 0;
108}
109
110int start_secondary(void *unused)
111{
112 unsigned int cpu = smp_processor_id();
113
114 atomic_inc(&init_mm.mm_count);
115 current->active_mm = &init_mm;
116
117 smp_store_cpu_info(cpu);
118
119 __smp_slave_init(cpu);
120 per_cpu_trap_init();
121
122 atomic_inc(&cpus_booted);
123
124 cpu_idle();
125 return 0;
126}
127
128void __init smp_cpus_done(unsigned int max_cpus)
129{
130 smp_mb();
131}
132
133void smp_send_reschedule(int cpu)
134{
135 __smp_send_ipi(cpu, SMP_MSG_RESCHEDULE);
136}
137
138static void stop_this_cpu(void *unused)
139{
140 cpu_clear(smp_processor_id(), cpu_online_map);
141 local_irq_disable();
142
143 for (;;)
144 cpu_relax();
145}
146
147void smp_send_stop(void)
148{
149 smp_call_function(stop_this_cpu, 0, 1, 0);
150}
151
152
153struct smp_fn_call_struct smp_fn_call = {
154 .lock = SPIN_LOCK_UNLOCKED,
155 .finished = ATOMIC_INIT(0),
156};
157
158/*
159 * The caller of this wants the passed function to run on every cpu. If wait
160 * is set, wait until all cpus have finished the function before returning.
161 * The lock is here to protect the call structure.
162 * You must not call this function with disabled interrupts or from a
163 * hardware interrupt handler or from a bottom half handler.
164 */
165int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
166{
167 unsigned int nr_cpus = atomic_read(&cpus_booted);
168 int i;
169
170 if (nr_cpus < 2)
171 return 0;
172
173 /* Can deadlock when called with interrupts disabled */
174 WARN_ON(irqs_disabled());
175
176 spin_lock(&smp_fn_call.lock);
177
178 atomic_set(&smp_fn_call.finished, 0);
179 smp_fn_call.fn = func;
180 smp_fn_call.data = info;
181
182 for (i = 0; i < nr_cpus; i++)
183 if (i != smp_processor_id())
184 __smp_call_function(i);
185
186 if (wait)
187 while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1));
188
189 spin_unlock(&smp_fn_call.lock);
190
191 return 0;
192}
193
194/* Not really SMP stuff ... */
195int setup_profiling_timer(unsigned int multiplier)
196{
197 return 0;
198}
199
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
new file mode 100644
index 000000000000..df5ac294c379
--- /dev/null
+++ b/arch/sh/kernel/sys_sh.c
@@ -0,0 +1,289 @@
1/*
2 * linux/arch/sh/kernel/sys_sh.c
3 *
4 * This file contains various random system calls that
5 * have a non-standard calling sequence on the Linux/SuperH
6 * platform.
7 *
8 * Taken from i386 version.
9 */
10
11#include <linux/errno.h>
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/sem.h>
17#include <linux/msg.h>
18#include <linux/shm.h>
19#include <linux/stat.h>
20#include <linux/syscalls.h>
21#include <linux/mman.h>
22#include <linux/file.h>
23#include <linux/utsname.h>
24
25#include <asm/uaccess.h>
26#include <asm/ipc.h>
27
28/*
29 * sys_pipe() is the normal C calling standard for creating
30 * a pipe. It's not the way Unix traditionally does this, though.
31 */
32asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
33 unsigned long r6, unsigned long r7,
34 struct pt_regs regs)
35{
36 int fd[2];
37 int error;
38
39 error = do_pipe(fd);
40 if (!error) {
41 regs.regs[1] = fd[1];
42 return fd[0];
43 }
44 return error;
45}
46
47#if defined(HAVE_ARCH_UNMAPPED_AREA)
48/*
49 * To avoid cache alias, we map the shard page with same color.
50 */
51#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1))
52
53unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
54 unsigned long len, unsigned long pgoff, unsigned long flags)
55{
56 struct mm_struct *mm = current->mm;
57 struct vm_area_struct *vma;
58 unsigned long start_addr;
59
60 if (flags & MAP_FIXED) {
61 /* We do not accept a shared mapping if it would violate
62 * cache aliasing constraints.
63 */
64 if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
65 return -EINVAL;
66 return addr;
67 }
68
69 if (len > TASK_SIZE)
70 return -ENOMEM;
71
72 if (addr) {
73 if (flags & MAP_PRIVATE)
74 addr = PAGE_ALIGN(addr);
75 else
76 addr = COLOUR_ALIGN(addr);
77 vma = find_vma(mm, addr);
78 if (TASK_SIZE - len >= addr &&
79 (!vma || addr + len <= vma->vm_start))
80 return addr;
81 }
82 if (flags & MAP_PRIVATE)
83 addr = PAGE_ALIGN(mm->free_area_cache);
84 else
85 addr = COLOUR_ALIGN(mm->free_area_cache);
86 start_addr = addr;
87
88full_search:
89 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
90 /* At this point: (!vma || addr < vma->vm_end). */
91 if (TASK_SIZE - len < addr) {
92 /*
93 * Start a new search - just in case we missed
94 * some holes.
95 */
96 if (start_addr != TASK_UNMAPPED_BASE) {
97 start_addr = addr = TASK_UNMAPPED_BASE;
98 goto full_search;
99 }
100 return -ENOMEM;
101 }
102 if (!vma || addr + len <= vma->vm_start) {
103 /*
104 * Remember the place where we stopped the search:
105 */
106 mm->free_area_cache = addr + len;
107 return addr;
108 }
109 addr = vma->vm_end;
110 if (!(flags & MAP_PRIVATE))
111 addr = COLOUR_ALIGN(addr);
112 }
113}
114#endif
115
116static inline long
117do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
118 unsigned long flags, int fd, unsigned long pgoff)
119{
120 int error = -EBADF;
121 struct file *file = NULL;
122
123 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
124 if (!(flags & MAP_ANONYMOUS)) {
125 file = fget(fd);
126 if (!file)
127 goto out;
128 }
129
130 down_write(&current->mm->mmap_sem);
131 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
132 up_write(&current->mm->mmap_sem);
133
134 if (file)
135 fput(file);
136out:
137 return error;
138}
139
140asmlinkage int old_mmap(unsigned long addr, unsigned long len,
141 unsigned long prot, unsigned long flags,
142 int fd, unsigned long off)
143{
144 if (off & ~PAGE_MASK)
145 return -EINVAL;
146 return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
147}
148
149asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
150 unsigned long prot, unsigned long flags,
151 unsigned long fd, unsigned long pgoff)
152{
153 return do_mmap2(addr, len, prot, flags, fd, pgoff);
154}
155
156/*
157 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
158 *
159 * This is really horribly ugly.
160 */
161asmlinkage int sys_ipc(uint call, int first, int second,
162 int third, void __user *ptr, long fifth)
163{
164 int version, ret;
165
166 version = call >> 16; /* hack for backward compatibility */
167 call &= 0xffff;
168
169 if (call <= SEMCTL)
170 switch (call) {
171 case SEMOP:
172 return sys_semtimedop(first, (struct sembuf __user *)ptr,
173 second, NULL);
174 case SEMTIMEDOP:
175 return sys_semtimedop(first, (struct sembuf __user *)ptr,
176 second,
177 (const struct timespec __user *)fifth);
178 case SEMGET:
179 return sys_semget (first, second, third);
180 case SEMCTL: {
181 union semun fourth;
182 if (!ptr)
183 return -EINVAL;
184 if (get_user(fourth.__pad, (void * __user *) ptr))
185 return -EFAULT;
186 return sys_semctl (first, second, third, fourth);
187 }
188 default:
189 return -EINVAL;
190 }
191
192 if (call <= MSGCTL)
193 switch (call) {
194 case MSGSND:
195 return sys_msgsnd (first, (struct msgbuf __user *) ptr,
196 second, third);
197 case MSGRCV:
198 switch (version) {
199 case 0: {
200 struct ipc_kludge tmp;
201 if (!ptr)
202 return -EINVAL;
203
204 if (copy_from_user(&tmp,
205 (struct ipc_kludge __user *) ptr,
206 sizeof (tmp)))
207 return -EFAULT;
208 return sys_msgrcv (first, tmp.msgp, second,
209 tmp.msgtyp, third);
210 }
211 default:
212 return sys_msgrcv (first,
213 (struct msgbuf __user *) ptr,
214 second, fifth, third);
215 }
216 case MSGGET:
217 return sys_msgget ((key_t) first, second);
218 case MSGCTL:
219 return sys_msgctl (first, second,
220 (struct msqid_ds __user *) ptr);
221 default:
222 return -EINVAL;
223 }
224 if (call <= SHMCTL)
225 switch (call) {
226 case SHMAT:
227 switch (version) {
228 default: {
229 ulong raddr;
230 ret = do_shmat (first, (char __user *) ptr,
231 second, &raddr);
232 if (ret)
233 return ret;
234 return put_user (raddr, (ulong __user *) third);
235 }
236 case 1: /* iBCS2 emulator entry point */
237 if (!segment_eq(get_fs(), get_ds()))
238 return -EINVAL;
239 return do_shmat (first, (char __user *) ptr,
240 second, (ulong *) third);
241 }
242 case SHMDT:
243 return sys_shmdt ((char __user *)ptr);
244 case SHMGET:
245 return sys_shmget (first, second, third);
246 case SHMCTL:
247 return sys_shmctl (first, second,
248 (struct shmid_ds __user *) ptr);
249 default:
250 return -EINVAL;
251 }
252
253 return -EINVAL;
254}
255
256asmlinkage int sys_uname(struct old_utsname * name)
257{
258 int err;
259 if (!name)
260 return -EFAULT;
261 down_read(&uts_sem);
262 err=copy_to_user(name, &system_utsname, sizeof (*name));
263 up_read(&uts_sem);
264 return err?-EFAULT:0;
265}
266
267asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char * buf,
268 size_t count, long dummy, loff_t pos)
269{
270 return sys_pread64(fd, buf, count, pos);
271}
272
273asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char * buf,
274 size_t count, long dummy, loff_t pos)
275{
276 return sys_pwrite64(fd, buf, count, pos);
277}
278
279asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
280 u32 len0, u32 len1, int advice)
281{
282#ifdef __LITTLE_ENDIAN__
283 return sys_fadvise64_64(fd, (u64)offset1 << 32 | offset0,
284 (u64)len1 << 32 | len0, advice);
285#else
286 return sys_fadvise64_64(fd, (u64)offset0 << 32 | offset1,
287 (u64)len0 << 32 | len1, advice);
288#endif
289}
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
new file mode 100644
index 000000000000..df7a9b9d4cbf
--- /dev/null
+++ b/arch/sh/kernel/time.c
@@ -0,0 +1,657 @@
1/*
2 * arch/sh/kernel/time.c
3 *
4 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
6 * Copyright (C) 2002, 2003, 2004 Paul Mundt
7 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
8 *
9 * Some code taken from i386 version.
10 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
11 */
12
13#include <linux/config.h>
14#include <linux/errno.h>
15#include <linux/module.h>
16#include <linux/sched.h>
17#include <linux/kernel.h>
18#include <linux/param.h>
19#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/interrupt.h>
22#include <linux/time.h>
23#include <linux/delay.h>
24#include <linux/init.h>
25#include <linux/smp.h>
26#include <linux/profile.h>
27
28#include <asm/processor.h>
29#include <asm/uaccess.h>
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/delay.h>
33#include <asm/machvec.h>
34#include <asm/rtc.h>
35#include <asm/freq.h>
36#include <asm/cpu/timer.h>
37#ifdef CONFIG_SH_KGDB
38#include <asm/kgdb.h>
39#endif
40
41#include <linux/timex.h>
42#include <linux/irq.h>
43
44#define TMU_TOCR_INIT 0x00
45#define TMU0_TCR_INIT 0x0020
46#define TMU_TSTR_INIT 1
47
48#define TMU0_TCR_CALIB 0x0000
49
50#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
51#define CLOCKGEN_MEMCLKCR 0xbb040038
52#define MEMCLKCR_RATIO_MASK 0x7
53#endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */
54
55extern unsigned long wall_jiffies;
56#define TICK_SIZE (tick_nsec / 1000)
57DEFINE_SPINLOCK(tmu0_lock);
58
59u64 jiffies_64 = INITIAL_JIFFIES;
60
61EXPORT_SYMBOL(jiffies_64);
62
63/* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want
64 * these routines anywhere... */
65#ifdef CONFIG_SH_RTC
66void (*rtc_get_time)(struct timespec *) = sh_rtc_gettimeofday;
67int (*rtc_set_time)(const time_t) = sh_rtc_settimeofday;
68#else
69void (*rtc_get_time)(struct timespec *);
70int (*rtc_set_time)(const time_t);
71#endif
72
73#if defined(CONFIG_CPU_SUBTYPE_SH7300)
74static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 };
75#endif
76#if defined(CONFIG_CPU_SH3)
77static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
78static int stc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 };
79#define bfc_divisors stc_multipliers
80#define bfc_values stc_values
81static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 };
82static int ifc_values[] = { 0, 1, 4, 2, 0, 0, 0, 0 };
83static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
84static int pfc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 };
85#elif defined(CONFIG_CPU_SH4)
86#if defined(CONFIG_CPU_SUBTYPE_SH73180)
87static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 };
88static int ifc_values[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
89#define bfc_divisors ifc_divisors /* Same */
90#define bfc_values ifc_values
91#define pfc_divisors ifc_divisors /* Same */
92#define pfc_values ifc_values
93#else
94static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 };
95static int ifc_values[] = { 0, 1, 2, 3, 0, 4, 0, 5 };
96#define bfc_divisors ifc_divisors /* Same */
97#define bfc_values ifc_values
98static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 };
99static int pfc_values[] = { 0, 0, 1, 2, 0, 3, 0, 4 };
100#endif
101#else
102#error "Unknown ifc/bfc/pfc/stc values for this processor"
103#endif
104
105/*
106 * Scheduler clock - returns current time in nanosec units.
107 */
108unsigned long long sched_clock(void)
109{
110 return (unsigned long long)jiffies * (1000000000 / HZ);
111}
112
113static unsigned long do_gettimeoffset(void)
114{
115 int count;
116 unsigned long flags;
117
118 static int count_p = 0x7fffffff; /* for the first call after boot */
119 static unsigned long jiffies_p = 0;
120
121 /*
122 * cache volatile jiffies temporarily; we have IRQs turned off.
123 */
124 unsigned long jiffies_t;
125
126 spin_lock_irqsave(&tmu0_lock, flags);
127 /* timer count may underflow right here */
128 count = ctrl_inl(TMU0_TCNT); /* read the latched count */
129
130 jiffies_t = jiffies;
131
132 /*
133 * avoiding timer inconsistencies (they are rare, but they happen)...
134 * there is one kind of problem that must be avoided here:
135 * 1. the timer counter underflows
136 */
137
138 if( jiffies_t == jiffies_p ) {
139 if( count > count_p ) {
140 /* the nutcase */
141
142 if(ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */
143 /*
144 * We cannot detect lost timer interrupts ...
145 * well, that's why we call them lost, don't we? :)
146 * [hmm, on the Pentium and Alpha we can ... sort of]
147 */
148 count -= LATCH;
149 } else {
150 printk("do_slow_gettimeoffset(): hardware timer problem?\n");
151 }
152 }
153 } else
154 jiffies_p = jiffies_t;
155
156 count_p = count;
157 spin_unlock_irqrestore(&tmu0_lock, flags);
158
159 count = ((LATCH-1) - count) * TICK_SIZE;
160 count = (count + LATCH/2) / LATCH;
161
162 return count;
163}
164
165void do_gettimeofday(struct timeval *tv)
166{
167 unsigned long seq;
168 unsigned long usec, sec;
169 unsigned long lost;
170
171 do {
172 seq = read_seqbegin(&xtime_lock);
173 usec = do_gettimeoffset();
174
175 lost = jiffies - wall_jiffies;
176 if (lost)
177 usec += lost * (1000000 / HZ);
178
179 sec = xtime.tv_sec;
180 usec += xtime.tv_nsec / 1000;
181 } while (read_seqretry(&xtime_lock, seq));
182
183 while (usec >= 1000000) {
184 usec -= 1000000;
185 sec++;
186 }
187
188 tv->tv_sec = sec;
189 tv->tv_usec = usec;
190}
191
192EXPORT_SYMBOL(do_gettimeofday);
193
194int do_settimeofday(struct timespec *tv)
195{
196 time_t wtm_sec, sec = tv->tv_sec;
197 long wtm_nsec, nsec = tv->tv_nsec;
198
199 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
200 return -EINVAL;
201
202 write_seqlock_irq(&xtime_lock);
203 /*
204 * This is revolting. We need to set "xtime" correctly. However, the
205 * value in this location is the value at the most recent update of
206 * wall time. Discover what correction gettimeofday() would have
207 * made, and then undo it!
208 */
209 nsec -= 1000 * (do_gettimeoffset() +
210 (jiffies - wall_jiffies) * (1000000 / HZ));
211
212 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
213 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
214
215 set_normalized_timespec(&xtime, sec, nsec);
216 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
217
218 time_adjust = 0; /* stop active adjtime() */
219 time_status |= STA_UNSYNC;
220 time_maxerror = NTP_PHASE_LIMIT;
221 time_esterror = NTP_PHASE_LIMIT;
222 write_sequnlock_irq(&xtime_lock);
223 clock_was_set();
224
225 return 0;
226}
227
228EXPORT_SYMBOL(do_settimeofday);
229
230/* last time the RTC clock got updated */
231static long last_rtc_update;
232
233/*
234 * timer_interrupt() needs to keep up the real-time clock,
235 * as well as call the "do_timer()" routine every clocktick
236 */
237static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
238{
239 do_timer(regs);
240#ifndef CONFIG_SMP
241 update_process_times(user_mode(regs));
242#endif
243 profile_tick(CPU_PROFILING, regs);
244
245#ifdef CONFIG_HEARTBEAT
246 if (sh_mv.mv_heartbeat != NULL)
247 sh_mv.mv_heartbeat();
248#endif
249
250 /*
251 * If we have an externally synchronized Linux clock, then update
252 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
253 * called as close as possible to 500 ms before the new second starts.
254 */
255 if ((time_status & STA_UNSYNC) == 0 &&
256 xtime.tv_sec > last_rtc_update + 660 &&
257 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
258 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
259 if (rtc_set_time(xtime.tv_sec) == 0)
260 last_rtc_update = xtime.tv_sec;
261 else
262 last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
263 }
264}
265
266/*
267 * This is the same as the above, except we _also_ save the current
268 * Time Stamp Counter value at the time of the timer interrupt, so that
269 * we later on can estimate the time of day more exactly.
270 */
271static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
272{
273 unsigned long timer_status;
274
275 /* Clear UNF bit */
276 timer_status = ctrl_inw(TMU0_TCR);
277 timer_status &= ~0x100;
278 ctrl_outw(timer_status, TMU0_TCR);
279
280 /*
281 * Here we are in the timer irq handler. We just have irqs locally
282 * disabled but we don't know if the timer_bh is running on the other
283 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
284 * the irq version of write_lock because as just said we have irq
285 * locally disabled. -arca
286 */
287 write_seqlock(&xtime_lock);
288 do_timer_interrupt(irq, NULL, regs);
289 write_sequnlock(&xtime_lock);
290
291 return IRQ_HANDLED;
292}
293
294/*
295 * Hah! We'll see if this works (switching from usecs to nsecs).
296 */
297static unsigned int __init get_timer_frequency(void)
298{
299 u32 freq;
300 struct timespec ts1, ts2;
301 unsigned long diff_nsec;
302 unsigned long factor;
303
304 /* Setup the timer: We don't want to generate interrupts, just
305 * have it count down at its natural rate.
306 */
307 ctrl_outb(0, TMU_TSTR);
308#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
309 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
310#endif
311 ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR);
312 ctrl_outl(0xffffffff, TMU0_TCOR);
313 ctrl_outl(0xffffffff, TMU0_TCNT);
314
315 rtc_get_time(&ts2);
316
317 do {
318 rtc_get_time(&ts1);
319 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
320
321 /* actually start the timer */
322 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
323
324 do {
325 rtc_get_time(&ts2);
326 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
327
328 freq = 0xffffffff - ctrl_inl(TMU0_TCNT);
329 if (ts2.tv_nsec < ts1.tv_nsec) {
330 ts2.tv_nsec += 1000000000;
331 ts2.tv_sec--;
332 }
333
334 diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec);
335
336 /* this should work well if the RTC has a precision of n Hz, where
337 * n is an integer. I don't think we have to worry about the other
338 * cases. */
339 factor = (1000000000 + diff_nsec/2) / diff_nsec;
340
341 if (factor * diff_nsec > 1100000000 ||
342 factor * diff_nsec < 900000000)
343 panic("weird RTC (diff_nsec %ld)", diff_nsec);
344
345 return freq * factor;
346}
347
348void (*board_time_init)(void);
349void (*board_timer_setup)(struct irqaction *irq);
350
351static unsigned int sh_pclk_freq __initdata = CONFIG_SH_PCLK_FREQ;
352
353static int __init sh_pclk_setup(char *str)
354{
355 unsigned int freq;
356
357 if (get_option(&str, &freq))
358 sh_pclk_freq = freq;
359
360 return 1;
361}
362__setup("sh_pclk=", sh_pclk_setup);
363
364static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL};
365
366void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsigned int *pfc)
367{
368 unsigned int frqcr = ctrl_inw(FRQCR);
369
370#if defined(CONFIG_CPU_SH3)
371#if defined(CONFIG_CPU_SUBTYPE_SH7300)
372 *ifc = md_table[((frqcr & 0x0070) >> 4)];
373 *bfc = md_table[((frqcr & 0x0700) >> 8)];
374 *pfc = md_table[frqcr & 0x0007];
375#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
376 *bfc = stc_multipliers[(frqcr & 0x0300) >> 8];
377 *ifc = ifc_divisors[(frqcr & 0x0030) >> 4];
378 *pfc = pfc_divisors[frqcr & 0x0003];
379#else
380 unsigned int tmp;
381
382 tmp = (frqcr & 0x8000) >> 13;
383 tmp |= (frqcr & 0x0030) >> 4;
384 *bfc = stc_multipliers[tmp];
385 tmp = (frqcr & 0x4000) >> 12;
386 tmp |= (frqcr & 0x000c) >> 2;
387 *ifc = ifc_divisors[tmp];
388 tmp = (frqcr & 0x2000) >> 11;
389 tmp |= frqcr & 0x0003;
390 *pfc = pfc_divisors[tmp];
391#endif
392#elif defined(CONFIG_CPU_SH4)
393#if defined(CONFIG_CPU_SUBTYPE_SH73180)
394 *ifc = ifc_divisors[(frqcr>> 20) & 0x0007];
395 *bfc = bfc_divisors[(frqcr>> 12) & 0x0007];
396 *pfc = pfc_divisors[frqcr & 0x0007];
397#else
398 *ifc = ifc_divisors[(frqcr >> 6) & 0x0007];
399 *bfc = bfc_divisors[(frqcr >> 3) & 0x0007];
400 *pfc = pfc_divisors[frqcr & 0x0007];
401#endif
402#endif
403}
404
405/*
406 * This bit of ugliness builds up accessor routines to get at both
407 * the divisors and the physical values.
408 */
409#define _FREQ_TABLE(x) \
410 unsigned int get_##x##_divisor(unsigned int value) \
411 { return x##_divisors[value]; } \
412 \
413 unsigned int get_##x##_value(unsigned int divisor) \
414 { return x##_values[(divisor - 1)]; }
415
416_FREQ_TABLE(ifc);
417_FREQ_TABLE(bfc);
418_FREQ_TABLE(pfc);
419
420#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
421
422/*
423 * The ST40 divisors are totally different so we set the cpu data
424 * clocks using a different algorithm
425 *
426 * I've just plugged this from the 2.4 code
427 * - Alex Bennee <kernel-hacker@bennee.com>
428 */
429#define CCN_PVR_CHIP_SHIFT 24
430#define CCN_PVR_CHIP_MASK 0xff
431#define CCN_PVR_CHIP_ST40STB1 0x4
432
433
434struct frqcr_data {
435 unsigned short frqcr;
436
437 struct {
438 unsigned char multiplier;
439 unsigned char divisor;
440 } factor[3];
441};
442
443static struct frqcr_data st40_frqcr_table[] = {
444 { 0x000, {{1,1}, {1,1}, {1,2}}},
445 { 0x002, {{1,1}, {1,1}, {1,4}}},
446 { 0x004, {{1,1}, {1,1}, {1,8}}},
447 { 0x008, {{1,1}, {1,2}, {1,2}}},
448 { 0x00A, {{1,1}, {1,2}, {1,4}}},
449 { 0x00C, {{1,1}, {1,2}, {1,8}}},
450 { 0x011, {{1,1}, {2,3}, {1,6}}},
451 { 0x013, {{1,1}, {2,3}, {1,3}}},
452 { 0x01A, {{1,1}, {1,2}, {1,4}}},
453 { 0x01C, {{1,1}, {1,2}, {1,8}}},
454 { 0x023, {{1,1}, {2,3}, {1,3}}},
455 { 0x02C, {{1,1}, {1,2}, {1,8}}},
456 { 0x048, {{1,2}, {1,2}, {1,4}}},
457 { 0x04A, {{1,2}, {1,2}, {1,6}}},
458 { 0x04C, {{1,2}, {1,2}, {1,8}}},
459 { 0x05A, {{1,2}, {1,3}, {1,6}}},
460 { 0x05C, {{1,2}, {1,3}, {1,6}}},
461 { 0x063, {{1,2}, {1,4}, {1,4}}},
462 { 0x06C, {{1,2}, {1,4}, {1,8}}},
463 { 0x091, {{1,3}, {1,3}, {1,6}}},
464 { 0x093, {{1,3}, {1,3}, {1,6}}},
465 { 0x0A3, {{1,3}, {1,6}, {1,6}}},
466 { 0x0DA, {{1,4}, {1,4}, {1,8}}},
467 { 0x0DC, {{1,4}, {1,4}, {1,8}}},
468 { 0x0EC, {{1,4}, {1,8}, {1,8}}},
469 { 0x123, {{1,4}, {1,4}, {1,8}}},
470 { 0x16C, {{1,4}, {1,8}, {1,8}}},
471};
472
473struct memclk_data {
474 unsigned char multiplier;
475 unsigned char divisor;
476};
477
478static struct memclk_data st40_memclk_table[8] = {
479 {1,1}, // 000
480 {1,2}, // 001
481 {1,3}, // 010
482 {2,3}, // 011
483 {1,4}, // 100
484 {1,6}, // 101
485 {1,8}, // 110
486 {1,8} // 111
487};
488
489static void st40_specific_time_init(unsigned int module_clock, unsigned short frqcr)
490{
491 unsigned int cpu_clock, master_clock, bus_clock, memory_clock;
492 struct frqcr_data *d;
493 int a;
494 unsigned long memclkcr;
495 struct memclk_data *e;
496
497 for (a = 0; a < ARRAY_SIZE(st40_frqcr_table); a++) {
498 d = &st40_frqcr_table[a];
499
500 if (d->frqcr == (frqcr & 0x1ff))
501 break;
502 }
503
504 if (a == ARRAY_SIZE(st40_frqcr_table)) {
505 d = st40_frqcr_table;
506
507 printk("ERROR: Unrecognised FRQCR value (0x%x), "
508 "using default multipliers\n", frqcr);
509 }
510
511 memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
512 e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
513
514 printk(KERN_INFO "Clock multipliers: CPU: %d/%d Bus: %d/%d "
515 "Mem: %d/%d Periph: %d/%d\n",
516 d->factor[0].multiplier, d->factor[0].divisor,
517 d->factor[1].multiplier, d->factor[1].divisor,
518 e->multiplier, e->divisor,
519 d->factor[2].multiplier, d->factor[2].divisor);
520
521 master_clock = module_clock * d->factor[2].divisor
522 / d->factor[2].multiplier;
523 bus_clock = master_clock * d->factor[1].multiplier
524 / d->factor[1].divisor;
525 memory_clock = master_clock * e->multiplier
526 / e->divisor;
527 cpu_clock = master_clock * d->factor[0].multiplier
528 / d->factor[0].divisor;
529
530 current_cpu_data.cpu_clock = cpu_clock;
531 current_cpu_data.master_clock = master_clock;
532 current_cpu_data.bus_clock = bus_clock;
533 current_cpu_data.memory_clock = memory_clock;
534 current_cpu_data.module_clock = module_clock;
535}
536#endif
537
538void __init time_init(void)
539{
540 unsigned int timer_freq = 0;
541 unsigned int ifc, pfc, bfc;
542 unsigned long interval;
543#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
544 unsigned long pvr;
545 unsigned short frqcr;
546#endif
547
548 if (board_time_init)
549 board_time_init();
550
551 /*
552 * If we don't have an RTC (such as with the SH7300), don't attempt to
553 * probe the timer frequency. Rely on an either hardcoded peripheral
554 * clock value, or on the sh_pclk command line option. Note that we
555 * still need to have CONFIG_SH_PCLK_FREQ set in order for things like
556 * CLOCK_TICK_RATE to be sane.
557 */
558 current_cpu_data.module_clock = sh_pclk_freq;
559
560#ifdef CONFIG_SH_PCLK_CALC
561 /* XXX: Switch this over to a more generic test. */
562 {
563 unsigned int freq;
564
565 /*
566 * If we've specified a peripheral clock frequency, and we have
567 * an RTC, compare it against the autodetected value. Complain
568 * if there's a mismatch.
569 */
570 timer_freq = get_timer_frequency();
571 freq = timer_freq * 4;
572
573 if (sh_pclk_freq && (sh_pclk_freq/100*99 > freq || sh_pclk_freq/100*101 < freq)) {
574 printk(KERN_NOTICE "Calculated peripheral clock value "
575 "%d differs from sh_pclk value %d, fixing..\n",
576 freq, sh_pclk_freq);
577 current_cpu_data.module_clock = freq;
578 }
579 }
580#endif
581
582#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
583 /* XXX: Update ST40 code to use board_time_init() */
584 pvr = ctrl_inl(CCN_PVR);
585 frqcr = ctrl_inw(FRQCR);
586 printk("time.c ST40 Probe: PVR %08lx, FRQCR %04hx\n", pvr, frqcr);
587
588 if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1)
589 st40_specific_time_init(current_cpu_data.module_clock, frqcr);
590 else
591#endif
592 get_current_frequency_divisors(&ifc, &bfc, &pfc);
593
594 if (rtc_get_time) {
595 rtc_get_time(&xtime);
596 } else {
597 xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0);
598 xtime.tv_nsec = 0;
599 }
600
601 set_normalized_timespec(&wall_to_monotonic,
602 -xtime.tv_sec, -xtime.tv_nsec);
603
604 if (board_timer_setup) {
605 board_timer_setup(&irq0);
606 } else {
607 setup_irq(TIMER_IRQ, &irq0);
608 }
609
610 /*
611 * for ST40 chips the current_cpu_data should already be set
612 * so not having valid pfc/bfc/ifc shouldn't be a problem
613 */
614 if (!current_cpu_data.master_clock)
615 current_cpu_data.master_clock = current_cpu_data.module_clock * pfc;
616 if (!current_cpu_data.bus_clock)
617 current_cpu_data.bus_clock = current_cpu_data.master_clock / bfc;
618 if (!current_cpu_data.cpu_clock)
619 current_cpu_data.cpu_clock = current_cpu_data.master_clock / ifc;
620
621 printk("CPU clock: %d.%02dMHz\n",
622 (current_cpu_data.cpu_clock / 1000000),
623 (current_cpu_data.cpu_clock % 1000000)/10000);
624 printk("Bus clock: %d.%02dMHz\n",
625 (current_cpu_data.bus_clock / 1000000),
626 (current_cpu_data.bus_clock % 1000000)/10000);
627#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
628 printk("Memory clock: %d.%02dMHz\n",
629 (current_cpu_data.memory_clock / 1000000),
630 (current_cpu_data.memory_clock % 1000000)/10000);
631#endif
632 printk("Module clock: %d.%02dMHz\n",
633 (current_cpu_data.module_clock / 1000000),
634 (current_cpu_data.module_clock % 1000000)/10000);
635
636 interval = (current_cpu_data.module_clock/4 + HZ/2) / HZ;
637
638 printk("Interval = %ld\n", interval);
639
640 /* Start TMU0 */
641 ctrl_outb(0, TMU_TSTR);
642#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
643 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
644#endif
645 ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
646 ctrl_outl(interval, TMU0_TCOR);
647 ctrl_outl(interval, TMU0_TCNT);
648 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
649
650#if defined(CONFIG_SH_KGDB)
651 /*
652 * Set up kgdb as requested. We do it here because the serial
653 * init uses the timer vars we just set up for figuring baud.
654 */
655 kgdb_init();
656#endif
657}
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
new file mode 100644
index 000000000000..7eb06719d844
--- /dev/null
+++ b/arch/sh/kernel/traps.c
@@ -0,0 +1,712 @@
1/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $
2 *
3 * linux/arch/sh/traps.c
4 *
5 * SuperH version: Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2000 Philipp Rumpf
7 * Copyright (C) 2000 David Howells
8 * Copyright (C) 2002, 2003 Paul Mundt
9 */
10
11/*
12 * 'Traps.c' handles hardware traps and faults after we have saved some
13 * state in 'entry.S'.
14 */
15#include <linux/config.h>
16#include <linux/sched.h>
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/errno.h>
20#include <linux/ptrace.h>
21#include <linux/timer.h>
22#include <linux/mm.h>
23#include <linux/smp.h>
24#include <linux/smp_lock.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/spinlock.h>
28#include <linux/module.h>
29#include <linux/kallsyms.h>
30
31#include <asm/system.h>
32#include <asm/uaccess.h>
33#include <asm/io.h>
34#include <asm/atomic.h>
35#include <asm/processor.h>
36#include <asm/sections.h>
37
38#ifdef CONFIG_SH_KGDB
39#include <asm/kgdb.h>
40#define CHK_REMOTE_DEBUG(regs) \
41{ \
42 if ((kgdb_debug_hook != (kgdb_debug_hook_t *) NULL) && (!user_mode(regs))) \
43 { \
44 (*kgdb_debug_hook)(regs); \
45 } \
46}
47#else
48#define CHK_REMOTE_DEBUG(regs)
49#endif
50
51#define DO_ERROR(trapnr, signr, str, name, tsk) \
52asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
53 unsigned long r6, unsigned long r7, \
54 struct pt_regs regs) \
55{ \
56 unsigned long error_code; \
57 \
58 /* Check if it's a DSP instruction */ \
59 if (is_dsp_inst(&regs)) { \
60 /* Enable DSP mode, and restart instruction. */ \
61 regs.sr |= SR_DSP; \
62 return; \
63 } \
64 \
65 asm volatile("stc r2_bank, %0": "=r" (error_code)); \
66 local_irq_enable(); \
67 tsk->thread.error_code = error_code; \
68 tsk->thread.trap_no = trapnr; \
69 CHK_REMOTE_DEBUG(&regs); \
70 force_sig(signr, tsk); \
71 die_if_no_fixup(str,&regs,error_code); \
72}
73
74#ifdef CONFIG_CPU_SH2
75#define TRAP_RESERVED_INST 4
76#define TRAP_ILLEGAL_SLOT_INST 6
77#else
78#define TRAP_RESERVED_INST 12
79#define TRAP_ILLEGAL_SLOT_INST 13
80#endif
81
82/*
83 * These constants are for searching for possible module text
84 * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
85 * a guess of how much space is likely to be vmalloced.
86 */
87#define VMALLOC_OFFSET (8*1024*1024)
88#define MODULE_RANGE (8*1024*1024)
89
90spinlock_t die_lock;
91
92void die(const char * str, struct pt_regs * regs, long err)
93{
94 static int die_counter;
95
96 console_verbose();
97 spin_lock_irq(&die_lock);
98 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
99 CHK_REMOTE_DEBUG(regs);
100 show_regs(regs);
101 spin_unlock_irq(&die_lock);
102 do_exit(SIGSEGV);
103}
104
105static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
106{
107 if (!user_mode(regs))
108 die(str, regs, err);
109}
110
111static int handle_unaligned_notify_count = 10;
112
113/*
114 * try and fix up kernelspace address errors
115 * - userspace errors just cause EFAULT to be returned, resulting in SEGV
116 * - kernel/userspace interfaces cause a jump to an appropriate handler
117 * - other kernel errors are bad
118 * - return 0 if fixed-up, -EFAULT if non-fatal (to the kernel) fault
119 */
120static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
121{
122 if (!user_mode(regs))
123 {
124 const struct exception_table_entry *fixup;
125 fixup = search_exception_tables(regs->pc);
126 if (fixup) {
127 regs->pc = fixup->fixup;
128 return 0;
129 }
130 die(str, regs, err);
131 }
132 return -EFAULT;
133}
134
135/*
136 * handle an instruction that does an unaligned memory access by emulating the
137 * desired behaviour
138 * - note that PC _may not_ point to the faulting instruction
139 * (if that instruction is in a branch delay slot)
140 * - return 0 if emulation okay, -EFAULT on existential error
141 */
142static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
143{
144 int ret, index, count;
145 unsigned long *rm, *rn;
146 unsigned char *src, *dst;
147
148 index = (instruction>>8)&15; /* 0x0F00 */
149 rn = &regs->regs[index];
150
151 index = (instruction>>4)&15; /* 0x00F0 */
152 rm = &regs->regs[index];
153
154 count = 1<<(instruction&3);
155
156 ret = -EFAULT;
157 switch (instruction>>12) {
158 case 0: /* mov.[bwl] to/from memory via r0+rn */
159 if (instruction & 8) {
160 /* from memory */
161 src = (unsigned char*) *rm;
162 src += regs->regs[0];
163 dst = (unsigned char*) rn;
164 *(unsigned long*)dst = 0;
165
166#ifdef __LITTLE_ENDIAN__
167 if (copy_from_user(dst, src, count))
168 goto fetch_fault;
169
170 if ((count == 2) && dst[1] & 0x80) {
171 dst[2] = 0xff;
172 dst[3] = 0xff;
173 }
174#else
175 dst += 4-count;
176
177 if (__copy_user(dst, src, count))
178 goto fetch_fault;
179
180 if ((count == 2) && dst[2] & 0x80) {
181 dst[0] = 0xff;
182 dst[1] = 0xff;
183 }
184#endif
185 } else {
186 /* to memory */
187 src = (unsigned char*) rm;
188#if !defined(__LITTLE_ENDIAN__)
189 src += 4-count;
190#endif
191 dst = (unsigned char*) *rn;
192 dst += regs->regs[0];
193
194 if (copy_to_user(dst, src, count))
195 goto fetch_fault;
196 }
197 ret = 0;
198 break;
199
200 case 1: /* mov.l Rm,@(disp,Rn) */
201 src = (unsigned char*) rm;
202 dst = (unsigned char*) *rn;
203 dst += (instruction&0x000F)<<2;
204
205 if (copy_to_user(dst,src,4))
206 goto fetch_fault;
207 ret = 0;
208 break;
209
210 case 2: /* mov.[bwl] to memory, possibly with pre-decrement */
211 if (instruction & 4)
212 *rn -= count;
213 src = (unsigned char*) rm;
214 dst = (unsigned char*) *rn;
215#if !defined(__LITTLE_ENDIAN__)
216 src += 4-count;
217#endif
218 if (copy_to_user(dst, src, count))
219 goto fetch_fault;
220 ret = 0;
221 break;
222
223 case 5: /* mov.l @(disp,Rm),Rn */
224 src = (unsigned char*) *rm;
225 src += (instruction&0x000F)<<2;
226 dst = (unsigned char*) rn;
227 *(unsigned long*)dst = 0;
228
229 if (copy_from_user(dst,src,4))
230 goto fetch_fault;
231 ret = 0;
232 break;
233
234 case 6: /* mov.[bwl] from memory, possibly with post-increment */
235 src = (unsigned char*) *rm;
236 if (instruction & 4)
237 *rm += count;
238 dst = (unsigned char*) rn;
239 *(unsigned long*)dst = 0;
240
241#ifdef __LITTLE_ENDIAN__
242 if (copy_from_user(dst, src, count))
243 goto fetch_fault;
244
245 if ((count == 2) && dst[1] & 0x80) {
246 dst[2] = 0xff;
247 dst[3] = 0xff;
248 }
249#else
250 dst += 4-count;
251
252 if (copy_from_user(dst, src, count))
253 goto fetch_fault;
254
255 if ((count == 2) && dst[2] & 0x80) {
256 dst[0] = 0xff;
257 dst[1] = 0xff;
258 }
259#endif
260 ret = 0;
261 break;
262
263 case 8:
264 switch ((instruction&0xFF00)>>8) {
265 case 0x81: /* mov.w R0,@(disp,Rn) */
266 src = (unsigned char*) &regs->regs[0];
267#if !defined(__LITTLE_ENDIAN__)
268 src += 2;
269#endif
270 dst = (unsigned char*) *rm; /* called Rn in the spec */
271 dst += (instruction&0x000F)<<1;
272
273 if (copy_to_user(dst, src, 2))
274 goto fetch_fault;
275 ret = 0;
276 break;
277
278 case 0x85: /* mov.w @(disp,Rm),R0 */
279 src = (unsigned char*) *rm;
280 src += (instruction&0x000F)<<1;
281 dst = (unsigned char*) &regs->regs[0];
282 *(unsigned long*)dst = 0;
283
284#if !defined(__LITTLE_ENDIAN__)
285 dst += 2;
286#endif
287
288 if (copy_from_user(dst, src, 2))
289 goto fetch_fault;
290
291#ifdef __LITTLE_ENDIAN__
292 if (dst[1] & 0x80) {
293 dst[2] = 0xff;
294 dst[3] = 0xff;
295 }
296#else
297 if (dst[2] & 0x80) {
298 dst[0] = 0xff;
299 dst[1] = 0xff;
300 }
301#endif
302 ret = 0;
303 break;
304 }
305 break;
306 }
307 return ret;
308
309 fetch_fault:
310 /* Argh. Address not only misaligned but also non-existent.
311 * Raise an EFAULT and see if it's trapped
312 */
313 return die_if_no_fixup("Fault in unaligned fixup", regs, 0);
314}
315
316/*
317 * emulate the instruction in the delay slot
318 * - fetches the instruction from PC+2
319 */
320static inline int handle_unaligned_delayslot(struct pt_regs *regs)
321{
322 u16 instruction;
323
324 if (copy_from_user(&instruction, (u16 *)(regs->pc+2), 2)) {
325 /* the instruction-fetch faulted */
326 if (user_mode(regs))
327 return -EFAULT;
328
329 /* kernel */
330 die("delay-slot-insn faulting in handle_unaligned_delayslot", regs, 0);
331 }
332
333 return handle_unaligned_ins(instruction,regs);
334}
335
336/*
337 * handle an instruction that does an unaligned memory access
338 * - have to be careful of branch delay-slot instructions that fault
339 * SH3:
340 * - if the branch would be taken PC points to the branch
341 * - if the branch would not be taken, PC points to delay-slot
342 * SH4:
343 * - PC always points to delayed branch
344 * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
345 */
346
347/* Macros to determine offset from current PC for branch instructions */
348/* Explicit type coercion is used to force sign extension where needed */
349#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
350#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
351
352static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
353{
354 u_int rm;
355 int ret, index;
356
357 index = (instruction>>8)&15; /* 0x0F00 */
358 rm = regs->regs[index];
359
360 /* shout about the first ten userspace fixups */
361 if (user_mode(regs) && handle_unaligned_notify_count>0) {
362 handle_unaligned_notify_count--;
363
364 printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
365 current->comm,current->pid,(u16*)regs->pc,instruction);
366 }
367
368 ret = -EFAULT;
369 switch (instruction&0xF000) {
370 case 0x0000:
371 if (instruction==0x000B) {
372 /* rts */
373 ret = handle_unaligned_delayslot(regs);
374 if (ret==0)
375 regs->pc = regs->pr;
376 }
377 else if ((instruction&0x00FF)==0x0023) {
378 /* braf @Rm */
379 ret = handle_unaligned_delayslot(regs);
380 if (ret==0)
381 regs->pc += rm + 4;
382 }
383 else if ((instruction&0x00FF)==0x0003) {
384 /* bsrf @Rm */
385 ret = handle_unaligned_delayslot(regs);
386 if (ret==0) {
387 regs->pr = regs->pc + 4;
388 regs->pc += rm + 4;
389 }
390 }
391 else {
392 /* mov.[bwl] to/from memory via r0+rn */
393 goto simple;
394 }
395 break;
396
397 case 0x1000: /* mov.l Rm,@(disp,Rn) */
398 goto simple;
399
400 case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */
401 goto simple;
402
403 case 0x4000:
404 if ((instruction&0x00FF)==0x002B) {
405 /* jmp @Rm */
406 ret = handle_unaligned_delayslot(regs);
407 if (ret==0)
408 regs->pc = rm;
409 }
410 else if ((instruction&0x00FF)==0x000B) {
411 /* jsr @Rm */
412 ret = handle_unaligned_delayslot(regs);
413 if (ret==0) {
414 regs->pr = regs->pc + 4;
415 regs->pc = rm;
416 }
417 }
418 else {
419 /* mov.[bwl] to/from memory via r0+rn */
420 goto simple;
421 }
422 break;
423
424 case 0x5000: /* mov.l @(disp,Rm),Rn */
425 goto simple;
426
427 case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */
428 goto simple;
429
430 case 0x8000: /* bf lab, bf/s lab, bt lab, bt/s lab */
431 switch (instruction&0x0F00) {
432 case 0x0100: /* mov.w R0,@(disp,Rm) */
433 goto simple;
434 case 0x0500: /* mov.w @(disp,Rm),R0 */
435 goto simple;
436 case 0x0B00: /* bf lab - no delayslot*/
437 break;
438 case 0x0F00: /* bf/s lab */
439 ret = handle_unaligned_delayslot(regs);
440 if (ret==0) {
441#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
442 if ((regs->sr & 0x00000001) != 0)
443 regs->pc += 4; /* next after slot */
444 else
445#endif
446 regs->pc += SH_PC_8BIT_OFFSET(instruction);
447 }
448 break;
449 case 0x0900: /* bt lab - no delayslot */
450 break;
451 case 0x0D00: /* bt/s lab */
452 ret = handle_unaligned_delayslot(regs);
453 if (ret==0) {
454#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
455 if ((regs->sr & 0x00000001) == 0)
456 regs->pc += 4; /* next after slot */
457 else
458#endif
459 regs->pc += SH_PC_8BIT_OFFSET(instruction);
460 }
461 break;
462 }
463 break;
464
465 case 0xA000: /* bra label */
466 ret = handle_unaligned_delayslot(regs);
467 if (ret==0)
468 regs->pc += SH_PC_12BIT_OFFSET(instruction);
469 break;
470
471 case 0xB000: /* bsr label */
472 ret = handle_unaligned_delayslot(regs);
473 if (ret==0) {
474 regs->pr = regs->pc + 4;
475 regs->pc += SH_PC_12BIT_OFFSET(instruction);
476 }
477 break;
478 }
479 return ret;
480
481 /* handle non-delay-slot instruction */
482 simple:
483 ret = handle_unaligned_ins(instruction,regs);
484 if (ret==0)
485 regs->pc += 2;
486 return ret;
487}
488
489/*
490 * Handle various address error exceptions
491 */
492asmlinkage void do_address_error(struct pt_regs *regs,
493 unsigned long writeaccess,
494 unsigned long address)
495{
496 unsigned long error_code;
497 mm_segment_t oldfs;
498 u16 instruction;
499 int tmp;
500
501 asm volatile("stc r2_bank,%0": "=r" (error_code));
502
503 oldfs = get_fs();
504
505 if (user_mode(regs)) {
506 local_irq_enable();
507 current->thread.error_code = error_code;
508 current->thread.trap_no = (writeaccess) ? 8 : 7;
509
510 /* bad PC is not something we can fix */
511 if (regs->pc & 1)
512 goto uspace_segv;
513
514 set_fs(USER_DS);
515 if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
516 /* Argh. Fault on the instruction itself.
517 This should never happen non-SMP
518 */
519 set_fs(oldfs);
520 goto uspace_segv;
521 }
522
523 tmp = handle_unaligned_access(instruction, regs);
524 set_fs(oldfs);
525
526 if (tmp==0)
527 return; /* sorted */
528
529 uspace_segv:
530 printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm);
531 force_sig(SIGSEGV, current);
532 } else {
533 if (regs->pc & 1)
534 die("unaligned program counter", regs, error_code);
535
536 set_fs(KERNEL_DS);
537 if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
538 /* Argh. Fault on the instruction itself.
539 This should never happen non-SMP
540 */
541 set_fs(oldfs);
542 die("insn faulting in do_address_error", regs, 0);
543 }
544
545 handle_unaligned_access(instruction, regs);
546 set_fs(oldfs);
547 }
548}
549
550#ifdef CONFIG_SH_DSP
551/*
552 * SH-DSP support gerg@snapgear.com.
553 */
554int is_dsp_inst(struct pt_regs *regs)
555{
556 unsigned short inst;
557
558 /*
559 * Safe guard if DSP mode is already enabled or we're lacking
560 * the DSP altogether.
561 */
562 if (!(cpu_data->flags & CPU_HAS_DSP) || (regs->sr & SR_DSP))
563 return 0;
564
565 get_user(inst, ((unsigned short *) regs->pc));
566
567 inst &= 0xf000;
568
569 /* Check for any type of DSP or support instruction */
570 if ((inst == 0xf000) || (inst == 0x4000))
571 return 1;
572
573 return 0;
574}
575#else
576#define is_dsp_inst(regs) (0)
577#endif /* CONFIG_SH_DSP */
578
579DO_ERROR(TRAP_RESERVED_INST, SIGILL, "reserved instruction", reserved_inst, current)
580DO_ERROR(TRAP_ILLEGAL_SLOT_INST, SIGILL, "illegal slot instruction", illegal_slot_inst, current)
581
582asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
583 unsigned long r6, unsigned long r7,
584 struct pt_regs regs)
585{
586 long ex;
587 asm volatile("stc r2_bank, %0" : "=r" (ex));
588 die_if_kernel("exception", &regs, ex);
589}
590
591#if defined(CONFIG_SH_STANDARD_BIOS)
592void *gdb_vbr_vector;
593
594static inline void __init gdb_vbr_init(void)
595{
596 register unsigned long vbr;
597
598 /*
599 * Read the old value of the VBR register to initialise
600 * the vector through which debug and BIOS traps are
601 * delegated by the Linux trap handler.
602 */
603 asm volatile("stc vbr, %0" : "=r" (vbr));
604
605 gdb_vbr_vector = (void *)(vbr + 0x100);
606 printk("Setting GDB trap vector to 0x%08lx\n",
607 (unsigned long)gdb_vbr_vector);
608}
609#endif
610
611void __init per_cpu_trap_init(void)
612{
613 extern void *vbr_base;
614
615#ifdef CONFIG_SH_STANDARD_BIOS
616 gdb_vbr_init();
617#endif
618
619 /* NOTE: The VBR value should be at P1
620 (or P2, virtural "fixed" address space).
621 It's definitely should not in physical address. */
622
623 asm volatile("ldc %0, vbr"
624 : /* no output */
625 : "r" (&vbr_base)
626 : "memory");
627}
628
629void __init trap_init(void)
630{
631 extern void *exception_handling_table[];
632
633 exception_handling_table[TRAP_RESERVED_INST]
634 = (void *)do_reserved_inst;
635 exception_handling_table[TRAP_ILLEGAL_SLOT_INST]
636 = (void *)do_illegal_slot_inst;
637
638#ifdef CONFIG_CPU_SH4
639 if (!(cpu_data->flags & CPU_HAS_FPU)) {
640 /* For SH-4 lacking an FPU, treat floating point instructions
641 as reserved. */
642 /* entry 64 corresponds to EXPEVT=0x800 */
643 exception_handling_table[64] = (void *)do_reserved_inst;
644 exception_handling_table[65] = (void *)do_illegal_slot_inst;
645 }
646#endif
647
648 /* Setup VBR for boot cpu */
649 per_cpu_trap_init();
650}
651
652void show_stack(struct task_struct *tsk, unsigned long *sp)
653{
654 unsigned long *stack, addr;
655 unsigned long module_start = VMALLOC_START;
656 unsigned long module_end = VMALLOC_END;
657 int i = 1;
658
659 if (tsk && !sp) {
660 sp = (unsigned long *)tsk->thread.sp;
661 }
662
663 if (!sp) {
664 __asm__ __volatile__ (
665 "mov r15, %0\n\t"
666 "stc r7_bank, %1\n\t"
667 : "=r" (module_start),
668 "=r" (module_end)
669 );
670
671 sp = (unsigned long *)module_start;
672 }
673
674 stack = sp;
675
676 printk("\nCall trace: ");
677#ifdef CONFIG_KALLSYMS
678 printk("\n");
679#endif
680
681 while (!kstack_end(stack)) {
682 addr = *stack++;
683 if (((addr >= (unsigned long)_text) &&
684 (addr <= (unsigned long)_etext)) ||
685 ((addr >= module_start) && (addr <= module_end))) {
686 /*
687 * For 80-columns display, 6 entry is maximum.
688 * NOTE: '[<8c00abcd>] ' consumes 13 columns .
689 */
690#ifndef CONFIG_KALLSYMS
691 if (i && ((i % 6) == 0))
692 printk("\n ");
693#endif
694 printk("[<%08lx>] ", addr);
695 print_symbol("%s\n", addr);
696 i++;
697 }
698 }
699
700 printk("\n");
701}
702
703void show_task(unsigned long *sp)
704{
705 show_stack(NULL, sp);
706}
707
708void dump_stack(void)
709{
710 show_stack(NULL, NULL);
711}
712EXPORT_SYMBOL(dump_stack);
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..51bdc1cf7838
--- /dev/null
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -0,0 +1,155 @@
1/* $Id: vmlinux.lds.S,v 1.8 2003/05/16 17:18:14 lethal Exp $
2 * ld script to make SuperH Linux kernel
3 * Written by Niibe Yutaka
4 */
5#include <linux/config.h>
6#include <asm-generic/vmlinux.lds.h>
7
8#ifdef CONFIG_CPU_LITTLE_ENDIAN
9OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
10#else
11OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
12#endif
13OUTPUT_ARCH(sh)
14ENTRY(_start)
15SECTIONS
16{
17 . = 0x80000000 + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
18 _text = .; /* Text and read-only data */
19 text = .; /* Text and read-only data */
20 .empty_zero_page : {
21 *(.empty_zero_page)
22 } = 0
23 .text : {
24 *(.text)
25 SCHED_TEXT
26 LOCK_TEXT
27 *(.fixup)
28 *(.gnu.warning)
29 } = 0x0009
30
31 . = ALIGN(16); /* Exception table */
32 __start___ex_table = .;
33 __ex_table : { *(__ex_table) }
34 __stop___ex_table = .;
35
36 RODATA
37
38 _etext = .; /* End of text section */
39
40 .data : { /* Data */
41 *(.data)
42
43 /* Align the initial ramdisk image (INITRD) on page boundaries. */
44 . = ALIGN(4096);
45 __rd_start = .;
46 *(.initrd)
47 . = ALIGN(4096);
48 __rd_end = .;
49
50 CONSTRUCTORS
51 }
52
53 . = ALIGN(4096);
54 .data.page_aligned : { *(.data.idt) }
55
56 . = ALIGN(32);
57 __per_cpu_start = .;
58 .data.percpu : { *(.data.percpu) }
59 __per_cpu_end = .;
60 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
61
62 _edata = .; /* End of data section */
63
64 . = ALIGN(8192); /* init_task */
65 .data.init_task : { *(.data.init_task) }
66 /* stack */
67 .stack : { stack = .; _stack = .; }
68
69 . = ALIGN(4096); /* Init code and data */
70 __init_begin = .;
71 _sinittext = .;
72 .init.text : { *(.init.text) }
73 _einittext = .;
74 .init.data : { *(.init.data) }
75 . = ALIGN(16);
76 __setup_start = .;
77 .init.setup : { *(.init.setup) }
78 __setup_end = .;
79 __initcall_start = .;
80 .initcall.init : {
81 *(.initcall1.init)
82 *(.initcall2.init)
83 *(.initcall3.init)
84 *(.initcall4.init)
85 *(.initcall5.init)
86 *(.initcall6.init)
87 *(.initcall7.init)
88 }
89 __initcall_end = .;
90 __con_initcall_start = .;
91 .con_initcall.init : { *(.con_initcall.init) }
92 __con_initcall_end = .;
93 SECURITY_INIT
94 __initramfs_start = .;
95 .init.ramfs : { *(.init.ramfs) }
96 __initramfs_end = .;
97 __machvec_start = .;
98 .init.machvec : { *(.init.machvec) }
99 __machvec_end = .;
100 . = ALIGN(4096);
101 __init_end = .;
102
103 . = ALIGN(4);
104 __bss_start = .; /* BSS */
105 .bss : { *(.bss) }
106
107 . = ALIGN(4);
108 _end = . ;
109
110 /* When something in the kernel is NOT compiled as a module, the
111 * module cleanup code and data are put into these segments. Both
112 * can then be thrown away, as cleanup code is never called unless
113 * it's a module.
114 */
115 /DISCARD/ : {
116 *(.exit.text)
117 *(.exit.data)
118 *(.exitcall.exit)
119 }
120
121 /* Stabs debugging sections. */
122 .stab 0 : { *(.stab) }
123 .stabstr 0 : { *(.stabstr) }
124 .stab.excl 0 : { *(.stab.excl) }
125 .stab.exclstr 0 : { *(.stab.exclstr) }
126 .stab.index 0 : { *(.stab.index) }
127 .stab.indexstr 0 : { *(.stab.indexstr) }
128 .comment 0 : { *(.comment) }
129 /* DWARF debug sections.
130 Symbols in the DWARF debugging section are relative to the beginning
131 of the section so we begin .debug at 0. */
132 /* DWARF 1 */
133 .debug 0 : { *(.debug) }
134 .line 0 : { *(.line) }
135 /* GNU DWARF 1 extensions */
136 .debug_srcinfo 0 : { *(.debug_srcinfo) }
137 .debug_sfnames 0 : { *(.debug_sfnames) }
138 /* DWARF 1.1 and DWARF 2 */
139 .debug_aranges 0 : { *(.debug_aranges) }
140 .debug_pubnames 0 : { *(.debug_pubnames) }
141 /* DWARF 2 */
142 .debug_info 0 : { *(.debug_info) }
143 .debug_abbrev 0 : { *(.debug_abbrev) }
144 .debug_line 0 : { *(.debug_line) }
145 .debug_frame 0 : { *(.debug_frame) }
146 .debug_str 0 : { *(.debug_str) }
147 .debug_loc 0 : { *(.debug_loc) }
148 .debug_macinfo 0 : { *(.debug_macinfo) }
149 /* SGI/MIPS DWARF 2 extensions */
150 .debug_weaknames 0 : { *(.debug_weaknames) }
151 .debug_funcnames 0 : { *(.debug_funcnames) }
152 .debug_typenames 0 : { *(.debug_typenames) }
153 .debug_varnames 0 : { *(.debug_varnames) }
154 /* These must appear regardless of . */
155}
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
new file mode 100644
index 000000000000..b5681e3f9684
--- /dev/null
+++ b/arch/sh/lib/Makefile
@@ -0,0 +1,13 @@
1#
2# Makefile for SuperH-specific library files..
3#
4
5lib-y = delay.o memset.o memmove.o memchr.o \
6 checksum.o strcasecmp.o strlen.o div64.o udivdi3.o \
7 div64-generic.o
8
9memcpy-y := memcpy.o
10memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o
11
12lib-y += $(memcpy-y)
13
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
new file mode 100644
index 000000000000..7c50dfe68c07
--- /dev/null
+++ b/arch/sh/lib/checksum.S
@@ -0,0 +1,385 @@
1/* $Id: checksum.S,v 1.10 2001/07/06 13:11:32 gniibe Exp $
2 *
3 * INET An implementation of the TCP/IP protocol suite for the LINUX
4 * operating system. INET is implemented using the BSD Socket
5 * interface as the means of communication with the user level.
6 *
7 * IP/TCP/UDP checksumming routines
8 *
9 * Authors: Jorge Cwik, <jorge@laser.satlink.net>
10 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
11 * Tom May, <ftom@netcom.com>
12 * Pentium Pro/II routines:
13 * Alexander Kjeldaas <astor@guardian.no>
14 * Finn Arne Gangstad <finnag@guardian.no>
15 * Lots of code moved from tcp.c and ip.c; see those files
16 * for more names.
17 *
18 * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception
19 * handling.
20 * Andi Kleen, add zeroing on error
21 * converted to pure assembler
22 *
23 * SuperH version: Copyright (C) 1999 Niibe Yutaka
24 *
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version
28 * 2 of the License, or (at your option) any later version.
29 */
30
31#include <asm/errno.h>
32#include <linux/linkage.h>
33
34/*
35 * computes a partial checksum, e.g. for TCP/UDP fragments
36 */
37
38/*
39 * unsigned int csum_partial(const unsigned char *buf, int len,
40 * unsigned int sum);
41 */
42
43.text
44ENTRY(csum_partial)
45 /*
46 * Experiments with Ethernet and SLIP connections show that buff
47 * is aligned on either a 2-byte or 4-byte boundary. We get at
48 * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
49 * Fortunately, it is easy to convert 2-byte alignment to 4-byte
50 * alignment for the unrolled loop.
51 */
52 mov r5, r1
53 mov r4, r0
54 tst #2, r0 ! Check alignment.
55 bt 2f ! Jump if alignment is ok.
56 !
57 add #-2, r5 ! Alignment uses up two bytes.
58 cmp/pz r5 !
59 bt/s 1f ! Jump if we had at least two bytes.
60 clrt
61 bra 6f
62 add #2, r5 ! r5 was < 2. Deal with it.
631:
64 mov r5, r1 ! Save new len for later use.
65 mov.w @r4+, r0
66 extu.w r0, r0
67 addc r0, r6
68 bf 2f
69 add #1, r6
702:
71 mov #-5, r0
72 shld r0, r5
73 tst r5, r5
74 bt/s 4f ! if it's =0, go to 4f
75 clrt
76 .align 2
773:
78 mov.l @r4+, r0
79 mov.l @r4+, r2
80 mov.l @r4+, r3
81 addc r0, r6
82 mov.l @r4+, r0
83 addc r2, r6
84 mov.l @r4+, r2
85 addc r3, r6
86 mov.l @r4+, r3
87 addc r0, r6
88 mov.l @r4+, r0
89 addc r2, r6
90 mov.l @r4+, r2
91 addc r3, r6
92 addc r0, r6
93 addc r2, r6
94 movt r0
95 dt r5
96 bf/s 3b
97 cmp/eq #1, r0
98 ! here, we know r5==0
99 addc r5, r6 ! add carry to r6
1004:
101 mov r1, r0
102 and #0x1c, r0
103 tst r0, r0
104 bt/s 6f
105 mov r0, r5
106 shlr2 r5
107 mov #0, r2
1085:
109 addc r2, r6
110 mov.l @r4+, r2
111 movt r0
112 dt r5
113 bf/s 5b
114 cmp/eq #1, r0
115 addc r2, r6
116 addc r5, r6 ! r5==0 here, so it means add carry-bit
1176:
118 mov r1, r5
119 mov #3, r0
120 and r0, r5
121 tst r5, r5
122 bt 9f ! if it's =0 go to 9f
123 mov #2, r1
124 cmp/hs r1, r5
125 bf 7f
126 mov.w @r4+, r0
127 extu.w r0, r0
128 cmp/eq r1, r5
129 bt/s 8f
130 clrt
131 shll16 r0
132 addc r0, r6
1337:
134 mov.b @r4+, r0
135 extu.b r0, r0
136#ifndef __LITTLE_ENDIAN__
137 shll8 r0
138#endif
1398:
140 addc r0, r6
141 mov #0, r0
142 addc r0, r6
1439:
144 rts
145 mov r6, r0
146
147/*
148unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
149 int sum, int *src_err_ptr, int *dst_err_ptr)
150 */
151
152/*
153 * Copy from ds while checksumming, otherwise like csum_partial
154 *
155 * The macros SRC and DST specify the type of access for the instruction.
156 * thus we can call a custom exception handler for all access types.
157 *
158 * FIXME: could someone double-check whether I haven't mixed up some SRC and
159 * DST definitions? It's damn hard to trigger all cases. I hope I got
160 * them all but there's no guarantee.
161 */
162
163#define SRC(...) \
164 9999: __VA_ARGS__ ; \
165 .section __ex_table, "a"; \
166 .long 9999b, 6001f ; \
167 .previous
168
169#define DST(...) \
170 9999: __VA_ARGS__ ; \
171 .section __ex_table, "a"; \
172 .long 9999b, 6002f ; \
173 .previous
174
175!
176! r4: const char *SRC
177! r5: char *DST
178! r6: int LEN
179! r7: int SUM
180!
181! on stack:
182! int *SRC_ERR_PTR
183! int *DST_ERR_PTR
184!
185ENTRY(csum_partial_copy_generic)
186 mov.l r5,@-r15
187 mov.l r6,@-r15
188
189 mov #3,r0 ! Check src and dest are equally aligned
190 mov r4,r1
191 and r0,r1
192 and r5,r0
193 cmp/eq r1,r0
194 bf 3f ! Different alignments, use slow version
195 tst #1,r0 ! Check dest word aligned
196 bf 3f ! If not, do it the slow way
197
198 mov #2,r0
199 tst r0,r5 ! Check dest alignment.
200 bt 2f ! Jump if alignment is ok.
201 add #-2,r6 ! Alignment uses up two bytes.
202 cmp/pz r6 ! Jump if we had at least two bytes.
203 bt/s 1f
204 clrt
205 bra 4f
206 add #2,r6 ! r6 was < 2. Deal with it.
207
2083: ! Handle different src and dest alignments.
209 ! This is not common, so simple byte by byte copy will do.
210 mov r6,r2
211 shlr r6
212 tst r6,r6
213 bt 4f
214 clrt
215 .align 2
2165:
217SRC( mov.b @r4+,r1 )
218SRC( mov.b @r4+,r0 )
219 extu.b r1,r1
220DST( mov.b r1,@r5 )
221DST( mov.b r0,@(1,r5) )
222 extu.b r0,r0
223 add #2,r5
224
225#ifdef __LITTLE_ENDIAN__
226 shll8 r0
227#else
228 shll8 r1
229#endif
230 or r1,r0
231
232 addc r0,r7
233 movt r0
234 dt r6
235 bf/s 5b
236 cmp/eq #1,r0
237 mov #0,r0
238 addc r0, r7
239
240 mov r2, r0
241 tst #1, r0
242 bt 7f
243 bra 5f
244 clrt
245
246 ! src and dest equally aligned, but to a two byte boundary.
247 ! Handle first two bytes as a special case
248 .align 2
2491:
250SRC( mov.w @r4+,r0 )
251DST( mov.w r0,@r5 )
252 add #2,r5
253 extu.w r0,r0
254 addc r0,r7
255 mov #0,r0
256 addc r0,r7
2572:
258 mov r6,r2
259 mov #-5,r0
260 shld r0,r6
261 tst r6,r6
262 bt/s 2f
263 clrt
264 .align 2
2651:
266SRC( mov.l @r4+,r0 )
267SRC( mov.l @r4+,r1 )
268 addc r0,r7
269DST( mov.l r0,@r5 )
270DST( mov.l r1,@(4,r5) )
271 addc r1,r7
272
273SRC( mov.l @r4+,r0 )
274SRC( mov.l @r4+,r1 )
275 addc r0,r7
276DST( mov.l r0,@(8,r5) )
277DST( mov.l r1,@(12,r5) )
278 addc r1,r7
279
280SRC( mov.l @r4+,r0 )
281SRC( mov.l @r4+,r1 )
282 addc r0,r7
283DST( mov.l r0,@(16,r5) )
284DST( mov.l r1,@(20,r5) )
285 addc r1,r7
286
287SRC( mov.l @r4+,r0 )
288SRC( mov.l @r4+,r1 )
289 addc r0,r7
290DST( mov.l r0,@(24,r5) )
291DST( mov.l r1,@(28,r5) )
292 addc r1,r7
293 add #32,r5
294 movt r0
295 dt r6
296 bf/s 1b
297 cmp/eq #1,r0
298 mov #0,r0
299 addc r0,r7
300
3012: mov r2,r6
302 mov #0x1c,r0
303 and r0,r6
304 cmp/pl r6
305 bf/s 4f
306 clrt
307 shlr2 r6
3083:
309SRC( mov.l @r4+,r0 )
310 addc r0,r7
311DST( mov.l r0,@r5 )
312 add #4,r5
313 movt r0
314 dt r6
315 bf/s 3b
316 cmp/eq #1,r0
317 mov #0,r0
318 addc r0,r7
3194: mov r2,r6
320 mov #3,r0
321 and r0,r6
322 cmp/pl r6
323 bf 7f
324 mov #2,r1
325 cmp/hs r1,r6
326 bf 5f
327SRC( mov.w @r4+,r0 )
328DST( mov.w r0,@r5 )
329 extu.w r0,r0
330 add #2,r5
331 cmp/eq r1,r6
332 bt/s 6f
333 clrt
334 shll16 r0
335 addc r0,r7
3365:
337SRC( mov.b @r4+,r0 )
338DST( mov.b r0,@r5 )
339 extu.b r0,r0
340#ifndef __LITTLE_ENDIAN__
341 shll8 r0
342#endif
3436: addc r0,r7
344 mov #0,r0
345 addc r0,r7
3467:
3475000:
348
349# Exception handler:
350.section .fixup, "ax"
351
3526001:
353 mov.l @(8,r15),r0 ! src_err_ptr
354 mov #-EFAULT,r1
355 mov.l r1,@r0
356
357 ! zero the complete destination - computing the rest
358 ! is too much work
359 mov.l @(4,r15),r5 ! dst
360 mov.l @r15,r6 ! len
361 mov #0,r7
3621: mov.b r7,@r5
363 dt r6
364 bf/s 1b
365 add #1,r5
366 mov.l 8000f,r0
367 jmp @r0
368 nop
369 .align 2
3708000: .long 5000b
371
3726002:
373 mov.l @(12,r15),r0 ! dst_err_ptr
374 mov #-EFAULT,r1
375 mov.l r1,@r0
376 mov.l 8001f,r0
377 jmp @r0
378 nop
379 .align 2
3808001: .long 5000b
381
382.previous
383 add #8,r15
384 rts
385 mov r7,r0
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c
new file mode 100644
index 000000000000..50b36037d86b
--- /dev/null
+++ b/arch/sh/lib/delay.c
@@ -0,0 +1,41 @@
1/*
2 * Precise Delay Loops for SuperH
3 *
4 * Copyright (C) 1999 Niibe Yutaka & Kaz Kojima
5 */
6
7#include <linux/sched.h>
8#include <linux/delay.h>
9
10void __delay(unsigned long loops)
11{
12 __asm__ __volatile__(
13 "tst %0, %0\n\t"
14 "1:\t"
15 "bf/s 1b\n\t"
16 " dt %0"
17 : "=r" (loops)
18 : "0" (loops)
19 : "t");
20}
21
22inline void __const_udelay(unsigned long xloops)
23{
24 __asm__("dmulu.l %0, %2\n\t"
25 "sts mach, %0"
26 : "=r" (xloops)
27 : "0" (xloops), "r" (cpu_data[_smp_processor_id()].loops_per_jiffy)
28 : "macl", "mach");
29 __delay(xloops * HZ);
30}
31
32void __udelay(unsigned long usecs)
33{
34 __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
35}
36
37void __ndelay(unsigned long nsecs)
38{
39 __const_udelay(nsecs * 0x00000005);
40}
41
diff --git a/arch/sh/lib/div64-generic.c b/arch/sh/lib/div64-generic.c
new file mode 100644
index 000000000000..c02473afd581
--- /dev/null
+++ b/arch/sh/lib/div64-generic.c
@@ -0,0 +1,19 @@
1/*
2 * Generic __div64_32 wrapper for __xdiv64_32.
3 */
4
5#include <linux/types.h>
6
7extern u64 __xdiv64_32(u64 n, u32 d);
8
9u64 __div64_32(u64 *xp, u32 y)
10{
11 u64 rem;
12 u64 q = __xdiv64_32(*xp, y);
13
14 rem = *xp - q * y;
15 *xp = q;
16
17 return rem;
18}
19
diff --git a/arch/sh/lib/div64.S b/arch/sh/lib/div64.S
new file mode 100644
index 000000000000..eefc275d64a7
--- /dev/null
+++ b/arch/sh/lib/div64.S
@@ -0,0 +1,46 @@
1/*
2 * unsigned long long __xdiv64_32(unsigned long long n, unsigned long d);
3 */
4
5#include <linux/linkage.h>
6
7.text
8ENTRY(__xdiv64_32)
9#ifdef __LITTLE_ENDIAN__
10 mov r4, r0
11 mov r5, r1
12#else
13 mov r4, r1
14 mov r5, r0
15#endif
16 cmp/hs r6, r1
17 bf.s 1f
18 mov #0, r2
19
20 mov r1, r2
21 mov #0, r3
22 div0u
23 .rept 32
24 rotcl r2
25 div1 r6, r3
26 .endr
27 rotcl r2
28 mul.l r6, r2
29 sts macl, r3
30 sub r3, r1
311:
32 div0u
33 .rept 32
34 rotcl r0
35 div1 r6, r1
36 .endr
37#ifdef __LITTLE_ENDIAN__
38 mov r2, r1
39 rts
40 rotcl r0
41#else
42 rotcl r0
43 mov r0, r1
44 rts
45 mov r2, r0
46#endif
diff --git a/arch/sh/lib/memchr.S b/arch/sh/lib/memchr.S
new file mode 100644
index 000000000000..bc6036ad5706
--- /dev/null
+++ b/arch/sh/lib/memchr.S
@@ -0,0 +1,26 @@
1/* $Id: memchr.S,v 1.1 2000/04/14 16:49:01 mjd Exp $
2 *
3 * "memchr" implementation of SuperH
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 *
7 */
8
9/*
10 * void *memchr(const void *s, int c, size_t n);
11 */
12
13#include <linux/linkage.h>
14ENTRY(memchr)
15 tst r6,r6
16 bt/s 2f
17 exts.b r5,r5
181: mov.b @r4,r1
19 cmp/eq r1,r5
20 bt/s 3f
21 dt r6
22 bf/s 1b
23 add #1,r4
242: mov #0,r4
253: rts
26 mov r4,r0
diff --git a/arch/sh/lib/memcpy-sh4.S b/arch/sh/lib/memcpy-sh4.S
new file mode 100644
index 000000000000..55f227441f9e
--- /dev/null
+++ b/arch/sh/lib/memcpy-sh4.S
@@ -0,0 +1,800 @@
1/*
2 * "memcpy" implementation of SuperH
3 *
4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (c) 2002 STMicroelectronics Ltd
6 * Modified from memcpy.S and micro-optimised for SH4
7 * Stuart Menefy (stuart.menefy@st.com)
8 *
9 */
10#include <linux/linkage.h>
11#include <linux/config.h>
12
13/*
14 * void *memcpy(void *dst, const void *src, size_t n);
15 *
16 * It is assumed that there is no overlap between src and dst.
17 * If there is an overlap, then the results are undefined.
18 */
19
20 !
21 ! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR.
22 !
23
24 ! Size is 16 or greater, and may have trailing bytes
25
26 .balign 32
27.Lcase1:
28 ! Read a long word and write a long word at once
29 ! At the start of each iteration, r7 contains last long load
30 add #-1,r5 ! 79 EX
31 mov r4,r2 ! 5 MT (0 cycles latency)
32
33 mov.l @(r0,r5),r7 ! 21 LS (2 cycles latency)
34 add #-4,r5 ! 50 EX
35
36 add #7,r2 ! 79 EX
37 !
38#ifdef CONFIG_CPU_LITTLE_ENDIAN
39 ! 6 cycles, 4 bytes per iteration
403: mov.l @(r0,r5),r1 ! 21 LS (latency=2) ! NMLK
41 mov r7, r3 ! 5 MT (latency=0) ! RQPO
42
43 cmp/hi r2,r0 ! 57 MT
44 shll16 r3 ! 103 EX
45
46 mov r1,r6 ! 5 MT (latency=0)
47 shll8 r3 ! 102 EX ! Oxxx
48
49 shlr8 r6 ! 106 EX ! xNML
50 mov r1, r7 ! 5 MT (latency=0)
51
52 or r6,r3 ! 82 EX ! ONML
53 bt/s 3b ! 109 BR
54
55 mov.l r3,@-r0 ! 30 LS
56#else
573: mov.l @(r0,r5),r1 ! 21 LS (latency=2) ! KLMN
58 mov r7,r3 ! 5 MT (latency=0) ! OPQR
59
60 cmp/hi r2,r0 ! 57 MT
61 shlr16 r3 ! 107 EX
62
63 shlr8 r3 ! 106 EX ! xxxO
64 mov r1,r6 ! 5 MT (latency=0)
65
66 shll8 r6 ! 102 EX ! LMNx
67 mov r1,r7 ! 5 MT (latency=0)
68
69 or r6,r3 ! 82 EX ! LMNO
70 bt/s 3b ! 109 BR
71
72 mov.l r3,@-r0 ! 30 LS
73#endif
74 ! Finally, copy a byte at once, if necessary
75
76 add #4,r5 ! 50 EX
77 cmp/eq r4,r0 ! 54 MT
78
79 add #-6,r2 ! 50 EX
80 bt 9f ! 109 BR
81
828: cmp/hi r2,r0 ! 57 MT
83 mov.b @(r0,r5),r1 ! 20 LS (latency=2)
84
85 bt/s 8b ! 109 BR
86
87 mov.b r1,@-r0 ! 29 LS
88
899: rts
90 nop
91
92
93 !
94 ! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R...
95 !
96
97 ! Size is 16 or greater, and may have trailing bytes
98
99 .balign 32
100.Lcase3:
101 ! Read a long word and write a long word at once
102 ! At the start of each iteration, r7 contains last long load
103 add #-3,r5 ! 79 EX
104 mov r4,r2 ! 5 MT (0 cycles latency)
105
106 mov.l @(r0,r5),r7 ! 21 LS (2 cycles latency)
107 add #-4,r5 ! 50 EX
108
109 add #7,r2 ! 79 EX
110 !
111#ifdef CONFIG_CPU_LITTLE_ENDIAN
112 ! 6 cycles, 4 bytes per iteration
1133: mov.l @(r0,r5),r1 ! 21 LS (latency=2) ! NMLK
114 mov r7, r3 ! 5 MT (latency=0) ! RQPO
115
116 cmp/hi r2,r0 ! 57 MT
117 shll8 r3 ! 102 EX ! QPOx
118
119 mov r1,r6 ! 5 MT (latency=0)
120 shlr16 r6 ! 107 EX
121
122 shlr8 r6 ! 106 EX ! xxxN
123 mov r1, r7 ! 5 MT (latency=0)
124
125 or r6,r3 ! 82 EX ! QPON
126 bt/s 3b ! 109 BR
127
128 mov.l r3,@-r0 ! 30 LS
129#else
1303: mov r1,r3 ! OPQR
131 shlr8 r3 ! xOPQ
132 mov.l @(r0,r5),r1 ! KLMN
133 mov r1,r6
134 shll16 r6
135 shll8 r6 ! Nxxx
136 or r6,r3 ! NOPQ
137 cmp/hi r2,r0
138 bt/s 3b
139 mov.l r3,@-r0
140#endif
141
142 ! Finally, copy a byte at once, if necessary
143
144 add #6,r5 ! 50 EX
145 cmp/eq r4,r0 ! 54 MT
146
147 add #-6,r2 ! 50 EX
148 bt 9f ! 109 BR
149
1508: cmp/hi r2,r0 ! 57 MT
151 mov.b @(r0,r5),r1 ! 20 LS (latency=2)
152
153 bt/s 8b ! 109 BR
154
155 mov.b r1,@-r0 ! 29 LS
156
1579: rts
158 nop
159
160ENTRY(memcpy)
161
162 ! Calculate the invariants which will be used in the remainder
163 ! of the code:
164 !
165 ! r4 --> [ ... ] DST [ ... ] SRC
166 ! [ ... ] [ ... ]
167 ! : :
168 ! r0 --> [ ... ] r0+r5 --> [ ... ]
169 !
170 !
171
172 ! Short circuit the common case of src, dst and len being 32 bit aligned
173 ! and test for zero length move
174
175 mov r6, r0 ! 5 MT (0 cycle latency)
176 or r4, r0 ! 82 EX
177
178 or r5, r0 ! 82 EX
179 tst r6, r6 ! 86 MT
180
181 bt/s 99f ! 111 BR (zero len)
182 tst #3, r0 ! 87 MT
183
184 mov r4, r0 ! 5 MT (0 cycle latency)
185 add r6, r0 ! 49 EX
186
187 mov #16, r1 ! 6 EX
188 bt/s .Lcase00 ! 111 BR (aligned)
189
190 sub r4, r5 ! 75 EX
191
192 ! Arguments are not nicely long word aligned or zero len.
193 ! Check for small copies, and if so do a simple byte at a time copy.
194 !
195 ! Deciding on an exact value of 'small' is not easy, as the point at which
196 ! using the optimised routines become worthwhile varies (these are the
197 ! cycle counts for differnet sizes using byte-at-a-time vs. optimised):
198 ! size byte-at-time long word byte
199 ! 16 42 39-40 46-50 50-55
200 ! 24 58 43-44 54-58 62-67
201 ! 36 82 49-50 66-70 80-85
202 ! However the penalty for getting it 'wrong' is much higher for long word
203 ! aligned data (and this is more common), so use a value of 16.
204
205 cmp/gt r6,r1 ! 56 MT
206
207 add #-1,r5 ! 50 EX
208 bf/s 6f ! 108 BR (not small)
209
210 mov r5, r3 ! 5 MT (latency=0)
211 shlr r6 ! 104 EX
212
213 mov.b @(r0,r5),r1 ! 20 LS (latency=2)
214 bf/s 4f ! 111 BR
215
216 add #-1,r3 ! 50 EX
217 tst r6, r6 ! 86 MT
218
219 bt/s 98f ! 110 BR
220 mov.b r1,@-r0 ! 29 LS
221
222 ! 4 cycles, 2 bytes per iteration
2233: mov.b @(r0,r5),r1 ! 20 LS (latency=2)
224
2254: mov.b @(r0,r3),r2 ! 20 LS (latency=2)
226 dt r6 ! 67 EX
227
228 mov.b r1,@-r0 ! 29 LS
229 bf/s 3b ! 111 BR
230
231 mov.b r2,@-r0 ! 29 LS
23298:
233 rts
234 nop
235
23699: rts
237 mov r4, r0
238
239 ! Size is not small, so its worthwhile looking for optimisations.
240 ! First align destination to a long word boundary.
241 !
242 ! r5 = normal value -1
243
2446: tst #3, r0 ! 87 MT
245 mov #3, r3 ! 6 EX
246
247 bt/s 2f ! 111 BR
248 and r0,r3 ! 78 EX
249
250 ! 3 cycles, 1 byte per iteration
2511: dt r3 ! 67 EX
252 mov.b @(r0,r5),r1 ! 19 LS (latency=2)
253
254 add #-1, r6 ! 79 EX
255 bf/s 1b ! 109 BR
256
257 mov.b r1,@-r0 ! 28 LS
258
2592: add #1, r5 ! 79 EX
260
261 ! Now select the appropriate bulk transfer code based on relative
262 ! alignment of src and dst.
263
264 mov r0, r3 ! 5 MT (latency=0)
265
266 mov r5, r0 ! 5 MT (latency=0)
267 tst #1, r0 ! 87 MT
268
269 bf/s 1f ! 111 BR
270 mov #64, r7 ! 6 EX
271
272 ! bit 0 clear
273
274 cmp/ge r7, r6 ! 55 MT
275
276 bt/s 2f ! 111 BR
277 tst #2, r0 ! 87 MT
278
279 ! small
280 bt/s .Lcase0
281 mov r3, r0
282
283 bra .Lcase2
284 nop
285
286 ! big
2872: bt/s .Lcase0b
288 mov r3, r0
289
290 bra .Lcase2b
291 nop
292
293 ! bit 0 set
2941: tst #2, r0 ! 87 MT
295
296 bt/s .Lcase1
297 mov r3, r0
298
299 bra .Lcase3
300 nop
301
302
303 !
304 ! GHIJ KLMN OPQR --> GHIJ KLMN OPQR
305 !
306
307 ! src, dst and size are all long word aligned
308 ! size is non-zero
309
310 .balign 32
311.Lcase00:
312 mov #64, r1 ! 6 EX
313 mov r5, r3 ! 5 MT (latency=0)
314
315 cmp/gt r6, r1 ! 56 MT
316 add #-4, r5 ! 50 EX
317
318 bf .Lcase00b ! 108 BR (big loop)
319 shlr2 r6 ! 105 EX
320
321 shlr r6 ! 104 EX
322 mov.l @(r0, r5), r1 ! 21 LS (latency=2)
323
324 bf/s 4f ! 111 BR
325 add #-8, r3 ! 50 EX
326
327 tst r6, r6 ! 86 MT
328 bt/s 5f ! 110 BR
329
330 mov.l r1,@-r0 ! 30 LS
331
332 ! 4 cycles, 2 long words per iteration
3333: mov.l @(r0, r5), r1 ! 21 LS (latency=2)
334
3354: mov.l @(r0, r3), r2 ! 21 LS (latency=2)
336 dt r6 ! 67 EX
337
338 mov.l r1, @-r0 ! 30 LS
339 bf/s 3b ! 109 BR
340
341 mov.l r2, @-r0 ! 30 LS
342
3435: rts
344 nop
345
346
347 ! Size is 16 or greater and less than 64, but may have trailing bytes
348
349 .balign 32
350.Lcase0:
351 add #-4, r5 ! 50 EX
352 mov r4, r7 ! 5 MT (latency=0)
353
354 mov.l @(r0, r5), r1 ! 21 LS (latency=2)
355 mov #4, r2 ! 6 EX
356
357 add #11, r7 ! 50 EX
358 tst r2, r6 ! 86 MT
359
360 mov r5, r3 ! 5 MT (latency=0)
361 bt/s 4f ! 111 BR
362
363 add #-4, r3 ! 50 EX
364 mov.l r1,@-r0 ! 30 LS
365
366 ! 4 cycles, 2 long words per iteration
3673: mov.l @(r0, r5), r1 ! 21 LS (latency=2)
368
3694: mov.l @(r0, r3), r2 ! 21 LS (latency=2)
370 cmp/hi r7, r0
371
372 mov.l r1, @-r0 ! 30 LS
373 bt/s 3b ! 109 BR
374
375 mov.l r2, @-r0 ! 30 LS
376
377 ! Copy the final 0-3 bytes
378
379 add #3,r5 ! 50 EX
380
381 cmp/eq r0, r4 ! 54 MT
382 add #-10, r7 ! 50 EX
383
384 bt 9f ! 110 BR
385
386 ! 3 cycles, 1 byte per iteration
3871: mov.b @(r0,r5),r1 ! 19 LS
388 cmp/hi r7,r0 ! 57 MT
389
390 bt/s 1b ! 111 BR
391 mov.b r1,@-r0 ! 28 LS
392
3939: rts
394 nop
395
396 ! Size is at least 64 bytes, so will be going round the big loop at least once.
397 !
398 ! r2 = rounded up r4
399 ! r3 = rounded down r0
400
401 .balign 32
402.Lcase0b:
403 add #-4, r5 ! 50 EX
404
405.Lcase00b:
406 mov r0, r3 ! 5 MT (latency=0)
407 mov #(~0x1f), r1 ! 6 EX
408
409 and r1, r3 ! 78 EX
410 mov r4, r2 ! 5 MT (latency=0)
411
412 cmp/eq r3, r0 ! 54 MT
413 add #0x1f, r2 ! 50 EX
414
415 bt/s 1f ! 110 BR
416 and r1, r2 ! 78 EX
417
418 ! copy initial words until cache line aligned
419
420 mov.l @(r0, r5), r1 ! 21 LS (latency=2)
421 tst #4, r0 ! 87 MT
422
423 mov r5, r6 ! 5 MT (latency=0)
424 add #-4, r6 ! 50 EX
425
426 bt/s 4f ! 111 BR
427 add #8, r3 ! 50 EX
428
429 tst #0x18, r0 ! 87 MT
430
431 bt/s 1f ! 109 BR
432 mov.l r1,@-r0 ! 30 LS
433
434 ! 4 cycles, 2 long words per iteration
4353: mov.l @(r0, r5), r1 ! 21 LS (latency=2)
436
4374: mov.l @(r0, r6), r7 ! 21 LS (latency=2)
438 cmp/eq r3, r0 ! 54 MT
439
440 mov.l r1, @-r0 ! 30 LS
441 bf/s 3b ! 109 BR
442
443 mov.l r7, @-r0 ! 30 LS
444
445 ! Copy the cache line aligned blocks
446 !
447 ! In use: r0, r2, r4, r5
448 ! Scratch: r1, r3, r6, r7
449 !
450 ! We could do this with the four scratch registers, but if src
451 ! and dest hit the same cache line, this will thrash, so make
452 ! use of additional registers.
453 !
454 ! We also need r0 as a temporary (for movca), so 'undo' the invariant:
455 ! r5: src (was r0+r5)
456 ! r1: dest (was r0)
457 ! this can be reversed at the end, so we don't need to save any extra
458 ! state.
459 !
4601: mov.l r8, @-r15 ! 30 LS
461 add r0, r5 ! 49 EX
462
463 mov.l r9, @-r15 ! 30 LS
464 mov r0, r1 ! 5 MT (latency=0)
465
466 mov.l r10, @-r15 ! 30 LS
467 add #-0x1c, r5 ! 50 EX
468
469 mov.l r11, @-r15 ! 30 LS
470
471 ! 16 cycles, 32 bytes per iteration
4722: mov.l @(0x00,r5),r0 ! 18 LS (latency=2)
473 add #-0x20, r1 ! 50 EX
474 mov.l @(0x04,r5),r3 ! 18 LS (latency=2)
475 mov.l @(0x08,r5),r6 ! 18 LS (latency=2)
476 mov.l @(0x0c,r5),r7 ! 18 LS (latency=2)
477 mov.l @(0x10,r5),r8 ! 18 LS (latency=2)
478 mov.l @(0x14,r5),r9 ! 18 LS (latency=2)
479 mov.l @(0x18,r5),r10 ! 18 LS (latency=2)
480 mov.l @(0x1c,r5),r11 ! 18 LS (latency=2)
481 movca.l r0,@r1 ! 40 LS (latency=3-7)
482 mov.l r3,@(0x04,r1) ! 33 LS
483 mov.l r6,@(0x08,r1) ! 33 LS
484 mov.l r7,@(0x0c,r1) ! 33 LS
485
486 mov.l r8,@(0x10,r1) ! 33 LS
487 add #-0x20, r5 ! 50 EX
488
489 mov.l r9,@(0x14,r1) ! 33 LS
490 cmp/eq r2,r1 ! 54 MT
491
492 mov.l r10,@(0x18,r1) ! 33 LS
493 bf/s 2b ! 109 BR
494
495 mov.l r11,@(0x1c,r1) ! 33 LS
496
497 mov r1, r0 ! 5 MT (latency=0)
498
499 mov.l @r15+, r11 ! 15 LS
500 sub r1, r5 ! 75 EX
501
502 mov.l @r15+, r10 ! 15 LS
503 cmp/eq r4, r0 ! 54 MT
504
505 bf/s 1f ! 109 BR
506 mov.l @r15+, r9 ! 15 LS
507
508 rts
5091: mov.l @r15+, r8 ! 15 LS
510 sub r4, r1 ! 75 EX (len remaining)
511
512 ! number of trailing bytes is non-zero
513 !
514 ! invariants restored (r5 already decremented by 4)
515 ! also r1=num bytes remaining
516
517 mov #4, r2 ! 6 EX
518 mov r4, r7 ! 5 MT (latency=0)
519
520 add #0x1c, r5 ! 50 EX (back to -4)
521 cmp/hs r2, r1 ! 58 MT
522
523 bf/s 5f ! 108 BR
524 add #11, r7 ! 50 EX
525
526 mov.l @(r0, r5), r6 ! 21 LS (latency=2)
527 tst r2, r1 ! 86 MT
528
529 mov r5, r3 ! 5 MT (latency=0)
530 bt/s 4f ! 111 BR
531
532 add #-4, r3 ! 50 EX
533 cmp/hs r2, r1 ! 58 MT
534
535 bt/s 5f ! 111 BR
536 mov.l r6,@-r0 ! 30 LS
537
538 ! 4 cycles, 2 long words per iteration
5393: mov.l @(r0, r5), r6 ! 21 LS (latency=2)
540
5414: mov.l @(r0, r3), r2 ! 21 LS (latency=2)
542 cmp/hi r7, r0
543
544 mov.l r6, @-r0 ! 30 LS
545 bt/s 3b ! 109 BR
546
547 mov.l r2, @-r0 ! 30 LS
548
549 ! Copy the final 0-3 bytes
550
5515: cmp/eq r0, r4 ! 54 MT
552 add #-10, r7 ! 50 EX
553
554 bt 9f ! 110 BR
555 add #3,r5 ! 50 EX
556
557 ! 3 cycles, 1 byte per iteration
5581: mov.b @(r0,r5),r1 ! 19 LS
559 cmp/hi r7,r0 ! 57 MT
560
561 bt/s 1b ! 111 BR
562 mov.b r1,@-r0 ! 28 LS
563
5649: rts
565 nop
566
567 !
568 ! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR..
569 !
570
571 .balign 32
572.Lcase2:
573 ! Size is 16 or greater and less then 64, but may have trailing bytes
574
5752: mov r5, r6 ! 5 MT (latency=0)
576 add #-2,r5 ! 50 EX
577
578 mov r4,r2 ! 5 MT (latency=0)
579 add #-4,r6 ! 50 EX
580
581 add #7,r2 ! 50 EX
5823: mov.w @(r0,r5),r1 ! 20 LS (latency=2)
583
584 mov.w @(r0,r6),r3 ! 20 LS (latency=2)
585 cmp/hi r2,r0 ! 57 MT
586
587 mov.w r1,@-r0 ! 29 LS
588 bt/s 3b ! 111 BR
589
590 mov.w r3,@-r0 ! 29 LS
591
592 bra 10f
593 nop
594
595
596 .balign 32
597.Lcase2b:
598 ! Size is at least 64 bytes, so will be going round the big loop at least once.
599 !
600 ! r2 = rounded up r4
601 ! r3 = rounded down r0
602
603 mov r0, r3 ! 5 MT (latency=0)
604 mov #(~0x1f), r1 ! 6 EX
605
606 and r1, r3 ! 78 EX
607 mov r4, r2 ! 5 MT (latency=0)
608
609 cmp/eq r3, r0 ! 54 MT
610 add #0x1f, r2 ! 50 EX
611
612 add #-2, r5 ! 50 EX
613 bt/s 1f ! 110 BR
614 and r1, r2 ! 78 EX
615
616 ! Copy a short word one at a time until we are cache line aligned
617 ! Normal values: r0, r2, r3, r4
618 ! Unused: r1, r6, r7
619 ! Mod: r5 (=r5-2)
620 !
621 add #2, r3 ! 50 EX
622
6232: mov.w @(r0,r5),r1 ! 20 LS (latency=2)
624 cmp/eq r3,r0 ! 54 MT
625
626 bf/s 2b ! 111 BR
627
628 mov.w r1,@-r0 ! 29 LS
629
630 ! Copy the cache line aligned blocks
631 !
632 ! In use: r0, r2, r4, r5 (=r5-2)
633 ! Scratch: r1, r3, r6, r7
634 !
635 ! We could do this with the four scratch registers, but if src
636 ! and dest hit the same cache line, this will thrash, so make
637 ! use of additional registers.
638 !
639 ! We also need r0 as a temporary (for movca), so 'undo' the invariant:
640 ! r5: src (was r0+r5)
641 ! r1: dest (was r0)
642 ! this can be reversed at the end, so we don't need to save any extra
643 ! state.
644 !
6451: mov.l r8, @-r15 ! 30 LS
646 add r0, r5 ! 49 EX
647
648 mov.l r9, @-r15 ! 30 LS
649 mov r0, r1 ! 5 MT (latency=0)
650
651 mov.l r10, @-r15 ! 30 LS
652 add #-0x1e, r5 ! 50 EX
653
654 mov.l r11, @-r15 ! 30 LS
655
656 mov.l r12, @-r15 ! 30 LS
657
658 ! 17 cycles, 32 bytes per iteration
659#ifdef CONFIG_CPU_LITTLE_ENDIAN
6602: mov.w @r5+, r0 ! 14 LS (latency=2) ..JI
661 add #-0x20, r1 ! 50 EX
662
663 mov.l @r5+, r3 ! 15 LS (latency=2) NMLK
664
665 mov.l @r5+, r6 ! 15 LS (latency=2) RQPO
666 shll16 r0 ! 103 EX JI..
667
668 mov.l @r5+, r7 ! 15 LS (latency=2)
669 xtrct r3, r0 ! 48 EX LKJI
670
671 mov.l @r5+, r8 ! 15 LS (latency=2)
672 xtrct r6, r3 ! 48 EX PONM
673
674 mov.l @r5+, r9 ! 15 LS (latency=2)
675 xtrct r7, r6 ! 48 EX
676
677 mov.l @r5+, r10 ! 15 LS (latency=2)
678 xtrct r8, r7 ! 48 EX
679
680 mov.l @r5+, r11 ! 15 LS (latency=2)
681 xtrct r9, r8 ! 48 EX
682
683 mov.w @r5+, r12 ! 15 LS (latency=2)
684 xtrct r10, r9 ! 48 EX
685
686 movca.l r0,@r1 ! 40 LS (latency=3-7)
687 xtrct r11, r10 ! 48 EX
688
689 mov.l r3, @(0x04,r1) ! 33 LS
690 xtrct r12, r11 ! 48 EX
691
692 mov.l r6, @(0x08,r1) ! 33 LS
693
694 mov.l r7, @(0x0c,r1) ! 33 LS
695
696 mov.l r8, @(0x10,r1) ! 33 LS
697 add #-0x40, r5 ! 50 EX
698
699 mov.l r9, @(0x14,r1) ! 33 LS
700 cmp/eq r2,r1 ! 54 MT
701
702 mov.l r10, @(0x18,r1) ! 33 LS
703 bf/s 2b ! 109 BR
704
705 mov.l r11, @(0x1c,r1) ! 33 LS
706#else
7072: mov.w @(0x1e,r5), r0 ! 17 LS (latency=2)
708 add #-2, r5 ! 50 EX
709
710 mov.l @(0x1c,r5), r3 ! 18 LS (latency=2)
711 add #-4, r1 ! 50 EX
712
713 mov.l @(0x18,r5), r6 ! 18 LS (latency=2)
714 shll16 r0 ! 103 EX
715
716 mov.l @(0x14,r5), r7 ! 18 LS (latency=2)
717 xtrct r3, r0 ! 48 EX
718
719 mov.l @(0x10,r5), r8 ! 18 LS (latency=2)
720 xtrct r6, r3 ! 48 EX
721
722 mov.l @(0x0c,r5), r9 ! 18 LS (latency=2)
723 xtrct r7, r6 ! 48 EX
724
725 mov.l @(0x08,r5), r10 ! 18 LS (latency=2)
726 xtrct r8, r7 ! 48 EX
727
728 mov.l @(0x04,r5), r11 ! 18 LS (latency=2)
729 xtrct r9, r8 ! 48 EX
730
731 mov.w @(0x02,r5), r12 ! 18 LS (latency=2)
732 xtrct r10, r9 ! 48 EX
733
734 movca.l r0,@r1 ! 40 LS (latency=3-7)
735 add #-0x1c, r1 ! 50 EX
736
737 mov.l r3, @(0x1c,r1) ! 33 LS
738 xtrct r11, r10 ! 48 EX
739
740 mov.l r6, @(0x18,r1) ! 33 LS
741 xtrct r12, r11 ! 48 EX
742
743 mov.l r7, @(0x14,r1) ! 33 LS
744
745 mov.l r8, @(0x10,r1) ! 33 LS
746 add #-0x3e, r5 ! 50 EX
747
748 mov.l r9, @(0x0c,r1) ! 33 LS
749 cmp/eq r2,r1 ! 54 MT
750
751 mov.l r10, @(0x08,r1) ! 33 LS
752 bf/s 2b ! 109 BR
753
754 mov.l r11, @(0x04,r1) ! 33 LS
755#endif
756
757 mov.l @r15+, r12
758 mov r1, r0 ! 5 MT (latency=0)
759
760 mov.l @r15+, r11 ! 15 LS
761 sub r1, r5 ! 75 EX
762
763 mov.l @r15+, r10 ! 15 LS
764 cmp/eq r4, r0 ! 54 MT
765
766 bf/s 1f ! 109 BR
767 mov.l @r15+, r9 ! 15 LS
768
769 rts
7701: mov.l @r15+, r8 ! 15 LS
771
772 add #0x1e, r5 ! 50 EX
773
774 ! Finish off a short word at a time
775 ! r5 must be invariant - 2
77610: mov r4,r2 ! 5 MT (latency=0)
777 add #1,r2 ! 50 EX
778
779 cmp/hi r2, r0 ! 57 MT
780 bf/s 1f ! 109 BR
781
782 add #2, r2 ! 50 EX
783
7843: mov.w @(r0,r5),r1 ! 20 LS
785 cmp/hi r2,r0 ! 57 MT
786
787 bt/s 3b ! 109 BR
788
789 mov.w r1,@-r0 ! 29 LS
7901:
791
792 !
793 ! Finally, copy the last byte if necessary
794 cmp/eq r4,r0 ! 54 MT
795 bt/s 9b
796 add #1,r5
797 mov.b @(r0,r5),r1
798 rts
799 mov.b r1,@-r0
800
diff --git a/arch/sh/lib/memcpy.S b/arch/sh/lib/memcpy.S
new file mode 100644
index 000000000000..232fab34c261
--- /dev/null
+++ b/arch/sh/lib/memcpy.S
@@ -0,0 +1,227 @@
1/* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
2 *
3 * "memcpy" implementation of SuperH
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 *
7 */
8
9/*
10 * void *memcpy(void *dst, const void *src, size_t n);
11 * No overlap between the memory of DST and of SRC are assumed.
12 */
13
14#include <linux/linkage.h>
15ENTRY(memcpy)
16 tst r6,r6
17 bt/s 9f ! if n=0, do nothing
18 mov r4,r0
19 sub r4,r5 ! From here, r5 has the distance to r0
20 add r6,r0 ! From here, r0 points the end of copying point
21 mov #12,r1
22 cmp/gt r6,r1
23 bt/s 7f ! if it's too small, copy a byte at once
24 add #-1,r5
25 add #1,r5
26 ! From here, r6 is free
27 !
28 ! r4 --> [ ... ] DST [ ... ] SRC
29 ! [ ... ] [ ... ]
30 ! : :
31 ! r0 --> [ ... ] r0+r5 --> [ ... ]
32 !
33 !
34 mov r5,r1
35 mov #3,r2
36 and r2,r1
37 shll2 r1
38 mov r0,r3 ! Save the value on R0 to R3
39 mova jmptable,r0
40 add r1,r0
41 mov.l @r0,r1
42 jmp @r1
43 mov r3,r0 ! and back to R0
44 .balign 4
45jmptable:
46 .long case0
47 .long case1
48 .long case2
49 .long case3
50
51 ! copy a byte at once
527: mov r4,r2
53 add #1,r2
548:
55 cmp/hi r2,r0
56 mov.b @(r0,r5),r1
57 bt/s 8b ! while (r0>r2)
58 mov.b r1,@-r0
599:
60 rts
61 nop
62
63case0:
64 !
65 ! GHIJ KLMN OPQR --> GHIJ KLMN OPQR
66 !
67 ! First, align to long word boundary
68 mov r0,r3
69 and r2,r3
70 tst r3,r3
71 bt/s 2f
72 add #-4,r5
73 add #3,r5
741: dt r3
75 mov.b @(r0,r5),r1
76 bf/s 1b
77 mov.b r1,@-r0
78 !
79 add #-3,r5
802: ! Second, copy a long word at once
81 mov r4,r2
82 add #7,r2
833: mov.l @(r0,r5),r1
84 cmp/hi r2,r0
85 bt/s 3b
86 mov.l r1,@-r0
87 !
88 ! Third, copy a byte at once, if necessary
89 cmp/eq r4,r0
90 bt/s 9b
91 add #3,r5
92 bra 8b
93 add #-6,r2
94
95case1:
96 !
97 ! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR.
98 !
99 ! First, align to long word boundary
100 mov r0,r3
101 and r2,r3
102 tst r3,r3
103 bt/s 2f
104 add #-1,r5
1051: dt r3
106 mov.b @(r0,r5),r1
107 bf/s 1b
108 mov.b r1,@-r0
109 !
1102: ! Second, read a long word and write a long word at once
111 mov.l @(r0,r5),r1
112 add #-4,r5
113 mov r4,r2
114 add #7,r2
115 !
116#ifdef __LITTLE_ENDIAN__
1173: mov r1,r3 ! RQPO
118 shll16 r3
119 shll8 r3 ! Oxxx
120 mov.l @(r0,r5),r1 ! NMLK
121 mov r1,r6
122 shlr8 r6 ! xNML
123 or r6,r3 ! ONML
124 cmp/hi r2,r0
125 bt/s 3b
126 mov.l r3,@-r0
127#else
1283: mov r1,r3 ! OPQR
129 shlr16 r3
130 shlr8 r3 ! xxxO
131 mov.l @(r0,r5),r1 ! KLMN
132 mov r1,r6
133 shll8 r6 ! LMNx
134 or r6,r3 ! LMNO
135 cmp/hi r2,r0
136 bt/s 3b
137 mov.l r3,@-r0
138#endif
139 !
140 ! Third, copy a byte at once, if necessary
141 cmp/eq r4,r0
142 bt/s 9b
143 add #4,r5
144 bra 8b
145 add #-6,r2
146
147case2:
148 !
149 ! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR..
150 !
151 ! First, align to word boundary
152 tst #1,r0
153 bt/s 2f
154 add #-1,r5
155 mov.b @(r0,r5),r1
156 mov.b r1,@-r0
157 !
1582: ! Second, read a word and write a word at once
159 add #-1,r5
160 mov r4,r2
161 add #3,r2
162 !
1633: mov.w @(r0,r5),r1
164 cmp/hi r2,r0
165 bt/s 3b
166 mov.w r1,@-r0
167 !
168 ! Third, copy a byte at once, if necessary
169 cmp/eq r4,r0
170 bt/s 9b
171 add #1,r5
172 mov.b @(r0,r5),r1
173 rts
174 mov.b r1,@-r0
175
176case3:
177 !
178 ! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R...
179 !
180 ! First, align to long word boundary
181 mov r0,r3
182 and r2,r3
183 tst r3,r3
184 bt/s 2f
185 add #-1,r5
1861: dt r3
187 mov.b @(r0,r5),r1
188 bf/s 1b
189 mov.b r1,@-r0
190 !
1912: ! Second, read a long word and write a long word at once
192 add #-2,r5
193 mov.l @(r0,r5),r1
194 add #-4,r5
195 mov r4,r2
196 add #7,r2
197 !
198#ifdef __LITTLE_ENDIAN__
1993: mov r1,r3 ! RQPO
200 shll8 r3 ! QPOx
201 mov.l @(r0,r5),r1 ! NMLK
202 mov r1,r6
203 shlr16 r6
204 shlr8 r6 ! xxxN
205 or r6,r3 ! QPON
206 cmp/hi r2,r0
207 bt/s 3b
208 mov.l r3,@-r0
209#else
2103: mov r1,r3 ! OPQR
211 shlr8 r3 ! xOPQ
212 mov.l @(r0,r5),r1 ! KLMN
213 mov r1,r6
214 shll16 r6
215 shll8 r6 ! Nxxx
216 or r6,r3 ! NOPQ
217 cmp/hi r2,r0
218 bt/s 3b
219 mov.l r3,@-r0
220#endif
221 !
222 ! Third, copy a byte at once, if necessary
223 cmp/eq r4,r0
224 bt/s 9b
225 add #6,r5
226 bra 8b
227 add #-6,r2
diff --git a/arch/sh/lib/memmove.S b/arch/sh/lib/memmove.S
new file mode 100644
index 000000000000..5a2211f09202
--- /dev/null
+++ b/arch/sh/lib/memmove.S
@@ -0,0 +1,254 @@
1/* $Id: memmove.S,v 1.2 2001/07/27 11:51:09 gniibe Exp $
2 *
3 * "memmove" implementation of SuperH
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 *
7 */
8
9/*
10 * void *memmove(void *dst, const void *src, size_t n);
11 * The memory areas may overlap.
12 */
13
14#include <linux/linkage.h>
15ENTRY(memmove)
16 ! if dest > src, call memcpy (it copies in decreasing order)
17 cmp/hi r5,r4
18 bf 1f
19 mov.l 2f,r0
20 jmp @r0
21 nop
22 .balign 4
232: .long memcpy
241:
25 sub r5,r4 ! From here, r4 has the distance to r0
26 tst r6,r6
27 bt/s 9f ! if n=0, do nothing
28 mov r5,r0
29 add r6,r5
30 mov #12,r1
31 cmp/gt r6,r1
32 bt/s 8f ! if it's too small, copy a byte at once
33 add #-1,r4
34 add #1,r4
35 !
36 ! [ ... ] DST [ ... ] SRC
37 ! [ ... ] [ ... ]
38 ! : :
39 ! r0+r4--> [ ... ] r0 --> [ ... ]
40 ! : :
41 ! [ ... ] [ ... ]
42 ! r5 -->
43 !
44 mov r4,r1
45 mov #3,r2
46 and r2,r1
47 shll2 r1
48 mov r0,r3 ! Save the value on R0 to R3
49 mova jmptable,r0
50 add r1,r0
51 mov.l @r0,r1
52 jmp @r1
53 mov r3,r0 ! and back to R0
54 .balign 4
55jmptable:
56 .long case0
57 .long case1
58 .long case2
59 .long case3
60
61 ! copy a byte at once
628: mov.b @r0+,r1
63 cmp/hs r5,r0
64 bf/s 8b ! while (r0<r5)
65 mov.b r1,@(r0,r4)
66 add #1,r4
679:
68 add r4,r0
69 rts
70 sub r6,r0
71
72case_none:
73 bra 8b
74 add #-1,r4
75
76case0:
77 !
78 ! GHIJ KLMN OPQR --> GHIJ KLMN OPQR
79 !
80 ! First, align to long word boundary
81 mov r0,r3
82 and r2,r3
83 tst r3,r3
84 bt/s 2f
85 add #-1,r4
86 mov #4,r2
87 sub r3,r2
881: dt r2
89 mov.b @r0+,r1
90 bf/s 1b
91 mov.b r1,@(r0,r4)
92 !
932: ! Second, copy a long word at once
94 add #-3,r4
95 add #-3,r5
963: mov.l @r0+,r1
97 cmp/hs r5,r0
98 bf/s 3b
99 mov.l r1,@(r0,r4)
100 add #3,r5
101 !
102 ! Third, copy a byte at once, if necessary
103 cmp/eq r5,r0
104 bt/s 9b
105 add #4,r4
106 bra 8b
107 add #-1,r4
108
109case3:
110 !
111 ! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR.
112 !
113 ! First, align to long word boundary
114 mov r0,r3
115 and r2,r3
116 tst r3,r3
117 bt/s 2f
118 add #-1,r4
119 mov #4,r2
120 sub r3,r2
1211: dt r2
122 mov.b @r0+,r1
123 bf/s 1b
124 mov.b r1,@(r0,r4)
125 !
1262: ! Second, read a long word and write a long word at once
127 add #-2,r4
128 mov.l @(r0,r4),r1
129 add #-7,r5
130 add #-4,r4
131 !
132#ifdef __LITTLE_ENDIAN__
133 shll8 r1
1343: mov r1,r3 ! JIHG
135 shlr8 r3 ! xJIH
136 mov.l @r0+,r1 ! NMLK
137 mov r1,r2
138 shll16 r2
139 shll8 r2 ! Kxxx
140 or r2,r3 ! KJIH
141 cmp/hs r5,r0
142 bf/s 3b
143 mov.l r3,@(r0,r4)
144#else
145 shlr8 r1
1463: mov r1,r3 ! GHIJ
147 shll8 r3 ! HIJx
148 mov.l @r0+,r1 ! KLMN
149 mov r1,r2
150 shlr16 r2
151 shlr8 r2 ! xxxK
152 or r2,r3 ! HIJK
153 cmp/hs r5,r0
154 bf/s 3b
155 mov.l r3,@(r0,r4)
156#endif
157 add #7,r5
158 !
159 ! Third, copy a byte at once, if necessary
160 cmp/eq r5,r0
161 bt/s 9b
162 add #7,r4
163 add #-3,r0
164 bra 8b
165 add #-1,r4
166
167case2:
168 !
169 ! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR..
170 !
171 ! First, align to word boundary
172 tst #1,r0
173 bt/s 2f
174 add #-1,r4
175 mov.b @r0+,r1
176 mov.b r1,@(r0,r4)
177 !
1782: ! Second, read a word and write a word at once
179 add #-1,r4
180 add #-1,r5
181 !
1823: mov.w @r0+,r1
183 cmp/hs r5,r0
184 bf/s 3b
185 mov.w r1,@(r0,r4)
186 add #1,r5
187 !
188 ! Third, copy a byte at once, if necessary
189 cmp/eq r5,r0
190 bt/s 9b
191 add #2,r4
192 mov.b @r0,r1
193 mov.b r1,@(r0,r4)
194 bra 9b
195 add #1,r0
196
197case1:
198 !
199 ! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R...
200 !
201 ! First, align to long word boundary
202 mov r0,r3
203 and r2,r3
204 tst r3,r3
205 bt/s 2f
206 add #-1,r4
207 mov #4,r2
208 sub r3,r2
2091: dt r2
210 mov.b @r0+,r1
211 bf/s 1b
212 mov.b r1,@(r0,r4)
213 !
2142: ! Second, read a long word and write a long word at once
215 mov.l @(r0,r4),r1
216 add #-7,r5
217 add #-4,r4
218 !
219#ifdef __LITTLE_ENDIAN__
220 shll16 r1
221 shll8 r1
2223: mov r1,r3 ! JIHG
223 shlr16 r3
224 shlr8 r3 ! xxxJ
225 mov.l @r0+,r1 ! NMLK
226 mov r1,r2
227 shll8 r2 ! MLKx
228 or r2,r3 ! MLKJ
229 cmp/hs r5,r0
230 bf/s 3b
231 mov.l r3,@(r0,r4)
232#else
233 shlr16 r1
234 shlr8 r1
2353: mov r1,r3 ! GHIJ
236 shll16 r3
237 shll8 r3 ! Jxxx
238 mov.l @r0+,r1 ! KLMN
239 mov r1,r2
240 shlr8 r2 ! xKLM
241 or r2,r3 ! JKLM
242 cmp/hs r5,r0
243 bf/s 3b ! while(r0<r5)
244 mov.l r3,@(r0,r4)
245#endif
246 add #7,r5
247 !
248 ! Third, copy a byte at once, if necessary
249 cmp/eq r5,r0
250 bt/s 9b
251 add #5,r4
252 add #-3,r0
253 bra 8b
254 add #-1,r4
diff --git a/arch/sh/lib/memset.S b/arch/sh/lib/memset.S
new file mode 100644
index 000000000000..95670090680e
--- /dev/null
+++ b/arch/sh/lib/memset.S
@@ -0,0 +1,57 @@
1/* $Id: memset.S,v 1.1 2000/04/14 16:49:01 mjd Exp $
2 *
3 * "memset" implementation of SuperH
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 *
7 */
8
9/*
10 * void *memset(void *s, int c, size_t n);
11 */
12
13#include <linux/linkage.h>
14
15ENTRY(memset)
16 tst r6,r6
17 bt/s 5f ! if n=0, do nothing
18 add r6,r4
19 mov #12,r0
20 cmp/gt r6,r0
21 bt/s 4f ! if it's too small, set a byte at once
22 mov r4,r0
23 and #3,r0
24 cmp/eq #0,r0
25 bt/s 2f ! It's aligned
26 sub r0,r6
271:
28 dt r0
29 bf/s 1b
30 mov.b r5,@-r4
312: ! make VVVV
32 swap.b r5,r0 ! V0
33 or r0,r5 ! VV
34 swap.w r5,r0 ! VV00
35 or r0,r5 ! VVVV
36 !
37 mov r6,r0
38 shlr2 r0
39 shlr r0 ! r0 = r6 >> 3
403:
41 dt r0
42 mov.l r5,@-r4 ! set 8-byte at once
43 bf/s 3b
44 mov.l r5,@-r4
45 !
46 mov #7,r0
47 and r0,r6
48 tst r6,r6
49 bt 5f
50 ! fill bytes
514:
52 dt r6
53 bf/s 4b
54 mov.b r5,@-r4
555:
56 rts
57 mov r4,r0
diff --git a/arch/sh/lib/strcasecmp.c b/arch/sh/lib/strcasecmp.c
new file mode 100644
index 000000000000..4e57a216feaf
--- /dev/null
+++ b/arch/sh/lib/strcasecmp.c
@@ -0,0 +1,26 @@
1/*
2 * linux/arch/alpha/lib/strcasecmp.c
3 */
4
5#include <linux/string.h>
6
7
8/* We handle nothing here except the C locale. Since this is used in
9 only one place, on strings known to contain only 7 bit ASCII, this
10 is ok. */
11
12int strcasecmp(const char *a, const char *b)
13{
14 int ca, cb;
15
16 do {
17 ca = *a++ & 0xff;
18 cb = *b++ & 0xff;
19 if (ca >= 'A' && ca <= 'Z')
20 ca += 'a' - 'A';
21 if (cb >= 'A' && cb <= 'Z')
22 cb += 'a' - 'A';
23 } while (ca == cb && ca != '\0');
24
25 return ca - cb;
26}
diff --git a/arch/sh/lib/strlen.S b/arch/sh/lib/strlen.S
new file mode 100644
index 000000000000..f8ab296047b3
--- /dev/null
+++ b/arch/sh/lib/strlen.S
@@ -0,0 +1,70 @@
1/* $Id: strlen.S,v 1.2 2001/06/29 14:07:15 gniibe Exp $
2 *
3 * "strlen" implementation of SuperH
4 *
5 * Copyright (C) 1999 Kaz Kojima
6 *
7 */
8
9/* size_t strlen (const char *s) */
10
11#include <linux/linkage.h>
12ENTRY(strlen)
13 mov r4,r0
14 and #3,r0
15 tst r0,r0
16 bt/s 1f
17 mov #0,r2
18
19 add #-1,r0
20 shll2 r0
21 shll r0
22 braf r0
23 nop
24
25 mov.b @r4+,r1
26 tst r1,r1
27 bt 8f
28 add #1,r2
29
30 mov.b @r4+,r1
31 tst r1,r1
32 bt 8f
33 add #1,r2
34
35 mov.b @r4+,r1
36 tst r1,r1
37 bt 8f
38 add #1,r2
39
401:
41 mov #0,r3
422:
43 mov.l @r4+,r1
44 cmp/str r3,r1
45 bf/s 2b
46 add #4,r2
47
48 add #-4,r2
49#ifndef __LITTLE_ENDIAN__
50 swap.b r1,r1
51 swap.w r1,r1
52 swap.b r1,r1
53#endif
54 extu.b r1,r0
55 tst r0,r0
56 bt/s 8f
57 shlr8 r1
58 add #1,r2
59 extu.b r1,r0
60 tst r0,r0
61 bt/s 8f
62 shlr8 r1
63 add #1,r2
64 extu.b r1,r0
65 tst r0,r0
66 bt 8f
67 add #1,r2
688:
69 rts
70 mov r2,r0
diff --git a/arch/sh/lib/udivdi3.c b/arch/sh/lib/udivdi3.c
new file mode 100644
index 000000000000..68f038bf3c50
--- /dev/null
+++ b/arch/sh/lib/udivdi3.c
@@ -0,0 +1,16 @@
1/*
2 * Simple __udivdi3 function which doesn't use FPU.
3 */
4
5#include <linux/types.h>
6
7extern u64 __xdiv64_32(u64 n, u32 d);
8extern void panic(const char * fmt, ...);
9
10u64 __udivdi3(u64 n, u64 d)
11{
12 if (d & ~0xffffffff)
13 panic("Need true 64-bit/64-bit division");
14 return __xdiv64_32(n, (u32)d);
15}
16
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
new file mode 100644
index 000000000000..9489a1424644
--- /dev/null
+++ b/arch/sh/mm/Makefile
@@ -0,0 +1,25 @@
1#
2# Makefile for the Linux SuperH-specific parts of the memory manager.
3#
4
5obj-y := init.o extable.o consistent.o
6
7obj-$(CONFIG_CPU_SH2) += cache-sh2.o
8obj-$(CONFIG_CPU_SH3) += cache-sh3.o
9obj-$(CONFIG_CPU_SH4) += cache-sh4.o pg-sh4.o
10
11obj-$(CONFIG_DMA_PAGE_OPS) += pg-dma.o
12obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
13
14mmu-y := fault-nommu.o tlb-nommu.o pg-nommu.o
15mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o
16
17obj-y += $(mmu-y)
18
19ifdef CONFIG_MMU
20obj-$(CONFIG_CPU_SH3) += tlb-sh3.o
21obj-$(CONFIG_CPU_SH4) += tlb-sh4.o ioremap.o
22obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o
23endif
24
25obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o
diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c
new file mode 100644
index 000000000000..2689cb24ea2b
--- /dev/null
+++ b/arch/sh/mm/cache-sh2.c
@@ -0,0 +1,50 @@
1/*
2 * arch/sh/mm/cache-sh2.c
3 *
4 * Copyright (C) 2002 Paul Mundt
5 *
6 * Released under the terms of the GNU GPL v2.0.
7 */
8#include <linux/init.h>
9#include <linux/mm.h>
10
11#include <asm/cache.h>
12#include <asm/addrspace.h>
13#include <asm/processor.h>
14#include <asm/cacheflush.h>
15#include <asm/io.h>
16
17/*
18 * Calculate the OC address and set the way bit on the SH-2.
19 *
20 * We must have already jump_to_P2()'ed prior to calling this
21 * function, since we rely on CCR manipulation to do the
22 * Right Thing(tm).
23 */
24unsigned long __get_oc_addr(unsigned long set, unsigned long way)
25{
26 unsigned long ccr;
27
28 /*
29 * On SH-2 the way bit isn't tracked in the address field
30 * if we're doing address array access .. instead, we need
31 * to manually switch out the way in the CCR.
32 */
33 ccr = ctrl_inl(CCR);
34 ccr &= ~0x00c0;
35 ccr |= way << cpu_data->dcache.way_shift;
36
37 /*
38 * Despite the number of sets being halved, we end up losing
39 * the first 2 ways to OCRAM instead of the last 2 (if we're
40 * 4-way). As a result, forcibly setting the W1 bit handily
41 * bumps us up 2 ways.
42 */
43 if (ccr & CCR_CACHE_ORA)
44 ccr |= 1 << (cpu_data->dcache.way_shift + 1);
45
46 ctrl_outl(ccr, CCR);
47
48 return CACHE_OC_ADDRESS_ARRAY | (set << cpu_data->dcache.entry_shift);
49}
50
diff --git a/arch/sh/mm/cache-sh3.c b/arch/sh/mm/cache-sh3.c
new file mode 100644
index 000000000000..838731fc608d
--- /dev/null
+++ b/arch/sh/mm/cache-sh3.c
@@ -0,0 +1,100 @@
1/*
2 * arch/sh/mm/cache-sh3.c
3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2002 Paul Mundt
6 *
7 * Released under the terms of the GNU GPL v2.0.
8 */
9
10#include <linux/init.h>
11#include <linux/mman.h>
12#include <linux/mm.h>
13#include <linux/threads.h>
14#include <asm/addrspace.h>
15#include <asm/page.h>
16#include <asm/pgtable.h>
17#include <asm/processor.h>
18#include <asm/cache.h>
19#include <asm/io.h>
20#include <asm/uaccess.h>
21#include <asm/pgalloc.h>
22#include <asm/mmu_context.h>
23#include <asm/cacheflush.h>
24
25/*
26 * Write back the dirty D-caches, but not invalidate them.
27 *
28 * Is this really worth it, or should we just alias this routine
29 * to __flush_purge_region too?
30 *
31 * START: Virtual Address (U0, P1, or P3)
32 * SIZE: Size of the region.
33 */
34
35void __flush_wback_region(void *start, int size)
36{
37 unsigned long v, j;
38 unsigned long begin, end;
39 unsigned long flags;
40
41 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
42 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
43 & ~(L1_CACHE_BYTES-1);
44
45 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
46 unsigned long addrstart = CACHE_OC_ADDRESS_ARRAY;
47 for (j = 0; j < cpu_data->dcache.ways; j++) {
48 unsigned long data, addr, p;
49
50 p = __pa(v);
51 addr = addrstart | (v & cpu_data->dcache.entry_mask);
52 local_irq_save(flags);
53 data = ctrl_inl(addr);
54
55 if ((data & CACHE_PHYSADDR_MASK) ==
56 (p & CACHE_PHYSADDR_MASK)) {
57 data &= ~SH_CACHE_UPDATED;
58 ctrl_outl(data, addr);
59 local_irq_restore(flags);
60 break;
61 }
62 local_irq_restore(flags);
63 addrstart += cpu_data->dcache.way_incr;
64 }
65 }
66}
67
68/*
69 * Write back the dirty D-caches and invalidate them.
70 *
71 * START: Virtual Address (U0, P1, or P3)
72 * SIZE: Size of the region.
73 */
74void __flush_purge_region(void *start, int size)
75{
76 unsigned long v;
77 unsigned long begin, end;
78
79 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
80 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
81 & ~(L1_CACHE_BYTES-1);
82
83 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
84 unsigned long data, addr;
85
86 data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */
87 addr = CACHE_OC_ADDRESS_ARRAY |
88 (v & cpu_data->dcache.entry_mask) | SH_CACHE_ASSOC;
89 ctrl_outl(data, addr);
90 }
91}
92
93/*
94 * No write back please
95 *
96 * Except I don't think there's any way to avoid the writeback. So we
97 * just alias it to __flush_purge_region(). dwmw2.
98 */
99void __flush_invalidate_region(void *start, int size)
100 __attribute__((alias("__flush_purge_region")));
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
new file mode 100644
index 000000000000..ab833adf28c3
--- /dev/null
+++ b/arch/sh/mm/cache-sh4.c
@@ -0,0 +1,362 @@
1/*
2 * arch/sh/mm/cache-sh4.c
3 *
4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt
6 * Copyright (C) 2003 Richard Curnow
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/mman.h>
16#include <linux/mm.h>
17#include <linux/threads.h>
18#include <asm/addrspace.h>
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/processor.h>
22#include <asm/cache.h>
23#include <asm/io.h>
24#include <asm/uaccess.h>
25#include <asm/pgalloc.h>
26#include <asm/mmu_context.h>
27#include <asm/cacheflush.h>
28
29extern void __flush_cache_4096_all(unsigned long start);
30static void __flush_cache_4096_all_ex(unsigned long start);
31extern void __flush_dcache_all(void);
32static void __flush_dcache_all_ex(void);
33
34/*
35 * SH-4 has virtually indexed and physically tagged cache.
36 */
37
38struct semaphore p3map_sem[4];
39
40void __init p3_cache_init(void)
41{
42 if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE))
43 panic("%s failed.", __FUNCTION__);
44
45 sema_init (&p3map_sem[0], 1);
46 sema_init (&p3map_sem[1], 1);
47 sema_init (&p3map_sem[2], 1);
48 sema_init (&p3map_sem[3], 1);
49}
50
51/*
52 * Write back the dirty D-caches, but not invalidate them.
53 *
54 * START: Virtual Address (U0, P1, or P3)
55 * SIZE: Size of the region.
56 */
57void __flush_wback_region(void *start, int size)
58{
59 unsigned long v;
60 unsigned long begin, end;
61
62 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
63 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
64 & ~(L1_CACHE_BYTES-1);
65 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
66 asm volatile("ocbwb %0"
67 : /* no output */
68 : "m" (__m(v)));
69 }
70}
71
72/*
73 * Write back the dirty D-caches and invalidate them.
74 *
75 * START: Virtual Address (U0, P1, or P3)
76 * SIZE: Size of the region.
77 */
78void __flush_purge_region(void *start, int size)
79{
80 unsigned long v;
81 unsigned long begin, end;
82
83 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
84 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
85 & ~(L1_CACHE_BYTES-1);
86 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
87 asm volatile("ocbp %0"
88 : /* no output */
89 : "m" (__m(v)));
90 }
91}
92
93
94/*
95 * No write back please
96 */
97void __flush_invalidate_region(void *start, int size)
98{
99 unsigned long v;
100 unsigned long begin, end;
101
102 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
103 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
104 & ~(L1_CACHE_BYTES-1);
105 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
106 asm volatile("ocbi %0"
107 : /* no output */
108 : "m" (__m(v)));
109 }
110}
111
112static void __flush_dcache_all_ex(void)
113{
114 unsigned long addr, end_addr, entry_offset;
115
116 end_addr = CACHE_OC_ADDRESS_ARRAY + (cpu_data->dcache.sets << cpu_data->dcache.entry_shift) * cpu_data->dcache.ways;
117 entry_offset = 1 << cpu_data->dcache.entry_shift;
118 for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; addr += entry_offset) {
119 ctrl_outl(0, addr);
120 }
121}
122
123static void __flush_cache_4096_all_ex(unsigned long start)
124{
125 unsigned long addr, entry_offset;
126 int i;
127
128 entry_offset = 1 << cpu_data->dcache.entry_shift;
129 for (i = 0; i < cpu_data->dcache.ways; i++, start += cpu_data->dcache.way_incr) {
130 for (addr = CACHE_OC_ADDRESS_ARRAY + start;
131 addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start;
132 addr += entry_offset) {
133 ctrl_outl(0, addr);
134 }
135 }
136}
137
138void flush_cache_4096_all(unsigned long start)
139{
140 if (cpu_data->dcache.ways == 1)
141 __flush_cache_4096_all(start);
142 else
143 __flush_cache_4096_all_ex(start);
144}
145
146/*
147 * Write back the range of D-cache, and purge the I-cache.
148 *
149 * Called from kernel/module.c:sys_init_module and routine for a.out format.
150 */
151void flush_icache_range(unsigned long start, unsigned long end)
152{
153 flush_cache_all();
154}
155
156/*
157 * Write back the D-cache and purge the I-cache for signal trampoline.
158 * .. which happens to be the same behavior as flush_icache_range().
159 * So, we simply flush out a line.
160 */
161void flush_cache_sigtramp(unsigned long addr)
162{
163 unsigned long v, index;
164 unsigned long flags;
165 int i;
166
167 v = addr & ~(L1_CACHE_BYTES-1);
168 asm volatile("ocbwb %0"
169 : /* no output */
170 : "m" (__m(v)));
171
172 index = CACHE_IC_ADDRESS_ARRAY | (v & cpu_data->icache.entry_mask);
173
174 local_irq_save(flags);
175 jump_to_P2();
176 for(i = 0; i < cpu_data->icache.ways; i++, index += cpu_data->icache.way_incr)
177 ctrl_outl(0, index); /* Clear out Valid-bit */
178 back_to_P1();
179 local_irq_restore(flags);
180}
181
182static inline void flush_cache_4096(unsigned long start,
183 unsigned long phys)
184{
185 unsigned long flags;
186 extern void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long exec_offset);
187
188 /*
189 * SH7751, SH7751R, and ST40 have no restriction to handle cache.
190 * (While SH7750 must do that at P2 area.)
191 */
192 if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG)
193 || start < CACHE_OC_ADDRESS_ARRAY) {
194 local_irq_save(flags);
195 __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0x20000000);
196 local_irq_restore(flags);
197 } else {
198 __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0);
199 }
200}
201
202/*
203 * Write back & invalidate the D-cache of the page.
204 * (To avoid "alias" issues)
205 */
206void flush_dcache_page(struct page *page)
207{
208 if (test_bit(PG_mapped, &page->flags)) {
209 unsigned long phys = PHYSADDR(page_address(page));
210
211 /* Loop all the D-cache */
212 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys);
213 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys);
214 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys);
215 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys);
216 }
217}
218
219static inline void flush_icache_all(void)
220{
221 unsigned long flags, ccr;
222
223 local_irq_save(flags);
224 jump_to_P2();
225
226 /* Flush I-cache */
227 ccr = ctrl_inl(CCR);
228 ccr |= CCR_CACHE_ICI;
229 ctrl_outl(ccr, CCR);
230
231 back_to_P1();
232 local_irq_restore(flags);
233}
234
235void flush_cache_all(void)
236{
237 if (cpu_data->dcache.ways == 1)
238 __flush_dcache_all();
239 else
240 __flush_dcache_all_ex();
241 flush_icache_all();
242}
243
244void flush_cache_mm(struct mm_struct *mm)
245{
246 /* Is there any good way? */
247 /* XXX: possibly call flush_cache_range for each vm area */
248 /*
249 * FIXME: Really, the optimal solution here would be able to flush out
250 * individual lines created by the specified context, but this isn't
251 * feasible for a number of architectures (such as MIPS, and some
252 * SPARC) .. is this possible for SuperH?
253 *
254 * In the meantime, we'll just flush all of the caches.. this
255 * seems to be the simplest way to avoid at least a few wasted
256 * cache flushes. -Lethal
257 */
258 flush_cache_all();
259}
260
261/*
262 * Write back and invalidate I/D-caches for the page.
263 *
264 * ADDR: Virtual Address (U0 address)
265 * PFN: Physical page number
266 */
267void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn)
268{
269 unsigned long phys = pfn << PAGE_SHIFT;
270
271 /* We only need to flush D-cache when we have alias */
272 if ((address^phys) & CACHE_ALIAS) {
273 /* Loop 4K of the D-cache */
274 flush_cache_4096(
275 CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS),
276 phys);
277 /* Loop another 4K of the D-cache */
278 flush_cache_4096(
279 CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS),
280 phys);
281 }
282
283 if (vma->vm_flags & VM_EXEC)
284 /* Loop 4K (half) of the I-cache */
285 flush_cache_4096(
286 CACHE_IC_ADDRESS_ARRAY | (address & 0x1000),
287 phys);
288}
289
290/*
291 * Write back and invalidate D-caches.
292 *
293 * START, END: Virtual Address (U0 address)
294 *
295 * NOTE: We need to flush the _physical_ page entry.
296 * Flushing the cache lines for U0 only isn't enough.
297 * We need to flush for P1 too, which may contain aliases.
298 */
299void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
300 unsigned long end)
301{
302 unsigned long p = start & PAGE_MASK;
303 pgd_t *dir;
304 pmd_t *pmd;
305 pte_t *pte;
306 pte_t entry;
307 unsigned long phys;
308 unsigned long d = 0;
309
310 dir = pgd_offset(vma->vm_mm, p);
311 pmd = pmd_offset(dir, p);
312
313 do {
314 if (pmd_none(*pmd) || pmd_bad(*pmd)) {
315 p &= ~((1 << PMD_SHIFT) -1);
316 p += (1 << PMD_SHIFT);
317 pmd++;
318 continue;
319 }
320 pte = pte_offset_kernel(pmd, p);
321 do {
322 entry = *pte;
323 if ((pte_val(entry) & _PAGE_PRESENT)) {
324 phys = pte_val(entry)&PTE_PHYS_MASK;
325 if ((p^phys) & CACHE_ALIAS) {
326 d |= 1 << ((p & CACHE_ALIAS)>>12);
327 d |= 1 << ((phys & CACHE_ALIAS)>>12);
328 if (d == 0x0f)
329 goto loop_exit;
330 }
331 }
332 pte++;
333 p += PAGE_SIZE;
334 } while (p < end && ((unsigned long)pte & ~PAGE_MASK));
335 pmd++;
336 } while (p < end);
337 loop_exit:
338 if (d & 1)
339 flush_cache_4096_all(0);
340 if (d & 2)
341 flush_cache_4096_all(0x1000);
342 if (d & 4)
343 flush_cache_4096_all(0x2000);
344 if (d & 8)
345 flush_cache_4096_all(0x3000);
346 if (vma->vm_flags & VM_EXEC)
347 flush_icache_all();
348}
349
350/*
351 * flush_icache_user_range
352 * @vma: VMA of the process
353 * @page: page
354 * @addr: U0 address
355 * @len: length of the range (< page size)
356 */
357void flush_icache_user_range(struct vm_area_struct *vma,
358 struct page *page, unsigned long addr, int len)
359{
360 flush_cache_page(vma, addr, page_to_pfn(page));
361}
362
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
new file mode 100644
index 000000000000..ad8ed7d41e16
--- /dev/null
+++ b/arch/sh/mm/cache-sh7705.c
@@ -0,0 +1,206 @@
1/*
2 * arch/sh/mm/cache-sh7705.c
3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2004 Alex Song
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 */
12
13#include <linux/init.h>
14#include <linux/mman.h>
15#include <linux/mm.h>
16#include <linux/threads.h>
17#include <asm/addrspace.h>
18#include <asm/page.h>
19#include <asm/pgtable.h>
20#include <asm/processor.h>
21#include <asm/cache.h>
22#include <asm/io.h>
23#include <asm/uaccess.h>
24#include <asm/pgalloc.h>
25#include <asm/mmu_context.h>
26#include <asm/cacheflush.h>
27
28/* The 32KB cache on the SH7705 suffers from the same synonym problem
29 * as SH4 CPUs */
30
31#define __pte_offset(address) \
32 ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
33#define pte_offset(dir, address) ((pte_t *) pmd_page_kernel(*(dir)) + \
34 __pte_offset(address))
35
36static inline void cache_wback_all(void)
37{
38 unsigned long ways, waysize, addrstart;
39
40 ways = cpu_data->dcache.ways;
41 waysize = cpu_data->dcache.sets;
42 waysize <<= cpu_data->dcache.entry_shift;
43
44 addrstart = CACHE_OC_ADDRESS_ARRAY;
45
46 do {
47 unsigned long addr;
48
49 for (addr = addrstart;
50 addr < addrstart + waysize;
51 addr += cpu_data->dcache.linesz) {
52 unsigned long data;
53 int v = SH_CACHE_UPDATED | SH_CACHE_VALID;
54
55 data = ctrl_inl(addr);
56
57 if ((data & v) == v)
58 ctrl_outl(data & ~v, addr);
59
60 }
61
62 addrstart += cpu_data->dcache.way_incr;
63 } while (--ways);
64}
65
66/*
67 * Write back the range of D-cache, and purge the I-cache.
68 *
69 * Called from kernel/module.c:sys_init_module and routine for a.out format.
70 */
71void flush_icache_range(unsigned long start, unsigned long end)
72{
73 __flush_wback_region((void *)start, end - start);
74}
75
76
77/*
78 * Writeback&Invalidate the D-cache of the page
79 */
80static void __flush_dcache_page(unsigned long phys)
81{
82 unsigned long ways, waysize, addrstart;
83 unsigned long flags;
84
85 phys |= SH_CACHE_VALID;
86
87 /*
88 * Here, phys is the physical address of the page. We check all the
89 * tags in the cache for those with the same page number as this page
90 * (by masking off the lowest 2 bits of the 19-bit tag; these bits are
91 * derived from the offset within in the 4k page). Matching valid
92 * entries are invalidated.
93 *
94 * Since 2 bits of the cache index are derived from the virtual page
95 * number, knowing this would reduce the number of cache entries to be
96 * searched by a factor of 4. However this function exists to deal with
97 * potential cache aliasing, therefore the optimisation is probably not
98 * possible.
99 */
100 local_irq_save(flags);
101 jump_to_P2();
102
103 ways = cpu_data->dcache.ways;
104 waysize = cpu_data->dcache.sets;
105 waysize <<= cpu_data->dcache.entry_shift;
106
107 addrstart = CACHE_OC_ADDRESS_ARRAY;
108
109 do {
110 unsigned long addr;
111
112 for (addr = addrstart;
113 addr < addrstart + waysize;
114 addr += cpu_data->dcache.linesz) {
115 unsigned long data;
116
117 data = ctrl_inl(addr) & (0x1ffffC00 | SH_CACHE_VALID);
118 if (data == phys) {
119 data &= ~(SH_CACHE_VALID | SH_CACHE_UPDATED);
120 ctrl_outl(data, addr);
121 }
122 }
123
124 addrstart += cpu_data->dcache.way_incr;
125 } while (--ways);
126
127 back_to_P1();
128 local_irq_restore(flags);
129}
130
131
132/*
133 * Write back & invalidate the D-cache of the page.
134 * (To avoid "alias" issues)
135 */
136void flush_dcache_page(struct page *page)
137{
138 if (test_bit(PG_mapped, &page->flags))
139 __flush_dcache_page(PHYSADDR(page_address(page)));
140}
141
142void flush_cache_all(void)
143{
144 unsigned long flags;
145
146 local_irq_save(flags);
147 jump_to_P2();
148
149 cache_wback_all();
150 back_to_P1();
151 local_irq_restore(flags);
152}
153
154void flush_cache_mm(struct mm_struct *mm)
155{
156 /* Is there any good way? */
157 /* XXX: possibly call flush_cache_range for each vm area */
158 flush_cache_all();
159}
160
161/*
162 * Write back and invalidate D-caches.
163 *
164 * START, END: Virtual Address (U0 address)
165 *
166 * NOTE: We need to flush the _physical_ page entry.
167 * Flushing the cache lines for U0 only isn't enough.
168 * We need to flush for P1 too, which may contain aliases.
169 */
170void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
171 unsigned long end)
172{
173
174 /*
175 * We could call flush_cache_page for the pages of these range,
176 * but it's not efficient (scan the caches all the time...).
177 *
178 * We can't use A-bit magic, as there's the case we don't have
179 * valid entry on TLB.
180 */
181 flush_cache_all();
182}
183
184/*
185 * Write back and invalidate I/D-caches for the page.
186 *
187 * ADDRESS: Virtual Address (U0 address)
188 */
189void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn)
190{
191 __flush_dcache_page(pfn << PAGE_SHIFT);
192}
193
194/*
195 * This is called when a page-cache page is about to be mapped into a
196 * user process' address space. It offers an opportunity for a
197 * port to ensure d-cache/i-cache coherency if necessary.
198 *
199 * Not entirely sure why this is necessary on SH3 with 32K cache but
200 * without it we get occasional "Memory fault" when loading a program.
201 */
202void flush_icache_page(struct vm_area_struct *vma, struct page *page)
203{
204 __flush_purge_region(page_address(page), PAGE_SIZE);
205}
206
diff --git a/arch/sh/mm/clear_page.S b/arch/sh/mm/clear_page.S
new file mode 100644
index 000000000000..ae58a61f0e66
--- /dev/null
+++ b/arch/sh/mm/clear_page.S
@@ -0,0 +1,295 @@
1/* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $
2 *
3 * __clear_user_page, __clear_user, clear_page implementation of SuperH
4 *
5 * Copyright (C) 2001 Kaz Kojima
6 * Copyright (C) 2001, 2002 Niibe Yutaka
7 *
8 */
9#include <linux/config.h>
10#include <linux/linkage.h>
11
12/*
13 * clear_page_slow
14 * @to: P1 address
15 *
16 * void clear_page_slow(void *to)
17 */
18
19/*
20 * r0 --- scratch
21 * r4 --- to
22 * r5 --- to + 4096
23 */
24ENTRY(clear_page_slow)
25 mov r4,r5
26 mov.w .Llimit,r0
27 add r0,r5
28 mov #0,r0
29 !
301:
31#if defined(CONFIG_CPU_SH3)
32 mov.l r0,@r4
33#elif defined(CONFIG_CPU_SH4)
34 movca.l r0,@r4
35 mov r4,r1
36#endif
37 add #32,r4
38 mov.l r0,@-r4
39 mov.l r0,@-r4
40 mov.l r0,@-r4
41 mov.l r0,@-r4
42 mov.l r0,@-r4
43 mov.l r0,@-r4
44 mov.l r0,@-r4
45#if defined(CONFIG_CPU_SH4)
46 ocbwb @r1
47#endif
48 cmp/eq r5,r4
49 bf/s 1b
50 add #28,r4
51 !
52 rts
53 nop
54.Llimit: .word (4096-28)
55
56ENTRY(__clear_user)
57 !
58 mov #0, r0
59 mov #0xe0, r1 ! 0xffffffe0
60 !
61 ! r4..(r4+31)&~32 -------- not aligned [ Area 0 ]
62 ! (r4+31)&~32..(r4+r5)&~32 -------- aligned [ Area 1 ]
63 ! (r4+r5)&~32..r4+r5 -------- not aligned [ Area 2 ]
64 !
65 ! Clear area 0
66 mov r4, r2
67 !
68 tst r1, r5 ! length < 32
69 bt .Larea2 ! skip to remainder
70 !
71 add #31, r2
72 and r1, r2
73 cmp/eq r4, r2
74 bt .Larea1
75 mov r2, r3
76 sub r4, r3
77 mov r3, r7
78 mov r4, r2
79 !
80.L0: dt r3
810: mov.b r0, @r2
82 bf/s .L0
83 add #1, r2
84 !
85 sub r7, r5
86 mov r2, r4
87.Larea1:
88 mov r4, r3
89 add r5, r3
90 and r1, r3
91 cmp/hi r2, r3
92 bf .Larea2
93 !
94 ! Clear area 1
95#if defined(CONFIG_CPU_SH4)
961: movca.l r0, @r2
97#else
981: mov.l r0, @r2
99#endif
100 add #4, r2
1012: mov.l r0, @r2
102 add #4, r2
1033: mov.l r0, @r2
104 add #4, r2
1054: mov.l r0, @r2
106 add #4, r2
1075: mov.l r0, @r2
108 add #4, r2
1096: mov.l r0, @r2
110 add #4, r2
1117: mov.l r0, @r2
112 add #4, r2
1138: mov.l r0, @r2
114 add #4, r2
115 cmp/hi r2, r3
116 bt/s 1b
117 nop
118 !
119 ! Clear area 2
120.Larea2:
121 mov r4, r3
122 add r5, r3
123 cmp/hs r3, r2
124 bt/s .Ldone
125 sub r2, r3
126.L2: dt r3
1279: mov.b r0, @r2
128 bf/s .L2
129 add #1, r2
130 !
131.Ldone: rts
132 mov #0, r0 ! return 0 as normal return
133
134 ! return the number of bytes remained
135.Lbad_clear_user:
136 mov r4, r0
137 add r5, r0
138 rts
139 sub r2, r0
140
141.section __ex_table,"a"
142 .align 2
143 .long 0b, .Lbad_clear_user
144 .long 1b, .Lbad_clear_user
145 .long 2b, .Lbad_clear_user
146 .long 3b, .Lbad_clear_user
147 .long 4b, .Lbad_clear_user
148 .long 5b, .Lbad_clear_user
149 .long 6b, .Lbad_clear_user
150 .long 7b, .Lbad_clear_user
151 .long 8b, .Lbad_clear_user
152 .long 9b, .Lbad_clear_user
153.previous
154
155#if defined(CONFIG_CPU_SH4)
156/*
157 * __clear_user_page
158 * @to: P3 address (with same color)
159 * @orig_to: P1 address
160 *
161 * void __clear_user_page(void *to, void *orig_to)
162 */
163
164/*
165 * r0 --- scratch
166 * r4 --- to
167 * r5 --- orig_to
168 * r6 --- to + 4096
169 */
170ENTRY(__clear_user_page)
171 mov.w .L4096,r0
172 mov r4,r6
173 add r0,r6
174 mov #0,r0
175 !
1761: ocbi @r5
177 add #32,r5
178 movca.l r0,@r4
179 mov r4,r1
180 add #32,r4
181 mov.l r0,@-r4
182 mov.l r0,@-r4
183 mov.l r0,@-r4
184 mov.l r0,@-r4
185 mov.l r0,@-r4
186 mov.l r0,@-r4
187 mov.l r0,@-r4
188 add #28,r4
189 cmp/eq r6,r4
190 bf/s 1b
191 ocbwb @r1
192 !
193 rts
194 nop
195.L4096: .word 4096
196
197ENTRY(__flush_cache_4096)
198 mov.l 1f,r3
199 add r6,r3
200 mov r4,r0
201 mov #64,r2
202 shll r2
203 mov #64,r6
204 jmp @r3
205 mov #96,r7
206 .align 2
2071: .long 2f
2082:
209 .rept 32
210 mov.l r5,@r0
211 mov.l r5,@(32,r0)
212 mov.l r5,@(r0,r6)
213 mov.l r5,@(r0,r7)
214 add r2,r5
215 add r2,r0
216 .endr
217 nop
218 nop
219 nop
220 nop
221 nop
222 nop
223 nop
224 rts
225 nop
226
227ENTRY(__flush_dcache_all)
228 mov.l 2f,r0
229 mov.l 3f,r4
230 and r0,r4 ! r4 = (unsigned long)&empty_zero_page[0] & ~0xffffc000
231 stc sr,r1 ! save SR
232 mov.l 4f,r2
233 or r1,r2
234 mov #32,r3
235 shll2 r3
2361:
237 ldc r2,sr ! set BL bit
238 movca.l r0,@r4
239 ocbi @r4
240 add #32,r4
241 movca.l r0,@r4
242 ocbi @r4
243 add #32,r4
244 movca.l r0,@r4
245 ocbi @r4
246 add #32,r4
247 movca.l r0,@r4
248 ocbi @r4
249 ldc r1,sr ! restore SR
250 dt r3
251 bf/s 1b
252 add #32,r4
253
254 rts
255 nop
256 .align 2
2572: .long 0xffffc000
2583: .long empty_zero_page
2594: .long 0x10000000 ! BL bit
260
261/* __flush_cache_4096_all(unsigned long addr) */
262ENTRY(__flush_cache_4096_all)
263 mov.l 2f,r0
264 mov.l 3f,r2
265 and r0,r2
266 or r2,r4 ! r4 = addr | (unsigned long)&empty_zero_page[0] & ~0x3fff
267 stc sr,r1 ! save SR
268 mov.l 4f,r2
269 or r1,r2
270 mov #32,r3
2711:
272 ldc r2,sr ! set BL bit
273 movca.l r0,@r4
274 ocbi @r4
275 add #32,r4
276 movca.l r0,@r4
277 ocbi @r4
278 add #32,r4
279 movca.l r0,@r4
280 ocbi @r4
281 add #32,r4
282 movca.l r0,@r4
283 ocbi @r4
284 ldc r1,sr ! restore SR
285 dt r3
286 bf/s 1b
287 add #32,r4
288
289 rts
290 nop
291 .align 2
2922: .long 0xffffc000
2933: .long empty_zero_page
2944: .long 0x10000000 ! BL bit
295#endif
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
new file mode 100644
index 000000000000..1f7af0c73cf4
--- /dev/null
+++ b/arch/sh/mm/consistent.c
@@ -0,0 +1,85 @@
1/*
2 * arch/sh/mm/consistent.c
3 *
4 * Copyright (C) 2004 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/mm.h>
11#include <linux/dma-mapping.h>
12#include <asm/io.h>
13
14void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle)
15{
16 struct page *page, *end, *free;
17 void *ret;
18 int order;
19
20 size = PAGE_ALIGN(size);
21 order = get_order(size);
22
23 page = alloc_pages(gfp, order);
24 if (!page)
25 return NULL;
26
27 ret = page_address(page);
28 *handle = virt_to_phys(ret);
29
30 /*
31 * We must flush the cache before we pass it on to the device
32 */
33 dma_cache_wback_inv(ret, size);
34
35 page = virt_to_page(ret);
36 free = page + (size >> PAGE_SHIFT);
37 end = page + (1 << order);
38
39 while (++page < end) {
40 set_page_count(page, 1);
41
42 /* Free any unused pages */
43 if (page >= free) {
44 __free_page(page);
45 }
46 }
47
48 return P2SEGADDR(ret);
49}
50
51void consistent_free(void *vaddr, size_t size)
52{
53 unsigned long addr = P1SEGADDR((unsigned long)vaddr);
54 struct page *page=virt_to_page(addr);
55 int num_pages=(size+PAGE_SIZE-1) >> PAGE_SHIFT;
56 int i;
57
58 for(i=0;i<num_pages;i++) {
59 __free_page((page+i));
60 }
61}
62
63void consistent_sync(void *vaddr, size_t size, int direction)
64{
65 void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
66
67 switch (direction) {
68 case DMA_FROM_DEVICE: /* invalidate only */
69 dma_cache_inv(p1addr, size);
70 break;
71 case DMA_TO_DEVICE: /* writeback only */
72 dma_cache_wback(p1addr, size);
73 break;
74 case DMA_BIDIRECTIONAL: /* writeback and invalidate */
75 dma_cache_wback_inv(p1addr, size);
76 break;
77 default:
78 BUG();
79 }
80}
81
82EXPORT_SYMBOL(consistent_alloc);
83EXPORT_SYMBOL(consistent_free);
84EXPORT_SYMBOL(consistent_sync);
85
diff --git a/arch/sh/mm/copy_page.S b/arch/sh/mm/copy_page.S
new file mode 100644
index 000000000000..1addffe117c3
--- /dev/null
+++ b/arch/sh/mm/copy_page.S
@@ -0,0 +1,397 @@
1/* $Id: copy_page.S,v 1.8 2003/08/25 17:03:10 lethal Exp $
2 *
3 * copy_page, __copy_user_page, __copy_user implementation of SuperH
4 *
5 * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima
6 * Copyright (C) 2002 Toshinobu Sugioka
7 *
8 */
9#include <linux/linkage.h>
10
11/*
12 * copy_page_slow
13 * @to: P1 address
14 * @from: P1 address
15 *
16 * void copy_page_slow(void *to, void *from)
17 */
18
19/*
20 * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
21 * r8 --- from + 4096
22 * r9 --- not used
23 * r10 --- to
24 * r11 --- from
25 */
26ENTRY(copy_page_slow)
27 mov.l r8,@-r15
28 mov.l r10,@-r15
29 mov.l r11,@-r15
30 mov r4,r10
31 mov r5,r11
32 mov r5,r8
33 mov.w .L4096,r0
34 add r0,r8
35 !
361: mov.l @r11+,r0
37 mov.l @r11+,r1
38 mov.l @r11+,r2
39 mov.l @r11+,r3
40 mov.l @r11+,r4
41 mov.l @r11+,r5
42 mov.l @r11+,r6
43 mov.l @r11+,r7
44#if defined(CONFIG_CPU_SH3)
45 mov.l r0,@r10
46#elif defined(CONFIG_CPU_SH4)
47 movca.l r0,@r10
48 mov r10,r0
49#endif
50 add #32,r10
51 mov.l r7,@-r10
52 mov.l r6,@-r10
53 mov.l r5,@-r10
54 mov.l r4,@-r10
55 mov.l r3,@-r10
56 mov.l r2,@-r10
57 mov.l r1,@-r10
58#if defined(CONFIG_CPU_SH4)
59 ocbwb @r0
60#endif
61 cmp/eq r11,r8
62 bf/s 1b
63 add #28,r10
64 !
65 mov.l @r15+,r11
66 mov.l @r15+,r10
67 mov.l @r15+,r8
68 rts
69 nop
70
71#if defined(CONFIG_CPU_SH4)
72/*
73 * __copy_user_page
74 * @to: P1 address (with same color)
75 * @from: P1 address
76 * @orig_to: P1 address
77 *
78 * void __copy_user_page(void *to, void *from, void *orig_to)
79 */
80
81/*
82 * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
83 * r8 --- from + 4096
84 * r9 --- orig_to
85 * r10 --- to
86 * r11 --- from
87 */
88ENTRY(__copy_user_page)
89 mov.l r8,@-r15
90 mov.l r9,@-r15
91 mov.l r10,@-r15
92 mov.l r11,@-r15
93 mov r4,r10
94 mov r5,r11
95 mov r6,r9
96 mov r5,r8
97 mov.w .L4096,r0
98 add r0,r8
99 !
1001: ocbi @r9
101 add #32,r9
102 mov.l @r11+,r0
103 mov.l @r11+,r1
104 mov.l @r11+,r2
105 mov.l @r11+,r3
106 mov.l @r11+,r4
107 mov.l @r11+,r5
108 mov.l @r11+,r6
109 mov.l @r11+,r7
110 movca.l r0,@r10
111 mov r10,r0
112 add #32,r10
113 mov.l r7,@-r10
114 mov.l r6,@-r10
115 mov.l r5,@-r10
116 mov.l r4,@-r10
117 mov.l r3,@-r10
118 mov.l r2,@-r10
119 mov.l r1,@-r10
120 ocbwb @r0
121 cmp/eq r11,r8
122 bf/s 1b
123 add #28,r10
124 !
125 mov.l @r15+,r11
126 mov.l @r15+,r10
127 mov.l @r15+,r9
128 mov.l @r15+,r8
129 rts
130 nop
131#endif
132.L4096: .word 4096
133/*
134 * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
135 * Return the number of bytes NOT copied
136 */
137#define EX(...) \
138 9999: __VA_ARGS__ ; \
139 .section __ex_table, "a"; \
140 .long 9999b, 6000f ; \
141 .previous
142ENTRY(__copy_user)
143 tst r6,r6 ! Check explicitly for zero
144 bf 1f
145 rts
146 mov #0,r0 ! normal return
1471:
148 mov.l r10,@-r15
149 mov.l r9,@-r15
150 mov.l r8,@-r15
151 mov r4,r3
152 add r6,r3 ! last destination address
153 mov #12,r0 ! Check if small number of bytes
154 cmp/gt r0,r6
155 bt 2f
156 bra .L_cleanup_loop
157 nop
1582:
159 neg r5,r0 ! Calculate bytes needed to align source
160 add #4,r0
161 and #3,r0
162 tst r0,r0
163 bt .L_jump
164 mov r0,r1
165
166.L_loop1:
167 ! Copy bytes to align source
168EX( mov.b @r5+,r0 )
169 dt r1
170EX( mov.b r0,@r4 )
171 add #-1,r6
172 bf/s .L_loop1
173 add #1,r4
174
175.L_jump:
176 mov r6,r2 ! Calculate number of longwords to copy
177 shlr2 r2
178 tst r2,r2
179 bt .L_cleanup
180
181 mov r4,r0 ! Jump to appropriate routine
182 and #3,r0
183 mov r0,r1
184 shll2 r1
185 mova .L_jump_tbl,r0
186 mov.l @(r0,r1),r1
187 jmp @r1
188 nop
189
190 .align 2
191.L_jump_tbl:
192 .long .L_dest00
193 .long .L_dest01
194 .long .L_dest10
195 .long .L_dest11
196
197! Destination = 00
198
199.L_dest00:
200 mov r2,r7
201 shlr2 r7
202 shlr r7
203 tst r7,r7
204 mov #7,r0
205 bt/s 1f
206 and r0,r2
207 .align 2
2082:
209EX( mov.l @r5+,r0 )
210EX( mov.l @r5+,r8 )
211EX( mov.l @r5+,r9 )
212EX( mov.l @r5+,r10 )
213EX( mov.l r0,@r4 )
214EX( mov.l r8,@(4,r4) )
215EX( mov.l r9,@(8,r4) )
216EX( mov.l r10,@(12,r4) )
217EX( mov.l @r5+,r0 )
218EX( mov.l @r5+,r8 )
219EX( mov.l @r5+,r9 )
220EX( mov.l @r5+,r10 )
221 dt r7
222EX( mov.l r0,@(16,r4) )
223EX( mov.l r8,@(20,r4) )
224EX( mov.l r9,@(24,r4) )
225EX( mov.l r10,@(28,r4) )
226 bf/s 2b
227 add #32,r4
228 tst r2,r2
229 bt .L_cleanup
2301:
231EX( mov.l @r5+,r0 )
232 dt r2
233EX( mov.l r0,@r4 )
234 bf/s 1b
235 add #4,r4
236
237 bra .L_cleanup
238 nop
239
240! Destination = 10
241
242.L_dest10:
243 mov r2,r7
244 shlr2 r7
245 shlr r7
246 tst r7,r7
247 mov #7,r0
248 bt/s 1f
249 and r0,r2
2502:
251 dt r7
252#ifdef __LITTLE_ENDIAN__
253EX( mov.l @r5+,r0 )
254EX( mov.l @r5+,r1 )
255EX( mov.l @r5+,r8 )
256EX( mov.l @r5+,r9 )
257EX( mov.l @r5+,r10 )
258EX( mov.w r0,@r4 )
259 add #2,r4
260 xtrct r1,r0
261 xtrct r8,r1
262 xtrct r9,r8
263 xtrct r10,r9
264
265EX( mov.l r0,@r4 )
266EX( mov.l r1,@(4,r4) )
267EX( mov.l r8,@(8,r4) )
268EX( mov.l r9,@(12,r4) )
269
270EX( mov.l @r5+,r1 )
271EX( mov.l @r5+,r8 )
272EX( mov.l @r5+,r0 )
273 xtrct r1,r10
274 xtrct r8,r1
275 xtrct r0,r8
276 shlr16 r0
277EX( mov.l r10,@(16,r4) )
278EX( mov.l r1,@(20,r4) )
279EX( mov.l r8,@(24,r4) )
280EX( mov.w r0,@(28,r4) )
281 bf/s 2b
282 add #30,r4
283#else
284EX( mov.l @(28,r5),r0 )
285EX( mov.l @(24,r5),r8 )
286EX( mov.l @(20,r5),r9 )
287EX( mov.l @(16,r5),r10 )
288EX( mov.w r0,@(30,r4) )
289 add #-2,r4
290 xtrct r8,r0
291 xtrct r9,r8
292 xtrct r10,r9
293EX( mov.l r0,@(28,r4) )
294EX( mov.l r8,@(24,r4) )
295EX( mov.l r9,@(20,r4) )
296
297EX( mov.l @(12,r5),r0 )
298EX( mov.l @(8,r5),r8 )
299 xtrct r0,r10
300EX( mov.l @(4,r5),r9 )
301 mov.l r10,@(16,r4)
302EX( mov.l @r5,r10 )
303 xtrct r8,r0
304 xtrct r9,r8
305 xtrct r10,r9
306EX( mov.l r0,@(12,r4) )
307EX( mov.l r8,@(8,r4) )
308 swap.w r10,r0
309EX( mov.l r9,@(4,r4) )
310EX( mov.w r0,@(2,r4) )
311
312 add #32,r5
313 bf/s 2b
314 add #34,r4
315#endif
316 tst r2,r2
317 bt .L_cleanup
318
3191: ! Read longword, write two words per iteration
320EX( mov.l @r5+,r0 )
321 dt r2
322#ifdef __LITTLE_ENDIAN__
323EX( mov.w r0,@r4 )
324 shlr16 r0
325EX( mov.w r0,@(2,r4) )
326#else
327EX( mov.w r0,@(2,r4) )
328 shlr16 r0
329EX( mov.w r0,@r4 )
330#endif
331 bf/s 1b
332 add #4,r4
333
334 bra .L_cleanup
335 nop
336
337! Destination = 01 or 11
338
339.L_dest01:
340.L_dest11:
341 ! Read longword, write byte, word, byte per iteration
342EX( mov.l @r5+,r0 )
343 dt r2
344#ifdef __LITTLE_ENDIAN__
345EX( mov.b r0,@r4 )
346 shlr8 r0
347 add #1,r4
348EX( mov.w r0,@r4 )
349 shlr16 r0
350EX( mov.b r0,@(2,r4) )
351 bf/s .L_dest01
352 add #3,r4
353#else
354EX( mov.b r0,@(3,r4) )
355 shlr8 r0
356 swap.w r0,r7
357EX( mov.b r7,@r4 )
358 add #1,r4
359EX( mov.w r0,@r4 )
360 bf/s .L_dest01
361 add #3,r4
362#endif
363
364! Cleanup last few bytes
365.L_cleanup:
366 mov r6,r0
367 and #3,r0
368 tst r0,r0
369 bt .L_exit
370 mov r0,r6
371
372.L_cleanup_loop:
373EX( mov.b @r5+,r0 )
374 dt r6
375EX( mov.b r0,@r4 )
376 bf/s .L_cleanup_loop
377 add #1,r4
378
379.L_exit:
380 mov #0,r0 ! normal return
3815000:
382
383# Exception handler:
384.section .fixup, "ax"
3856000:
386 mov.l 8000f,r1
387 mov r3,r0
388 jmp @r1
389 sub r4,r0
390 .align 2
3918000: .long 5000b
392
393.previous
394 mov.l @r15+,r8
395 mov.l @r15+,r9
396 rts
397 mov.l @r15+,r10
diff --git a/arch/sh/mm/extable.c b/arch/sh/mm/extable.c
new file mode 100644
index 000000000000..505ede7c21bf
--- /dev/null
+++ b/arch/sh/mm/extable.c
@@ -0,0 +1,22 @@
1/*
2 * linux/arch/sh/mm/extable.c
3 * Taken from:
4 * linux/arch/i386/mm/extable.c
5 */
6
7#include <linux/config.h>
8#include <linux/module.h>
9#include <asm/uaccess.h>
10
11int fixup_exception(struct pt_regs *regs)
12{
13 const struct exception_table_entry *fixup;
14
15 fixup = search_exception_tables(regs->pc);
16 if (fixup) {
17 regs->pc = fixup->fixup;
18 return 1;
19 }
20
21 return 0;
22}
diff --git a/arch/sh/mm/fault-nommu.c b/arch/sh/mm/fault-nommu.c
new file mode 100644
index 000000000000..34d4e0c68fbb
--- /dev/null
+++ b/arch/sh/mm/fault-nommu.c
@@ -0,0 +1,82 @@
1/*
2 * arch/sh/mm/fault-nommu.c
3 *
4 * Copyright (C) 2002 Paul Mundt
5 *
6 * Based on linux/arch/sh/mm/fault.c:
7 * Copyright (C) 1999 Niibe Yutaka
8 *
9 * Released under the terms of the GNU GPL v2.0.
10 */
11
12#include <linux/signal.h>
13#include <linux/sched.h>
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/string.h>
17#include <linux/types.h>
18#include <linux/ptrace.h>
19#include <linux/mman.h>
20#include <linux/mm.h>
21#include <linux/smp.h>
22#include <linux/smp_lock.h>
23#include <linux/interrupt.h>
24
25#include <asm/system.h>
26#include <asm/io.h>
27#include <asm/uaccess.h>
28#include <asm/pgalloc.h>
29#include <asm/mmu_context.h>
30#include <asm/cacheflush.h>
31
32#if defined(CONFIG_SH_KGDB)
33#include <asm/kgdb.h>
34#endif
35
36extern void die(const char *,struct pt_regs *,long);
37
38/*
39 * This routine handles page faults. It determines the address,
40 * and the problem, and then passes it off to one of the appropriate
41 * routines.
42 */
43asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
44 unsigned long address)
45{
46#if defined(CONFIG_SH_KGDB)
47 if (kgdb_nofault && kgdb_bus_err_hook)
48 kgdb_bus_err_hook();
49#endif
50
51 /*
52 * Oops. The kernel tried to access some bad page. We'll have to
53 * terminate things with extreme prejudice.
54 *
55 */
56 if (address < PAGE_SIZE) {
57 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
58 } else {
59 printk(KERN_ALERT "Unable to handle kernel paging request");
60 }
61
62 printk(" at virtual address %08lx\n", address);
63 printk(KERN_ALERT "pc = %08lx\n", regs->pc);
64
65 die("Oops", regs, writeaccess);
66 do_exit(SIGKILL);
67}
68
69asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
70 unsigned long address)
71{
72#if defined(CONFIG_SH_KGDB)
73 if (kgdb_nofault && kgdb_bus_err_hook)
74 kgdb_bus_err_hook();
75#endif
76
77 if (address >= TASK_SIZE)
78 return 1;
79
80 return 0;
81}
82
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
new file mode 100644
index 000000000000..7abba2161da6
--- /dev/null
+++ b/arch/sh/mm/fault.c
@@ -0,0 +1,374 @@
1/* $Id: fault.c,v 1.14 2004/01/13 05:52:11 kkojima Exp $
2 *
3 * linux/arch/sh/mm/fault.c
4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2003 Paul Mundt
6 *
7 * Based on linux/arch/i386/mm/fault.c:
8 * Copyright (C) 1995 Linus Torvalds
9 */
10
11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/interrupt.h>
23#include <linux/module.h>
24
25#include <asm/system.h>
26#include <asm/io.h>
27#include <asm/uaccess.h>
28#include <asm/pgalloc.h>
29#include <asm/mmu_context.h>
30#include <asm/cacheflush.h>
31#include <asm/kgdb.h>
32
33extern void die(const char *,struct pt_regs *,long);
34
35/*
36 * This routine handles page faults. It determines the address,
37 * and the problem, and then passes it off to one of the appropriate
38 * routines.
39 */
40asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
41 unsigned long address)
42{
43 struct task_struct *tsk;
44 struct mm_struct *mm;
45 struct vm_area_struct * vma;
46 unsigned long page;
47
48#ifdef CONFIG_SH_KGDB
49 if (kgdb_nofault && kgdb_bus_err_hook)
50 kgdb_bus_err_hook();
51#endif
52
53 tsk = current;
54 mm = tsk->mm;
55
56 /*
57 * If we're in an interrupt or have no user
58 * context, we must not take the fault..
59 */
60 if (in_atomic() || !mm)
61 goto no_context;
62
63 down_read(&mm->mmap_sem);
64
65 vma = find_vma(mm, address);
66 if (!vma)
67 goto bad_area;
68 if (vma->vm_start <= address)
69 goto good_area;
70 if (!(vma->vm_flags & VM_GROWSDOWN))
71 goto bad_area;
72 if (expand_stack(vma, address))
73 goto bad_area;
74/*
75 * Ok, we have a good vm_area for this memory access, so
76 * we can handle it..
77 */
78good_area:
79 if (writeaccess) {
80 if (!(vma->vm_flags & VM_WRITE))
81 goto bad_area;
82 } else {
83 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
84 goto bad_area;
85 }
86
87 /*
88 * If for any reason at all we couldn't handle the fault,
89 * make sure we exit gracefully rather than endlessly redo
90 * the fault.
91 */
92survive:
93 switch (handle_mm_fault(mm, vma, address, writeaccess)) {
94 case VM_FAULT_MINOR:
95 tsk->min_flt++;
96 break;
97 case VM_FAULT_MAJOR:
98 tsk->maj_flt++;
99 break;
100 case VM_FAULT_SIGBUS:
101 goto do_sigbus;
102 case VM_FAULT_OOM:
103 goto out_of_memory;
104 default:
105 BUG();
106 }
107
108 up_read(&mm->mmap_sem);
109 return;
110
111/*
112 * Something tried to access memory that isn't in our memory map..
113 * Fix it, but check if it's kernel or user first..
114 */
115bad_area:
116 up_read(&mm->mmap_sem);
117
118 if (user_mode(regs)) {
119 tsk->thread.address = address;
120 tsk->thread.error_code = writeaccess;
121 force_sig(SIGSEGV, tsk);
122 return;
123 }
124
125no_context:
126 /* Are we prepared to handle this kernel fault? */
127 if (fixup_exception(regs))
128 return;
129
130/*
131 * Oops. The kernel tried to access some bad page. We'll have to
132 * terminate things with extreme prejudice.
133 *
134 */
135 if (address < PAGE_SIZE)
136 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
137 else
138 printk(KERN_ALERT "Unable to handle kernel paging request");
139 printk(" at virtual address %08lx\n", address);
140 printk(KERN_ALERT "pc = %08lx\n", regs->pc);
141 asm volatile("mov.l %1, %0"
142 : "=r" (page)
143 : "m" (__m(MMU_TTB)));
144 if (page) {
145 page = ((unsigned long *) page)[address >> 22];
146 printk(KERN_ALERT "*pde = %08lx\n", page);
147 if (page & _PAGE_PRESENT) {
148 page &= PAGE_MASK;
149 address &= 0x003ff000;
150 page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
151 printk(KERN_ALERT "*pte = %08lx\n", page);
152 }
153 }
154 die("Oops", regs, writeaccess);
155 do_exit(SIGKILL);
156
157/*
158 * We ran out of memory, or some other thing happened to us that made
159 * us unable to handle the page fault gracefully.
160 */
161out_of_memory:
162 up_read(&mm->mmap_sem);
163 if (current->pid == 1) {
164 yield();
165 down_read(&mm->mmap_sem);
166 goto survive;
167 }
168 printk("VM: killing process %s\n", tsk->comm);
169 if (user_mode(regs))
170 do_exit(SIGKILL);
171 goto no_context;
172
173do_sigbus:
174 up_read(&mm->mmap_sem);
175
176 /*
177 * Send a sigbus, regardless of whether we were in kernel
178 * or user mode.
179 */
180 tsk->thread.address = address;
181 tsk->thread.error_code = writeaccess;
182 tsk->thread.trap_no = 14;
183 force_sig(SIGBUS, tsk);
184
185 /* Kernel mode? Handle exceptions or die */
186 if (!user_mode(regs))
187 goto no_context;
188}
189
190/*
191 * Called with interrupt disabled.
192 */
193asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
194 unsigned long address)
195{
196 unsigned long addrmax = P4SEG;
197 pgd_t *dir;
198 pmd_t *pmd;
199 pte_t *pte;
200 pte_t entry;
201
202#ifdef CONFIG_SH_KGDB
203 if (kgdb_nofault && kgdb_bus_err_hook)
204 kgdb_bus_err_hook();
205#endif
206
207#ifdef CONFIG_SH_STORE_QUEUES
208 addrmax = P4SEG_STORE_QUE + 0x04000000;
209#endif
210
211 if (address >= P3SEG && address < addrmax)
212 dir = pgd_offset_k(address);
213 else if (address >= TASK_SIZE)
214 return 1;
215 else if (!current->mm)
216 return 1;
217 else
218 dir = pgd_offset(current->mm, address);
219
220 pmd = pmd_offset(dir, address);
221 if (pmd_none(*pmd))
222 return 1;
223 if (pmd_bad(*pmd)) {
224 pmd_ERROR(*pmd);
225 pmd_clear(pmd);
226 return 1;
227 }
228 pte = pte_offset_kernel(pmd, address);
229 entry = *pte;
230 if (pte_none(entry) || pte_not_present(entry)
231 || (writeaccess && !pte_write(entry)))
232 return 1;
233
234 if (writeaccess)
235 entry = pte_mkdirty(entry);
236 entry = pte_mkyoung(entry);
237
238#ifdef CONFIG_CPU_SH4
239 /*
240 * ITLB is not affected by "ldtlb" instruction.
241 * So, we need to flush the entry by ourselves.
242 */
243
244 {
245 unsigned long flags;
246 local_irq_save(flags);
247 __flush_tlb_page(get_asid(), address&PAGE_MASK);
248 local_irq_restore(flags);
249 }
250#endif
251
252 set_pte(pte, entry);
253 update_mmu_cache(NULL, address, entry);
254
255 return 0;
256}
257
258void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
259{
260 if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) {
261 unsigned long flags;
262 unsigned long asid;
263 unsigned long saved_asid = MMU_NO_ASID;
264
265 asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
266 page &= PAGE_MASK;
267
268 local_irq_save(flags);
269 if (vma->vm_mm != current->mm) {
270 saved_asid = get_asid();
271 set_asid(asid);
272 }
273 __flush_tlb_page(asid, page);
274 if (saved_asid != MMU_NO_ASID)
275 set_asid(saved_asid);
276 local_irq_restore(flags);
277 }
278}
279
280void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
281 unsigned long end)
282{
283 struct mm_struct *mm = vma->vm_mm;
284
285 if (mm->context != NO_CONTEXT) {
286 unsigned long flags;
287 int size;
288
289 local_irq_save(flags);
290 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
291 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
292 mm->context = NO_CONTEXT;
293 if (mm == current->mm)
294 activate_context(mm);
295 } else {
296 unsigned long asid = mm->context&MMU_CONTEXT_ASID_MASK;
297 unsigned long saved_asid = MMU_NO_ASID;
298
299 start &= PAGE_MASK;
300 end += (PAGE_SIZE - 1);
301 end &= PAGE_MASK;
302 if (mm != current->mm) {
303 saved_asid = get_asid();
304 set_asid(asid);
305 }
306 while (start < end) {
307 __flush_tlb_page(asid, start);
308 start += PAGE_SIZE;
309 }
310 if (saved_asid != MMU_NO_ASID)
311 set_asid(saved_asid);
312 }
313 local_irq_restore(flags);
314 }
315}
316
317void flush_tlb_kernel_range(unsigned long start, unsigned long end)
318{
319 unsigned long flags;
320 int size;
321
322 local_irq_save(flags);
323 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
324 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
325 flush_tlb_all();
326 } else {
327 unsigned long asid = init_mm.context&MMU_CONTEXT_ASID_MASK;
328 unsigned long saved_asid = get_asid();
329
330 start &= PAGE_MASK;
331 end += (PAGE_SIZE - 1);
332 end &= PAGE_MASK;
333 set_asid(asid);
334 while (start < end) {
335 __flush_tlb_page(asid, start);
336 start += PAGE_SIZE;
337 }
338 set_asid(saved_asid);
339 }
340 local_irq_restore(flags);
341}
342
343void flush_tlb_mm(struct mm_struct *mm)
344{
345 /* Invalidate all TLB of this process. */
346 /* Instead of invalidating each TLB, we get new MMU context. */
347 if (mm->context != NO_CONTEXT) {
348 unsigned long flags;
349
350 local_irq_save(flags);
351 mm->context = NO_CONTEXT;
352 if (mm == current->mm)
353 activate_context(mm);
354 local_irq_restore(flags);
355 }
356}
357
358void flush_tlb_all(void)
359{
360 unsigned long flags, status;
361
362 /*
363 * Flush all the TLB.
364 *
365 * Write to the MMU control register's bit:
366 * TF-bit for SH-3, TI-bit for SH-4.
367 * It's same position, bit #2.
368 */
369 local_irq_save(flags);
370 status = ctrl_inl(MMUCR);
371 status |= 0x04;
372 ctrl_outl(status, MMUCR);
373 local_irq_restore(flags);
374}
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
new file mode 100644
index 000000000000..1f897bab2318
--- /dev/null
+++ b/arch/sh/mm/hugetlbpage.c
@@ -0,0 +1,264 @@
1/*
2 * arch/sh/mm/hugetlbpage.c
3 *
4 * SuperH HugeTLB page support.
5 *
6 * Cloned from sparc64 by Paul Mundt.
7 *
8 * Copyright (C) 2002, 2003 David S. Miller (davem@redhat.com)
9 */
10
11#include <linux/config.h>
12#include <linux/init.h>
13#include <linux/fs.h>
14#include <linux/mm.h>
15#include <linux/hugetlb.h>
16#include <linux/pagemap.h>
17#include <linux/smp_lock.h>
18#include <linux/slab.h>
19#include <linux/sysctl.h>
20
21#include <asm/mman.h>
22#include <asm/pgalloc.h>
23#include <asm/tlb.h>
24#include <asm/tlbflush.h>
25#include <asm/cacheflush.h>
26
27static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
28{
29 pgd_t *pgd;
30 pmd_t *pmd;
31 pte_t *pte = NULL;
32
33 pgd = pgd_offset(mm, addr);
34 if (pgd) {
35 pmd = pmd_alloc(mm, pgd, addr);
36 if (pmd)
37 pte = pte_alloc_map(mm, pmd, addr);
38 }
39 return pte;
40}
41
42static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
43{
44 pgd_t *pgd;
45 pmd_t *pmd;
46 pte_t *pte = NULL;
47
48 pgd = pgd_offset(mm, addr);
49 if (pgd) {
50 pmd = pmd_offset(pgd, addr);
51 if (pmd)
52 pte = pte_offset_map(pmd, addr);
53 }
54 return pte;
55}
56
57#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
58
59static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
60 struct page *page, pte_t * page_table, int write_access)
61{
62 unsigned long i;
63 pte_t entry;
64
65 add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
66
67 if (write_access)
68 entry = pte_mkwrite(pte_mkdirty(mk_pte(page,
69 vma->vm_page_prot)));
70 else
71 entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
72 entry = pte_mkyoung(entry);
73 mk_pte_huge(entry);
74
75 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
76 set_pte(page_table, entry);
77 page_table++;
78
79 pte_val(entry) += PAGE_SIZE;
80 }
81}
82
83/*
84 * This function checks for proper alignment of input addr and len parameters.
85 */
86int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
87{
88 if (len & ~HPAGE_MASK)
89 return -EINVAL;
90 if (addr & ~HPAGE_MASK)
91 return -EINVAL;
92 return 0;
93}
94
95int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
96 struct vm_area_struct *vma)
97{
98 pte_t *src_pte, *dst_pte, entry;
99 struct page *ptepage;
100 unsigned long addr = vma->vm_start;
101 unsigned long end = vma->vm_end;
102 int i;
103
104 while (addr < end) {
105 dst_pte = huge_pte_alloc(dst, addr);
106 if (!dst_pte)
107 goto nomem;
108 src_pte = huge_pte_offset(src, addr);
109 BUG_ON(!src_pte || pte_none(*src_pte));
110 entry = *src_pte;
111 ptepage = pte_page(entry);
112 get_page(ptepage);
113 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
114 set_pte(dst_pte, entry);
115 pte_val(entry) += PAGE_SIZE;
116 dst_pte++;
117 }
118 add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
119 addr += HPAGE_SIZE;
120 }
121 return 0;
122
123nomem:
124 return -ENOMEM;
125}
126
127int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
128 struct page **pages, struct vm_area_struct **vmas,
129 unsigned long *position, int *length, int i)
130{
131 unsigned long vaddr = *position;
132 int remainder = *length;
133
134 WARN_ON(!is_vm_hugetlb_page(vma));
135
136 while (vaddr < vma->vm_end && remainder) {
137 if (pages) {
138 pte_t *pte;
139 struct page *page;
140
141 pte = huge_pte_offset(mm, vaddr);
142
143 /* hugetlb should be locked, and hence, prefaulted */
144 BUG_ON(!pte || pte_none(*pte));
145
146 page = pte_page(*pte);
147
148 WARN_ON(!PageCompound(page));
149
150 get_page(page);
151 pages[i] = page;
152 }
153
154 if (vmas)
155 vmas[i] = vma;
156
157 vaddr += PAGE_SIZE;
158 --remainder;
159 ++i;
160 }
161
162 *length = remainder;
163 *position = vaddr;
164
165 return i;
166}
167
168struct page *follow_huge_addr(struct mm_struct *mm,
169 unsigned long address, int write)
170{
171 return ERR_PTR(-EINVAL);
172}
173
174int pmd_huge(pmd_t pmd)
175{
176 return 0;
177}
178
179struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
180 pmd_t *pmd, int write)
181{
182 return NULL;
183}
184
185void unmap_hugepage_range(struct vm_area_struct *vma,
186 unsigned long start, unsigned long end)
187{
188 struct mm_struct *mm = vma->vm_mm;
189 unsigned long address;
190 pte_t *pte;
191 struct page *page;
192 int i;
193
194 BUG_ON(start & (HPAGE_SIZE - 1));
195 BUG_ON(end & (HPAGE_SIZE - 1));
196
197 for (address = start; address < end; address += HPAGE_SIZE) {
198 pte = huge_pte_offset(mm, address);
199 BUG_ON(!pte);
200 if (pte_none(*pte))
201 continue;
202 page = pte_page(*pte);
203 put_page(page);
204 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
205 pte_clear(mm, address+(i*PAGE_SIZE), pte);
206 pte++;
207 }
208 }
209 add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
210 flush_tlb_range(vma, start, end);
211}
212
213int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
214{
215 struct mm_struct *mm = current->mm;
216 unsigned long addr;
217 int ret = 0;
218
219 BUG_ON(vma->vm_start & ~HPAGE_MASK);
220 BUG_ON(vma->vm_end & ~HPAGE_MASK);
221
222 spin_lock(&mm->page_table_lock);
223 for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
224 unsigned long idx;
225 pte_t *pte = huge_pte_alloc(mm, addr);
226 struct page *page;
227
228 if (!pte) {
229 ret = -ENOMEM;
230 goto out;
231 }
232 if (!pte_none(*pte))
233 continue;
234
235 idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
236 + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
237 page = find_get_page(mapping, idx);
238 if (!page) {
239 /* charge the fs quota first */
240 if (hugetlb_get_quota(mapping)) {
241 ret = -ENOMEM;
242 goto out;
243 }
244 page = alloc_huge_page();
245 if (!page) {
246 hugetlb_put_quota(mapping);
247 ret = -ENOMEM;
248 goto out;
249 }
250 ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
251 if (! ret) {
252 unlock_page(page);
253 } else {
254 hugetlb_put_quota(mapping);
255 free_huge_page(page);
256 goto out;
257 }
258 }
259 set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
260 }
261out:
262 spin_unlock(&mm->page_table_lock);
263 return ret;
264}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
new file mode 100644
index 000000000000..4e9c854845a4
--- /dev/null
+++ b/arch/sh/mm/init.c
@@ -0,0 +1,313 @@
1/* $Id: init.c,v 1.19 2004/02/21 04:42:16 kkojima Exp $
2 *
3 * linux/arch/sh/mm/init.c
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2002, 2004 Paul Mundt
7 *
8 * Based on linux/arch/i386/mm/init.c:
9 * Copyright (C) 1995 Linus Torvalds
10 */
11
12#include <linux/config.h>
13#include <linux/signal.h>
14#include <linux/sched.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/string.h>
18#include <linux/types.h>
19#include <linux/ptrace.h>
20#include <linux/mman.h>
21#include <linux/mm.h>
22#include <linux/swap.h>
23#include <linux/smp.h>
24#include <linux/init.h>
25#include <linux/highmem.h>
26#include <linux/bootmem.h>
27#include <linux/pagemap.h>
28
29#include <asm/processor.h>
30#include <asm/system.h>
31#include <asm/uaccess.h>
32#include <asm/pgtable.h>
33#include <asm/pgalloc.h>
34#include <asm/mmu_context.h>
35#include <asm/io.h>
36#include <asm/tlb.h>
37#include <asm/cacheflush.h>
38#include <asm/cache.h>
39
40DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
41pgd_t swapper_pg_dir[PTRS_PER_PGD];
42
43/*
44 * Cache of MMU context last used.
45 */
46unsigned long mmu_context_cache = NO_CONTEXT;
47
48#ifdef CONFIG_MMU
49/* It'd be good if these lines were in the standard header file. */
50#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
51#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
52#endif
53
54#ifdef CONFIG_DISCONTIGMEM
55pg_data_t discontig_page_data[MAX_NUMNODES];
56bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
57#endif
58
59void (*copy_page)(void *from, void *to);
60void (*clear_page)(void *to);
61
62void show_mem(void)
63{
64 int i, total = 0, reserved = 0;
65 int shared = 0, cached = 0;
66
67 printk("Mem-info:\n");
68 show_free_areas();
69 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
70 i = max_mapnr;
71 while (i-- > 0) {
72 total++;
73 if (PageReserved(mem_map+i))
74 reserved++;
75 else if (PageSwapCache(mem_map+i))
76 cached++;
77 else if (page_count(mem_map+i))
78 shared += page_count(mem_map+i) - 1;
79 }
80 printk("%d pages of RAM\n",total);
81 printk("%d reserved pages\n",reserved);
82 printk("%d pages shared\n",shared);
83 printk("%d pages swap cached\n",cached);
84}
85
86static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
87{
88 pgd_t *pgd;
89 pmd_t *pmd;
90 pte_t *pte;
91
92 pgd = swapper_pg_dir + pgd_index(addr);
93 if (pgd_none(*pgd)) {
94 pgd_ERROR(*pgd);
95 return;
96 }
97
98 pmd = pmd_offset(pgd, addr);
99 if (pmd_none(*pmd)) {
100 pte = (pte_t *)get_zeroed_page(GFP_ATOMIC);
101 set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
102 if (pte != pte_offset_kernel(pmd, 0)) {
103 pmd_ERROR(*pmd);
104 return;
105 }
106 }
107
108 pte = pte_offset_kernel(pmd, addr);
109 if (!pte_none(*pte)) {
110 pte_ERROR(*pte);
111 return;
112 }
113
114 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
115
116 __flush_tlb_page(get_asid(), addr);
117}
118
119/*
120 * As a performance optimization, other platforms preserve the fixmap mapping
121 * across a context switch, we don't presently do this, but this could be done
122 * in a similar fashion as to the wired TLB interface that sh64 uses (by way
123 * of the memorry mapped UTLB configuration) -- this unfortunately forces us to
124 * give up a TLB entry for each mapping we want to preserve. While this may be
125 * viable for a small number of fixmaps, it's not particularly useful for
126 * everything and needs to be carefully evaluated. (ie, we may want this for
127 * the vsyscall page).
128 *
129 * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass
130 * in at __set_fixmap() time to determine the appropriate behavior to follow.
131 *
132 * -- PFM.
133 */
134void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
135{
136 unsigned long address = __fix_to_virt(idx);
137
138 if (idx >= __end_of_fixed_addresses) {
139 BUG();
140 return;
141 }
142
143 set_pte_phys(address, phys, prot);
144}
145
146/* References to section boundaries */
147
148extern char _text, _etext, _edata, __bss_start, _end;
149extern char __init_begin, __init_end;
150
151/*
152 * paging_init() sets up the page tables
153 *
154 * This routines also unmaps the page at virtual kernel address 0, so
155 * that we can trap those pesky NULL-reference errors in the kernel.
156 */
157void __init paging_init(void)
158{
159 unsigned long zones_size[MAX_NR_ZONES] = { 0, };
160
161 /*
162 * Setup some defaults for the zone sizes.. these should be safe
163 * regardless of distcontiguous memory or MMU settings.
164 */
165 zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
166 zones_size[ZONE_NORMAL] = __MEMORY_SIZE >> PAGE_SHIFT;
167#ifdef CONFIG_HIGHMEM
168 zones_size[ZONE_HIGHMEM] = 0 >> PAGE_SHIFT;
169#endif
170
171#ifdef CONFIG_MMU
172 /*
173 * If we have an MMU, and want to be using it .. we need to adjust
174 * the zone sizes accordingly, in addition to turning it on.
175 */
176 {
177 unsigned long max_dma, low, start_pfn;
178 pgd_t *pg_dir;
179 int i;
180
181 /* We don't need kernel mapping as hardware support that. */
182 pg_dir = swapper_pg_dir;
183
184 for (i = 0; i < PTRS_PER_PGD; i++)
185 pgd_val(pg_dir[i]) = 0;
186
187 /* Turn on the MMU */
188 enable_mmu();
189
190 /* Fixup the zone sizes */
191 start_pfn = START_PFN;
192 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
193 low = MAX_LOW_PFN;
194
195 if (low < max_dma) {
196 zones_size[ZONE_DMA] = low - start_pfn;
197 zones_size[ZONE_NORMAL] = 0;
198 } else {
199 zones_size[ZONE_DMA] = max_dma - start_pfn;
200 zones_size[ZONE_NORMAL] = low - max_dma;
201 }
202 }
203
204#elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4)
205 /*
206 * If we don't have CONFIG_MMU set and the processor in question
207 * still has an MMU, care needs to be taken to make sure it doesn't
208 * stay on.. Since the boot loader could have potentially already
209 * turned it on, and we clearly don't want it, we simply turn it off.
210 *
211 * We don't need to do anything special for the zone sizes, since the
212 * default values that were already configured up above should be
213 * satisfactory.
214 */
215 disable_mmu();
216#endif
217 NODE_DATA(0)->node_mem_map = NULL;
218 free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
219
220#ifdef CONFIG_DISCONTIGMEM
221 /*
222 * And for discontig, do some more fixups on the zone sizes..
223 */
224 zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
225 zones_size[ZONE_NORMAL] = 0;
226 free_area_init_node(1, NODE_DATA(1), zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0);
227#endif
228}
229
230void __init mem_init(void)
231{
232 extern unsigned long empty_zero_page[1024];
233 int codesize, reservedpages, datasize, initsize;
234 int tmp;
235 extern unsigned long memory_start;
236
237#ifdef CONFIG_MMU
238 high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE);
239#else
240 extern unsigned long memory_end;
241
242 high_memory = (void *)(memory_end & PAGE_MASK);
243#endif
244
245 max_mapnr = num_physpages = MAP_NR(high_memory) - MAP_NR(memory_start);
246
247 /* clear the zero-page */
248 memset(empty_zero_page, 0, PAGE_SIZE);
249 __flush_wback_region(empty_zero_page, PAGE_SIZE);
250
251 /*
252 * Setup wrappers for copy/clear_page(), these will get overridden
253 * later in the boot process if a better method is available.
254 */
255 copy_page = copy_page_slow;
256 clear_page = clear_page_slow;
257
258 /* this will put all low memory onto the freelists */
259 totalram_pages += free_all_bootmem_node(NODE_DATA(0));
260#ifdef CONFIG_DISCONTIGMEM
261 totalram_pages += free_all_bootmem_node(NODE_DATA(1));
262#endif
263 reservedpages = 0;
264 for (tmp = 0; tmp < num_physpages; tmp++)
265 /*
266 * Only count reserved RAM pages
267 */
268 if (PageReserved(mem_map+tmp))
269 reservedpages++;
270
271 codesize = (unsigned long) &_etext - (unsigned long) &_text;
272 datasize = (unsigned long) &_edata - (unsigned long) &_etext;
273 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
274
275 printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
276 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
277 max_mapnr << (PAGE_SHIFT-10),
278 codesize >> 10,
279 reservedpages << (PAGE_SHIFT-10),
280 datasize >> 10,
281 initsize >> 10);
282
283 p3_cache_init();
284}
285
286void free_initmem(void)
287{
288 unsigned long addr;
289
290 addr = (unsigned long)(&__init_begin);
291 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
292 ClearPageReserved(virt_to_page(addr));
293 set_page_count(virt_to_page(addr), 1);
294 free_page(addr);
295 totalram_pages++;
296 }
297 printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
298}
299
300#ifdef CONFIG_BLK_DEV_INITRD
301void free_initrd_mem(unsigned long start, unsigned long end)
302{
303 unsigned long p;
304 for (p = start; p < end; p += PAGE_SIZE) {
305 ClearPageReserved(virt_to_page(p));
306 set_page_count(virt_to_page(p), 1);
307 free_page(p);
308 totalram_pages++;
309 }
310 printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
311}
312#endif
313
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
new file mode 100644
index 000000000000..9f490c2742f0
--- /dev/null
+++ b/arch/sh/mm/ioremap.c
@@ -0,0 +1,163 @@
1/*
2 * arch/sh/mm/ioremap.c
3 *
4 * Re-map IO memory to kernel address space so that we can access it.
5 * This is needed for high PCI addresses that aren't mapped in the
6 * 640k-1MB IO memory area on PC's
7 *
8 * (C) Copyright 1995 1996 Linus Torvalds
9 */
10
11#include <linux/vmalloc.h>
12#include <linux/mm.h>
13#include <asm/io.h>
14#include <asm/page.h>
15#include <asm/pgalloc.h>
16#include <asm/cacheflush.h>
17#include <asm/tlbflush.h>
18
19static inline void remap_area_pte(pte_t * pte, unsigned long address,
20 unsigned long size, unsigned long phys_addr, unsigned long flags)
21{
22 unsigned long end;
23 unsigned long pfn;
24 pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW |
25 _PAGE_DIRTY | _PAGE_ACCESSED |
26 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | flags);
27
28 address &= ~PMD_MASK;
29 end = address + size;
30 if (end > PMD_SIZE)
31 end = PMD_SIZE;
32 if (address >= end)
33 BUG();
34 pfn = phys_addr >> PAGE_SHIFT;
35 do {
36 if (!pte_none(*pte)) {
37 printk("remap_area_pte: page already exists\n");
38 BUG();
39 }
40 set_pte(pte, pfn_pte(pfn, pgprot));
41 address += PAGE_SIZE;
42 pfn++;
43 pte++;
44 } while (address && (address < end));
45}
46
47static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
48 unsigned long size, unsigned long phys_addr, unsigned long flags)
49{
50 unsigned long end;
51
52 address &= ~PGDIR_MASK;
53 end = address + size;
54 if (end > PGDIR_SIZE)
55 end = PGDIR_SIZE;
56 phys_addr -= address;
57 if (address >= end)
58 BUG();
59 do {
60 pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
61 if (!pte)
62 return -ENOMEM;
63 remap_area_pte(pte, address, end - address, address + phys_addr, flags);
64 address = (address + PMD_SIZE) & PMD_MASK;
65 pmd++;
66 } while (address && (address < end));
67 return 0;
68}
69
70int remap_area_pages(unsigned long address, unsigned long phys_addr,
71 unsigned long size, unsigned long flags)
72{
73 int error;
74 pgd_t * dir;
75 unsigned long end = address + size;
76
77 phys_addr -= address;
78 dir = pgd_offset_k(address);
79 flush_cache_all();
80 if (address >= end)
81 BUG();
82 spin_lock(&init_mm.page_table_lock);
83 do {
84 pmd_t *pmd;
85 pmd = pmd_alloc(&init_mm, dir, address);
86 error = -ENOMEM;
87 if (!pmd)
88 break;
89 if (remap_area_pmd(pmd, address, end - address,
90 phys_addr + address, flags))
91 break;
92 error = 0;
93 address = (address + PGDIR_SIZE) & PGDIR_MASK;
94 dir++;
95 } while (address && (address < end));
96 spin_unlock(&init_mm.page_table_lock);
97 flush_tlb_all();
98 return error;
99}
100
101/*
102 * Generic mapping function (not visible outside):
103 */
104
105/*
106 * Remap an arbitrary physical address space into the kernel virtual
107 * address space. Needed when the kernel wants to access high addresses
108 * directly.
109 *
110 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
111 * have to convert them into an offset in a page-aligned mapping, but the
112 * caller shouldn't need to know that small detail.
113 */
114void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
115{
116 void * addr;
117 struct vm_struct * area;
118 unsigned long offset, last_addr;
119
120 /* Don't allow wraparound or zero size */
121 last_addr = phys_addr + size - 1;
122 if (!size || last_addr < phys_addr)
123 return NULL;
124
125 /*
126 * Don't remap the low PCI/ISA area, it's always mapped..
127 */
128 if (phys_addr >= 0xA0000 && last_addr < 0x100000)
129 return phys_to_virt(phys_addr);
130
131 /*
132 * Don't allow anybody to remap normal RAM that we're using..
133 */
134 if (phys_addr < virt_to_phys(high_memory))
135 return NULL;
136
137 /*
138 * Mappings have to be page-aligned
139 */
140 offset = phys_addr & ~PAGE_MASK;
141 phys_addr &= PAGE_MASK;
142 size = PAGE_ALIGN(last_addr+1) - phys_addr;
143
144 /*
145 * Ok, go for it..
146 */
147 area = get_vm_area(size, VM_IOREMAP);
148 if (!area)
149 return NULL;
150 area->phys_addr = phys_addr;
151 addr = area->addr;
152 if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
153 vunmap(addr);
154 return NULL;
155 }
156 return (void *) (offset + (char *)addr);
157}
158
159void p3_iounmap(void *addr)
160{
161 if (addr > high_memory)
162 vfree((void *)(PAGE_MASK & (unsigned long)addr));
163}
diff --git a/arch/sh/mm/pg-dma.c b/arch/sh/mm/pg-dma.c
new file mode 100644
index 000000000000..1406d2e348ca
--- /dev/null
+++ b/arch/sh/mm/pg-dma.c
@@ -0,0 +1,97 @@
1/*
2 * arch/sh/mm/pg-dma.c
3 *
4 * Fast clear_page()/copy_page() implementation using the SH DMAC
5 *
6 * Copyright (C) 2003 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <asm/semaphore.h>
16#include <asm/mmu_context.h>
17#include <asm/addrspace.h>
18#include <asm/atomic.h>
19#include <asm/page.h>
20#include <asm/dma.h>
21#include <asm/io.h>
22
23/* Channel to use for page ops, must be dual-address mode capable. */
24static int dma_channel = CONFIG_DMA_PAGE_OPS_CHANNEL;
25
26static void copy_page_dma(void *to, void *from)
27{
28 /*
29 * This doesn't seem to get triggered until further along in the
30 * boot process, at which point the DMAC is already initialized.
31 * Fix this in the same fashion as clear_page_dma() in the event
32 * that this crashes due to the DMAC not being initialized.
33 */
34
35 flush_icache_range((unsigned long)from, PAGE_SIZE);
36 dma_write_page(dma_channel, (unsigned long)from, (unsigned long)to);
37 dma_wait_for_completion(dma_channel);
38}
39
40static void clear_page_dma(void *to)
41{
42 extern unsigned long empty_zero_page[1024];
43
44 /*
45 * We get invoked quite early on, if the DMAC hasn't been initialized
46 * yet, fall back on the slow manual implementation.
47 */
48 if (dma_info[dma_channel].chan != dma_channel) {
49 clear_page_slow(to);
50 return;
51 }
52
53 dma_write_page(dma_channel, (unsigned long)empty_zero_page,
54 (unsigned long)to);
55
56 /*
57 * FIXME: Something is a bit racy here, if we poll the counter right
58 * away, we seem to lock. flushing the page from the dcache doesn't
59 * seem to make a difference one way or the other, though either a full
60 * icache or dcache flush does.
61 *
62 * The location of this is important as well, and must happen prior to
63 * the completion loop but after the transfer was initiated.
64 *
65 * Oddly enough, this doesn't appear to be an issue for copy_page()..
66 */
67 flush_icache_range((unsigned long)to, PAGE_SIZE);
68
69 dma_wait_for_completion(dma_channel);
70}
71
72static int __init pg_dma_init(void)
73{
74 int ret;
75
76 ret = request_dma(dma_channel, "page ops");
77 if (ret != 0)
78 return ret;
79
80 copy_page = copy_page_dma;
81 clear_page = clear_page_dma;
82
83 return ret;
84}
85
86static void __exit pg_dma_exit(void)
87{
88 free_dma(dma_channel);
89}
90
91module_init(pg_dma_init);
92module_exit(pg_dma_exit);
93
94MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
95MODULE_DESCRIPTION("Optimized page copy/clear routines using a dual-address mode capable DMAC channel");
96MODULE_LICENSE("GPL");
97
diff --git a/arch/sh/mm/pg-nommu.c b/arch/sh/mm/pg-nommu.c
new file mode 100644
index 000000000000..8f9165a4e333
--- /dev/null
+++ b/arch/sh/mm/pg-nommu.c
@@ -0,0 +1,36 @@
1/*
2 * arch/sh/mm/pg-nommu.c
3 *
4 * clear_page()/copy_page() implementation for MMUless SH.
5 *
6 * Copyright (C) 2003 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/string.h>
15#include <asm/page.h>
16
17static void copy_page_nommu(void *to, void *from)
18{
19 memcpy(to, from, PAGE_SIZE);
20}
21
22static void clear_page_nommu(void *to)
23{
24 memset(to, 0, PAGE_SIZE);
25}
26
27static int __init pg_nommu_init(void)
28{
29 copy_page = copy_page_nommu;
30 clear_page = clear_page_nommu;
31
32 return 0;
33}
34
35subsys_initcall(pg_nommu_init);
36
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
new file mode 100644
index 000000000000..e5907c7330e5
--- /dev/null
+++ b/arch/sh/mm/pg-sh4.c
@@ -0,0 +1,122 @@
1/*
2 * arch/sh/mm/pg-sh4.c
3 *
4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2002 Paul Mundt
6 *
7 * Released under the terms of the GNU GPL v2.0.
8 */
9#include <linux/config.h>
10#include <linux/init.h>
11#include <linux/mman.h>
12#include <linux/mm.h>
13#include <linux/threads.h>
14#include <asm/addrspace.h>
15#include <asm/page.h>
16#include <asm/pgtable.h>
17#include <asm/processor.h>
18#include <asm/cache.h>
19#include <asm/io.h>
20#include <asm/uaccess.h>
21#include <asm/pgalloc.h>
22#include <asm/mmu_context.h>
23#include <asm/cacheflush.h>
24
25extern struct semaphore p3map_sem[];
26
27/*
28 * clear_user_page
29 * @to: P1 address
30 * @address: U0 address to be mapped
31 * @page: page (virt_to_page(to))
32 */
33void clear_user_page(void *to, unsigned long address, struct page *page)
34{
35 __set_bit(PG_mapped, &page->flags);
36 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
37 clear_page(to);
38 else {
39 pgprot_t pgprot = __pgprot(_PAGE_PRESENT |
40 _PAGE_RW | _PAGE_CACHABLE |
41 _PAGE_DIRTY | _PAGE_ACCESSED |
42 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
43 unsigned long phys_addr = PHYSADDR(to);
44 unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
45 pgd_t *dir = pgd_offset_k(p3_addr);
46 pmd_t *pmd = pmd_offset(dir, p3_addr);
47 pte_t *pte = pte_offset_kernel(pmd, p3_addr);
48 pte_t entry;
49 unsigned long flags;
50
51 entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot);
52 down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
53 set_pte(pte, entry);
54 local_irq_save(flags);
55 __flush_tlb_page(get_asid(), p3_addr);
56 local_irq_restore(flags);
57 update_mmu_cache(NULL, p3_addr, entry);
58 __clear_user_page((void *)p3_addr, to);
59 pte_clear(&init_mm, p3_addr, pte);
60 up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
61 }
62}
63
64/*
65 * copy_user_page
66 * @to: P1 address
67 * @from: P1 address
68 * @address: U0 address to be mapped
69 * @page: page (virt_to_page(to))
70 */
71void copy_user_page(void *to, void *from, unsigned long address,
72 struct page *page)
73{
74 __set_bit(PG_mapped, &page->flags);
75 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
76 copy_page(to, from);
77 else {
78 pgprot_t pgprot = __pgprot(_PAGE_PRESENT |
79 _PAGE_RW | _PAGE_CACHABLE |
80 _PAGE_DIRTY | _PAGE_ACCESSED |
81 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
82 unsigned long phys_addr = PHYSADDR(to);
83 unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
84 pgd_t *dir = pgd_offset_k(p3_addr);
85 pmd_t *pmd = pmd_offset(dir, p3_addr);
86 pte_t *pte = pte_offset_kernel(pmd, p3_addr);
87 pte_t entry;
88 unsigned long flags;
89
90 entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot);
91 down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
92 set_pte(pte, entry);
93 local_irq_save(flags);
94 __flush_tlb_page(get_asid(), p3_addr);
95 local_irq_restore(flags);
96 update_mmu_cache(NULL, p3_addr, entry);
97 __copy_user_page((void *)p3_addr, from, to);
98 pte_clear(&init_mm, p3_addr, pte);
99 up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
100 }
101}
102
103/*
104 * For SH-4, we have our own implementation for ptep_get_and_clear
105 */
106inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
107{
108 pte_t pte = *ptep;
109
110 pte_clear(mm, addr, ptep);
111 if (!pte_not_present(pte)) {
112 unsigned long pfn = pte_pfn(pte);
113 if (pfn_valid(pfn)) {
114 struct page *page = pfn_to_page(pfn);
115 struct address_space *mapping = page_mapping(page);
116 if (!mapping || !mapping_writably_mapped(mapping))
117 __clear_bit(PG_mapped, &page->flags);
118 }
119 }
120 return pte;
121}
122
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
new file mode 100644
index 000000000000..ff9ece986cbc
--- /dev/null
+++ b/arch/sh/mm/pg-sh7705.c
@@ -0,0 +1,137 @@
1/*
2 * arch/sh/mm/pg-sh7705.c
3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2004 Alex Song
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 */
12
13#include <linux/init.h>
14#include <linux/mman.h>
15#include <linux/mm.h>
16#include <linux/threads.h>
17#include <asm/addrspace.h>
18#include <asm/page.h>
19#include <asm/pgtable.h>
20#include <asm/processor.h>
21#include <asm/cache.h>
22#include <asm/io.h>
23#include <asm/uaccess.h>
24#include <asm/pgalloc.h>
25#include <asm/mmu_context.h>
26#include <asm/cacheflush.h>
27
28static inline void __flush_purge_virtual_region(void *p1, void *virt, int size)
29{
30 unsigned long v;
31 unsigned long begin, end;
32 unsigned long p1_begin;
33
34
35 begin = L1_CACHE_ALIGN((unsigned long)virt);
36 end = L1_CACHE_ALIGN((unsigned long)virt + size);
37
38 p1_begin = (unsigned long)p1 & ~(L1_CACHE_BYTES - 1);
39
40 /* do this the slow way as we may not have TLB entries
41 * for virt yet. */
42 for (v = begin; v < end; v += L1_CACHE_BYTES) {
43 unsigned long p;
44 unsigned long ways, addr;
45
46 p = __pa(p1_begin);
47
48 ways = cpu_data->dcache.ways;
49 addr = CACHE_OC_ADDRESS_ARRAY;
50
51 do {
52 unsigned long data;
53
54 addr |= (v & cpu_data->dcache.entry_mask);
55
56 data = ctrl_inl(addr);
57 if ((data & CACHE_PHYSADDR_MASK) ==
58 (p & CACHE_PHYSADDR_MASK)) {
59 data &= ~(SH_CACHE_UPDATED|SH_CACHE_VALID);
60 ctrl_outl(data, addr);
61 }
62
63 addr += cpu_data->dcache.way_incr;
64 } while (--ways);
65
66 p1_begin += L1_CACHE_BYTES;
67 }
68}
69
70/*
71 * clear_user_page
72 * @to: P1 address
73 * @address: U0 address to be mapped
74 */
75void clear_user_page(void *to, unsigned long address, struct page *pg)
76{
77 struct page *page = virt_to_page(to);
78
79 __set_bit(PG_mapped, &page->flags);
80 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
81 clear_page(to);
82 __flush_wback_region(to, PAGE_SIZE);
83 } else {
84 __flush_purge_virtual_region(to,
85 (void *)(address & 0xfffff000),
86 PAGE_SIZE);
87 clear_page(to);
88 __flush_wback_region(to, PAGE_SIZE);
89 }
90}
91
92/*
93 * copy_user_page
94 * @to: P1 address
95 * @from: P1 address
96 * @address: U0 address to be mapped
97 */
98void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
99{
100 struct page *page = virt_to_page(to);
101
102
103 __set_bit(PG_mapped, &page->flags);
104 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
105 copy_page(to, from);
106 __flush_wback_region(to, PAGE_SIZE);
107 } else {
108 __flush_purge_virtual_region(to,
109 (void *)(address & 0xfffff000),
110 PAGE_SIZE);
111 copy_page(to, from);
112 __flush_wback_region(to, PAGE_SIZE);
113 }
114}
115
116/*
117 * For SH7705, we have our own implementation for ptep_get_and_clear
118 * Copied from pg-sh4.c
119 */
120inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
121{
122 pte_t pte = *ptep;
123
124 pte_clear(mm, addr, ptep);
125 if (!pte_not_present(pte)) {
126 unsigned long pfn = pte_pfn(pte);
127 if (pfn_valid(pfn)) {
128 struct page *page = pfn_to_page(pfn);
129 struct address_space *mapping = page_mapping(page);
130 if (!mapping || !mapping_writably_mapped(mapping))
131 __clear_bit(PG_mapped, &page->flags);
132 }
133 }
134
135 return pte;
136}
137
diff --git a/arch/sh/mm/tlb-nommu.c b/arch/sh/mm/tlb-nommu.c
new file mode 100644
index 000000000000..e55cfea01092
--- /dev/null
+++ b/arch/sh/mm/tlb-nommu.c
@@ -0,0 +1,58 @@
1/*
2 * arch/sh/mm/tlb-nommu.c
3 *
4 * TLB Operations for MMUless SH.
5 *
6 * Copyright (C) 2002 Paul Mundt
7 *
8 * Released under the terms of the GNU GPL v2.0.
9 */
10#include <linux/kernel.h>
11#include <linux/mm.h>
12
13/*
14 * Nothing too terribly exciting here ..
15 */
16
17void flush_tlb(void)
18{
19 BUG();
20}
21
22void flush_tlb_all(void)
23{
24 BUG();
25}
26
27void flush_tlb_mm(struct mm_struct *mm)
28{
29 BUG();
30}
31
32void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
33 unsigned long end)
34{
35 BUG();
36}
37
38void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
39{
40 BUG();
41}
42
43void __flush_tlb_page(unsigned long asid, unsigned long page)
44{
45 BUG();
46}
47
48void flush_tlb_kernel_range(unsigned long start, unsigned long end)
49{
50 BUG();
51}
52
53void update_mmu_cache(struct vm_area_struct * vma,
54 unsigned long address, pte_t pte)
55{
56 BUG();
57}
58
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
new file mode 100644
index 000000000000..7a0d5c10bf20
--- /dev/null
+++ b/arch/sh/mm/tlb-sh3.c
@@ -0,0 +1,92 @@
1/*
2 * arch/sh/mm/tlb-sh3.c
3 *
4 * SH-3 specific TLB operations
5 *
6 * Copyright (C) 1999 Niibe Yutaka
7 * Copyright (C) 2002 Paul Mundt
8 *
9 * Released under the terms of the GNU GPL v2.0.
10 */
11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/interrupt.h>
23
24#include <asm/system.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27#include <asm/pgalloc.h>
28#include <asm/mmu_context.h>
29#include <asm/cacheflush.h>
30
31void update_mmu_cache(struct vm_area_struct * vma,
32 unsigned long address, pte_t pte)
33{
34 unsigned long flags;
35 unsigned long pteval;
36 unsigned long vpn;
37
38 /* Ptrace may call this routine. */
39 if (vma && current->active_mm != vma->vm_mm)
40 return;
41
42#if defined(CONFIG_SH7705_CACHE_32KB)
43 struct page *page;
44 page = pte_page(pte);
45 if (VALID_PAGE(page) && !test_bit(PG_mapped, &page->flags)) {
46 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
47 __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
48 __set_bit(PG_mapped, &page->flags);
49 }
50#endif
51
52 local_irq_save(flags);
53
54 /* Set PTEH register */
55 vpn = (address & MMU_VPN_MASK) | get_asid();
56 ctrl_outl(vpn, MMU_PTEH);
57
58 pteval = pte_val(pte);
59
60 /* Set PTEL register */
61 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
62 /* conveniently, we want all the software flags to be 0 anyway */
63 ctrl_outl(pteval, MMU_PTEL);
64
65 /* Load the TLB */
66 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
67 local_irq_restore(flags);
68}
69
70void __flush_tlb_page(unsigned long asid, unsigned long page)
71{
72 unsigned long addr, data;
73 int i, ways = MMU_NTLB_WAYS;
74
75 /*
76 * NOTE: PTEH.ASID should be set to this MM
77 * _AND_ we need to write ASID to the array.
78 *
79 * It would be simple if we didn't need to set PTEH.ASID...
80 */
81 addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000);
82 data = (page & 0xfffe0000) | asid; /* VALID bit is off */
83
84 if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) {
85 addr |= MMU_PAGE_ASSOC_BIT;
86 ways = 1; /* we already know the way .. */
87 }
88
89 for (i = 0; i < ways; i++)
90 ctrl_outl(data, addr + (i << 8));
91}
92
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
new file mode 100644
index 000000000000..115b1b6be40b
--- /dev/null
+++ b/arch/sh/mm/tlb-sh4.c
@@ -0,0 +1,96 @@
1/*
2 * arch/sh/mm/tlb-sh4.c
3 *
4 * SH-4 specific TLB operations
5 *
6 * Copyright (C) 1999 Niibe Yutaka
7 * Copyright (C) 2002 Paul Mundt
8 *
9 * Released under the terms of the GNU GPL v2.0.
10 */
11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/smp_lock.h>
22#include <linux/interrupt.h>
23
24#include <asm/system.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27#include <asm/pgalloc.h>
28#include <asm/mmu_context.h>
29#include <asm/cacheflush.h>
30
31void update_mmu_cache(struct vm_area_struct * vma,
32 unsigned long address, pte_t pte)
33{
34 unsigned long flags;
35 unsigned long pteval;
36 unsigned long vpn;
37 struct page *page;
38 unsigned long pfn;
39 unsigned long ptea;
40
41 /* Ptrace may call this routine. */
42 if (vma && current->active_mm != vma->vm_mm)
43 return;
44
45 pfn = pte_pfn(pte);
46 if (pfn_valid(pfn)) {
47 page = pfn_to_page(pfn);
48 if (!test_bit(PG_mapped, &page->flags)) {
49 unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
50 __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
51 __set_bit(PG_mapped, &page->flags);
52 }
53 }
54
55 local_irq_save(flags);
56
57 /* Set PTEH register */
58 vpn = (address & MMU_VPN_MASK) | get_asid();
59 ctrl_outl(vpn, MMU_PTEH);
60
61 pteval = pte_val(pte);
62 /* Set PTEA register */
63 /* TODO: make this look less hacky */
64 ptea = ((pteval >> 28) & 0xe) | (pteval & 0x1);
65 ctrl_outl(ptea, MMU_PTEA);
66
67 /* Set PTEL register */
68 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
69#ifdef CONFIG_SH_WRITETHROUGH
70 pteval |= _PAGE_WT;
71#endif
72 /* conveniently, we want all the software flags to be 0 anyway */
73 ctrl_outl(pteval, MMU_PTEL);
74
75 /* Load the TLB */
76 asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
77 local_irq_restore(flags);
78}
79
80void __flush_tlb_page(unsigned long asid, unsigned long page)
81{
82 unsigned long addr, data;
83
84 /*
85 * NOTE: PTEH.ASID should be set to this MM
86 * _AND_ we need to write ASID to the array.
87 *
88 * It would be simple if we didn't need to set PTEH.ASID...
89 */
90 addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT;
91 data = page | asid; /* VALID bit is off */
92 jump_to_P2();
93 ctrl_outl(data, addr);
94 back_to_P1();
95}
96
diff --git a/arch/sh/oprofile/Kconfig b/arch/sh/oprofile/Kconfig
new file mode 100644
index 000000000000..5ade19801b97
--- /dev/null
+++ b/arch/sh/oprofile/Kconfig
@@ -0,0 +1,23 @@
1
2menu "Profiling support"
3 depends on EXPERIMENTAL
4
5config PROFILING
6 bool "Profiling support (EXPERIMENTAL)"
7 help
8 Say Y here to enable the extended profiling support mechanisms used
9 by profilers such as OProfile.
10
11
12config OPROFILE
13 tristate "OProfile system profiling (EXPERIMENTAL)"
14 depends on PROFILING
15 help
16 OProfile is a profiling system capable of profiling the
17 whole system, include the kernel, kernel modules, libraries,
18 and applications.
19
20 If unsure, say N.
21
22endmenu
23
diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile
new file mode 100644
index 000000000000..686738d4aa3c
--- /dev/null
+++ b/arch/sh/oprofile/Makefile
@@ -0,0 +1,13 @@
1obj-$(CONFIG_OPROFILE) += oprofile.o
2
3DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
4 oprof.o cpu_buffer.o buffer_sync.o \
5 event_buffer.o oprofile_files.o \
6 oprofilefs.o oprofile_stats.o \
7 timer_int.o )
8
9profdrvr-y := op_model_null.o
10profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750) := op_model_sh7750.o
11
12oprofile-y := $(DRIVER_OBJS) $(profdrvr-y)
13
diff --git a/arch/sh/oprofile/op_model_null.c b/arch/sh/oprofile/op_model_null.c
new file mode 100644
index 000000000000..a845b088edb4
--- /dev/null
+++ b/arch/sh/oprofile/op_model_null.c
@@ -0,0 +1,23 @@
1/*
2 * arch/sh/oprofile/op_model_null.c
3 *
4 * Copyright (C) 2003 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/kernel.h>
11#include <linux/oprofile.h>
12#include <linux/init.h>
13#include <linux/errno.h>
14
15int __init oprofile_arch_init(struct oprofile_operations *ops)
16{
17 return -ENODEV;
18}
19
20void oprofile_arch_exit(void)
21{
22}
23
diff --git a/arch/sh/oprofile/op_model_sh7750.c b/arch/sh/oprofile/op_model_sh7750.c
new file mode 100644
index 000000000000..5ec9ddcc4b0b
--- /dev/null
+++ b/arch/sh/oprofile/op_model_sh7750.c
@@ -0,0 +1,281 @@
1/*
2 * arch/sh/oprofile/op_model_sh7750.c
3 *
4 * OProfile support for SH7750/SH7750S Performance Counters
5 *
6 * Copyright (C) 2003, 2004 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/oprofile.h>
14#include <linux/profile.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/interrupt.h>
18#include <linux/fs.h>
19#include <linux/notifier.h>
20#include <asm/uaccess.h>
21#include <asm/io.h>
22
23#define PM_CR_BASE 0xff000084 /* 16-bit */
24#define PM_CTR_BASE 0xff100004 /* 32-bit */
25
26#define PMCR1 (PM_CR_BASE + 0x00)
27#define PMCR2 (PM_CR_BASE + 0x04)
28#define PMCTR1H (PM_CTR_BASE + 0x00)
29#define PMCTR1L (PM_CTR_BASE + 0x04)
30#define PMCTR2H (PM_CTR_BASE + 0x08)
31#define PMCTR2L (PM_CTR_BASE + 0x0c)
32
33#define PMCR_PMM_MASK 0x0000003f
34
35#define PMCR_CLKF 0x00000100
36#define PMCR_PMCLR 0x00002000
37#define PMCR_PMST 0x00004000
38#define PMCR_PMEN 0x00008000
39
40#define PMCR_ENABLE (PMCR_PMST | PMCR_PMEN)
41
42/*
43 * SH7750/SH7750S have 2 perf counters
44 */
45#define NR_CNTRS 2
46
47extern const char *get_cpu_subtype(void);
48
49struct op_counter_config {
50 unsigned long enabled;
51 unsigned long event;
52 unsigned long count;
53
54 /* Dummy values for userspace tool compliance */
55 unsigned long kernel;
56 unsigned long user;
57 unsigned long unit_mask;
58};
59
60static struct op_counter_config ctr[NR_CNTRS];
61
62/*
63 * There are a number of events supported by each counter (33 in total).
64 * Since we have 2 counters, each counter will take the event code as it
65 * corresponds to the PMCR PMM setting. Each counter can be configured
66 * independently.
67 *
68 * Event Code Description
69 * ---------- -----------
70 *
71 * 0x01 Operand read access
72 * 0x02 Operand write access
73 * 0x03 UTLB miss
74 * 0x04 Operand cache read miss
75 * 0x05 Operand cache write miss
76 * 0x06 Instruction fetch (w/ cache)
77 * 0x07 Instruction TLB miss
78 * 0x08 Instruction cache miss
79 * 0x09 All operand accesses
80 * 0x0a All instruction accesses
81 * 0x0b OC RAM operand access
82 * 0x0d On-chip I/O space access
83 * 0x0e Operand access (r/w)
84 * 0x0f Operand cache miss (r/w)
85 * 0x10 Branch instruction
86 * 0x11 Branch taken
87 * 0x12 BSR/BSRF/JSR
88 * 0x13 Instruction execution
89 * 0x14 Instruction execution in parallel
90 * 0x15 FPU Instruction execution
91 * 0x16 Interrupt
92 * 0x17 NMI
93 * 0x18 trapa instruction execution
94 * 0x19 UBCA match
95 * 0x1a UBCB match
96 * 0x21 Instruction cache fill
97 * 0x22 Operand cache fill
98 * 0x23 Elapsed time
99 * 0x24 Pipeline freeze by I-cache miss
100 * 0x25 Pipeline freeze by D-cache miss
101 * 0x27 Pipeline freeze by branch instruction
102 * 0x28 Pipeline freeze by CPU register
103 * 0x29 Pipeline freeze by FPU
104 *
105 * Unfortunately we don't have a native exception or interrupt for counter
106 * overflow (although since these counters can run for 16.3 days without
107 * overflowing, it's not really necessary).
108 *
109 * OProfile on the other hand likes to have samples taken periodically, so
110 * for now we just piggyback the timer interrupt to get the expected
111 * behavior.
112 */
113
114static int sh7750_timer_notify(struct notifier_block *self,
115 unsigned long val, void *regs)
116{
117 oprofile_add_sample((struct pt_regs *)regs, 0);
118 return 0;
119}
120
121static struct notifier_block sh7750_timer_notifier = {
122 .notifier_call = sh7750_timer_notify,
123};
124
125static u64 sh7750_read_counter(int counter)
126{
127 u32 hi, lo;
128
129 hi = (counter == 0) ? ctrl_inl(PMCTR1H) : ctrl_inl(PMCTR2H);
130 lo = (counter == 0) ? ctrl_inl(PMCTR1L) : ctrl_inl(PMCTR2L);
131
132 return (u64)((u64)(hi & 0xffff) << 32) | lo;
133}
134
135/*
136 * Files will be in a path like:
137 *
138 * /<oprofilefs mount point>/<counter number>/<file>
139 *
140 * So when dealing with <file>, we look to the parent dentry for the counter
141 * number.
142 */
143static inline int to_counter(struct file *file)
144{
145 const unsigned char *name = file->f_dentry->d_parent->d_name.name;
146
147 return (int)simple_strtol(name, NULL, 10);
148}
149
150/*
151 * XXX: We have 48-bit counters, so we're probably going to want something
152 * more along the lines of oprofilefs_ullong_to_user().. Truncating to
153 * unsigned long works fine for now though, as long as we don't attempt to
154 * profile for too horribly long.
155 */
156static ssize_t sh7750_read_count(struct file *file, char __user *buf,
157 size_t count, loff_t *ppos)
158{
159 int counter = to_counter(file);
160 u64 val = sh7750_read_counter(counter);
161
162 return oprofilefs_ulong_to_user((unsigned long)val, buf, count, ppos);
163}
164
165static ssize_t sh7750_write_count(struct file *file, const char __user *buf,
166 size_t count, loff_t *ppos)
167{
168 int counter = to_counter(file);
169 unsigned long val;
170
171 if (oprofilefs_ulong_from_user(&val, buf, count))
172 return -EFAULT;
173
174 /*
175 * Any write will clear the counter, although only 0 should be
176 * written for this purpose, as we do not support setting the
177 * counter to an arbitrary value.
178 */
179 WARN_ON(val != 0);
180
181 if (counter == 0) {
182 ctrl_outw(ctrl_inw(PMCR1) | PMCR_PMCLR, PMCR1);
183 } else {
184 ctrl_outw(ctrl_inw(PMCR2) | PMCR_PMCLR, PMCR2);
185 }
186
187 return count;
188}
189
190static struct file_operations count_fops = {
191 .read = sh7750_read_count,
192 .write = sh7750_write_count,
193};
194
195static int sh7750_perf_counter_create_files(struct super_block *sb, struct dentry *root)
196{
197 int i;
198
199 for (i = 0; i < NR_CNTRS; i++) {
200 struct dentry *dir;
201 char buf[3];
202
203 snprintf(buf, sizeof(buf), "%d", i);
204 dir = oprofilefs_mkdir(sb, root, buf);
205
206 oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
207 oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
208 oprofilefs_create_file(sb, dir, "count", &count_fops);
209
210 /* Dummy entries */
211 oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
212 oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
213 oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
214 }
215
216 return 0;
217}
218
219static int sh7750_perf_counter_start(void)
220{
221 u16 pmcr;
222
223 /* Enable counter 1 */
224 if (ctr[0].enabled) {
225 pmcr = ctrl_inw(PMCR1);
226 WARN_ON(pmcr & PMCR_PMEN);
227
228 pmcr &= ~PMCR_PMM_MASK;
229 pmcr |= ctr[0].event;
230 ctrl_outw(pmcr | PMCR_ENABLE, PMCR1);
231 }
232
233 /* Enable counter 2 */
234 if (ctr[1].enabled) {
235 pmcr = ctrl_inw(PMCR2);
236 WARN_ON(pmcr & PMCR_PMEN);
237
238 pmcr &= ~PMCR_PMM_MASK;
239 pmcr |= ctr[1].event;
240 ctrl_outw(pmcr | PMCR_ENABLE, PMCR2);
241 }
242
243 return register_profile_notifier(&sh7750_timer_notifier);
244}
245
246static void sh7750_perf_counter_stop(void)
247{
248 ctrl_outw(ctrl_inw(PMCR1) & ~PMCR_PMEN, PMCR1);
249 ctrl_outw(ctrl_inw(PMCR2) & ~PMCR_PMEN, PMCR2);
250
251 unregister_profile_notifier(&sh7750_timer_notifier);
252}
253
254static struct oprofile_operations sh7750_perf_counter_ops = {
255 .create_files = sh7750_perf_counter_create_files,
256 .start = sh7750_perf_counter_start,
257 .stop = sh7750_perf_counter_stop,
258};
259
260int __init oprofile_arch_init(struct oprofile_operations **ops)
261{
262 if (!(cpu_data->flags & CPU_HAS_PERF_COUNTER))
263 return -ENODEV;
264
265 sh7750_perf_counter_ops.cpu_type = (char *)get_cpu_subtype();
266 *ops = &sh7750_perf_counter_ops;
267
268 printk(KERN_INFO "oprofile: using SH-4 (%s) performance monitoring.\n",
269 sh7750_perf_counter_ops.cpu_type);
270
271 /* Clear the counters */
272 ctrl_outw(ctrl_inw(PMCR1) | PMCR_PMCLR, PMCR1);
273 ctrl_outw(ctrl_inw(PMCR2) | PMCR_PMCLR, PMCR2);
274
275 return 0;
276}
277
278void oprofile_arch_exit(void)
279{
280}
281
diff --git a/arch/sh/ramdisk/Makefile b/arch/sh/ramdisk/Makefile
new file mode 100644
index 000000000000..99e1c68673cf
--- /dev/null
+++ b/arch/sh/ramdisk/Makefile
@@ -0,0 +1,20 @@
1#
2# Makefile for a ramdisk image
3#
4
5obj-y += ramdisk.o
6
7
8O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32)
9img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE))
10# add $(src) when $(img) is relative
11img := $(subst $(src)//,/,$(src)/$(img))
12
13quiet_cmd_ramdisk = LD $@
14define cmd_ramdisk
15 $(LD) -T $(srctree)/$(src)/ld.script -b binary --oformat $(O_FORMAT) \
16 -o $@ $(img)
17endef
18
19$(obj)/ramdisk.o: $(img) $(srctree)/$(src)/ld.script
20 $(call cmd,ramdisk)
diff --git a/arch/sh/ramdisk/ld.script b/arch/sh/ramdisk/ld.script
new file mode 100644
index 000000000000..94beee248c04
--- /dev/null
+++ b/arch/sh/ramdisk/ld.script
@@ -0,0 +1,9 @@
1OUTPUT_ARCH(sh)
2SECTIONS
3{
4 .initrd :
5 {
6 *(.data)
7 }
8}
9
diff --git a/arch/sh/tools/Makefile b/arch/sh/tools/Makefile
new file mode 100644
index 000000000000..3c370a113291
--- /dev/null
+++ b/arch/sh/tools/Makefile
@@ -0,0 +1,15 @@
1#
2# arch/sh/tools/Makefile
3#
4# Copyright (C) 2003 Paul Mundt
5#
6# This file is subject to the terms and conditions of the GNU General Public
7# License. See the file "COPYING" in the main directory of this archive
8# for more details.
9#
10# Shamelessly cloned from ARM.
11#
12
13include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types
14 @echo ' Generating $@'
15 $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
diff --git a/arch/sh/tools/gen-mach-types b/arch/sh/tools/gen-mach-types
new file mode 100644
index 000000000000..bb2b82234e83
--- /dev/null
+++ b/arch/sh/tools/gen-mach-types
@@ -0,0 +1,49 @@
1#!/bin/awk
2#
3# Awk script to generate include/asm-sh/machtypes.h
4# Heavily based on arch/arm/tools/gen-mach-types
5#
6BEGIN { nr = 0 }
7/^#/ { next }
8/^[ ]*$/ { next }
9
10NF == 2 {
11 mach[nr] = $1;
12 config[nr] = "CONFIG_"$2;
13 nr++;
14 }
15
16END {
17 printf("/*\n");
18 printf(" * Automagically generated, don't touch.\n");
19 printf(" */\n");
20 printf("#ifndef __ASM_SH_MACHTYPES_H\n");
21 printf("#define __ASM_SH_MACHTYPES_H\n");
22 printf("\n");
23 printf("#include <linux/config.h>\n");
24 printf("\n");
25 printf("/*\n");
26 printf(" * We'll use the following MACH_xxx defs for placeholders for the time\n");
27 printf(" * being .. these will all go away once sh_machtype is assigned per-board.\n");
28 printf(" *\n");
29 printf(" * For now we leave things the way they are for backwards compatibility.\n");
30 printf(" */\n");
31 printf("\n");
32 printf("/* Mach types */\n");
33
34 for (i = 0; i < nr; i++) {
35 printf("#ifdef %s\n", config[i]);
36 printf(" #define MACH_%s\t\t1\n", mach[i]);
37 printf("#else\n");
38 printf(" #define MACH_%s\t\t0\n", mach[i]);
39 printf("#endif\n");
40 }
41
42 printf("\n");
43 printf("/* Machtype checks */\n");
44 for (i = 0; i < nr; i++)
45 printf("#define mach_is_%s()\t\t\t(MACH_%s)\n",
46 tolower(mach[i]), mach[i]);
47 printf("\n");
48 printf("#endif /* __ASM_SH_MACHTYPES_H */\n");
49 }
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
new file mode 100644
index 000000000000..0693fbd1f956
--- /dev/null
+++ b/arch/sh/tools/mach-types
@@ -0,0 +1,31 @@
1#
2# List of boards.
3#
4
5#
6# MACH_<xxx> CONFIG_<xxx>
7#
8SE SH_SOLUTION_ENGINE
97751SE SH_7751_SOLUTION_ENGINE
107300SE SH_7300_SOLUTION_ENGINE
1173180SE SH_73180_SOLUTION_ENGINE
127751SYSTEMH SH_7751_SYSTEMH
13HP600 SH_HP600
14HP620 SH_HP620
15HP680 SH_HP680
16HP690 SH_HP690
17HD64461 HD64461
18HD64465 HD64465
19SH2000 SH_SH2000
20SATURN SH_SATURN
21DREAMCAST SH_DREAMCAST
22BIGSUR SH_BIGSUR
23ADX SH_ADX
24MPC1211 SH_MPC1211
25SNAPGEAR SH_SECUREEDGE5410
26HS7751RVOIP SH_HS7751RVOIP
27RTS7751R2D SH_RTS7751R2D
28EDOSK7705 SH_EDOSK7705
29SH4202_MICRODEV SH_SH4202_MICRODEV
30SH03 SH_SH03
31