diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /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')
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 | |||
6 | mainmenu "Linux/SuperH Kernel Configuration" | ||
7 | |||
8 | config 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 | |||
17 | config UID16 | ||
18 | bool | ||
19 | default y | ||
20 | |||
21 | config RWSEM_GENERIC_SPINLOCK | ||
22 | bool | ||
23 | default y | ||
24 | |||
25 | config RWSEM_XCHGADD_ALGORITHM | ||
26 | bool | ||
27 | |||
28 | config GENERIC_HARDIRQS | ||
29 | bool | ||
30 | default y | ||
31 | |||
32 | config GENERIC_IRQ_PROBE | ||
33 | bool | ||
34 | default y | ||
35 | |||
36 | config GENERIC_CALIBRATE_DELAY | ||
37 | bool | ||
38 | default y | ||
39 | |||
40 | source "init/Kconfig" | ||
41 | |||
42 | menu "System type" | ||
43 | |||
44 | choice | ||
45 | prompt "SuperH system type" | ||
46 | default SH_UNKNOWN | ||
47 | |||
48 | config SH_SOLUTION_ENGINE | ||
49 | bool "SolutionEngine" | ||
50 | help | ||
51 | Select SolutionEngine if configuring for a Hitachi SH7709 | ||
52 | or SH7750 evaluation board. | ||
53 | |||
54 | config SH_7751_SOLUTION_ENGINE | ||
55 | bool "SolutionEngine7751" | ||
56 | help | ||
57 | Select 7751 SolutionEngine if configuring for a Hitachi SH7751 | ||
58 | evaluation board. | ||
59 | |||
60 | config 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 | |||
66 | config 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 | |||
72 | config SH_7751_SYSTEMH | ||
73 | bool "SystemH7751R" | ||
74 | help | ||
75 | Select SystemH if you are configuring for a Renesas SystemH | ||
76 | 7751R evaluation board. | ||
77 | |||
78 | config SH_STB1_HARP | ||
79 | bool "STB1_Harp" | ||
80 | |||
81 | config SH_STB1_OVERDRIVE | ||
82 | bool "STB1_Overdrive" | ||
83 | |||
84 | config 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 | |||
91 | config 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 | |||
98 | config 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 | |||
105 | config 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 | |||
112 | config 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 | |||
118 | config 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 | |||
124 | config SH_SATURN | ||
125 | bool "Saturn" | ||
126 | help | ||
127 | Select Saturn if configuring for a SEGA Saturn. | ||
128 | |||
129 | config 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 | |||
137 | config SH_CAT68701 | ||
138 | bool "CAT68701" | ||
139 | |||
140 | config SH_BIGSUR | ||
141 | bool "BigSur" | ||
142 | |||
143 | config 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 | |||
152 | config SH_ADX | ||
153 | bool "ADX" | ||
154 | |||
155 | config SH_MPC1211 | ||
156 | bool "MPC1211" | ||
157 | |||
158 | config 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 | |||
168 | config 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 | |||
175 | config SH_HS7751RVOIP | ||
176 | bool "HS7751RVOIP" | ||
177 | help | ||
178 | Select HS7751RVOIP if configuring for a Renesas Technology | ||
179 | Sales VoIP board. | ||
180 | |||
181 | config SH_RTS7751R2D | ||
182 | bool "RTS7751R2D" | ||
183 | help | ||
184 | Select RTS7751R2D if configuring for a Renesas Technology | ||
185 | Sales SH-Graphics board. | ||
186 | |||
187 | config SH_EDOSK7705 | ||
188 | bool "EDOSK7705" | ||
189 | |||
190 | config 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 | |||
196 | config 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 | |||
208 | endchoice | ||
209 | |||
210 | choice | ||
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 | |||
220 | config CPU_SH2 | ||
221 | bool "SH-2" | ||
222 | select SH_WRITETHROUGH | ||
223 | |||
224 | config CPU_SH3 | ||
225 | bool "SH-3" | ||
226 | |||
227 | config CPU_SH4 | ||
228 | bool "SH-4" | ||
229 | |||
230 | endchoice | ||
231 | |||
232 | choice | ||
233 | prompt "Processor subtype" | ||
234 | |||
235 | config CPU_SUBTYPE_SH7604 | ||
236 | bool "SH7604" | ||
237 | depends on CPU_SH2 | ||
238 | help | ||
239 | Select SH7604 if you have SH7604 | ||
240 | |||
241 | config CPU_SUBTYPE_SH7300 | ||
242 | bool "SH7300" | ||
243 | depends on CPU_SH3 | ||
244 | |||
245 | config CPU_SUBTYPE_SH7705 | ||
246 | bool "SH7705" | ||
247 | depends on CPU_SH3 | ||
248 | |||
249 | config 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 | |||
255 | config 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 | |||
262 | config 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 | |||
268 | config 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 | |||
274 | config 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 | |||
281 | config CPU_SUBTYPE_SH7760 | ||
282 | bool "SH7760" | ||
283 | depends on CPU_SH4 | ||
284 | |||
285 | config CPU_SUBTYPE_SH73180 | ||
286 | bool "SH73180" | ||
287 | depends on CPU_SH4 | ||
288 | |||
289 | config 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 | |||
296 | config CPU_SUBTYPE_ST40GX1 | ||
297 | bool "ST40GX1" | ||
298 | depends on CPU_SH4 | ||
299 | help | ||
300 | Select ST40GX1 if you have a ST40GX1 CPU. | ||
301 | |||
302 | config CPU_SUBTYPE_SH4_202 | ||
303 | bool "SH4-202" | ||
304 | depends on CPU_SH4 | ||
305 | |||
306 | endchoice | ||
307 | |||
308 | config SH7705_CACHE_32KB | ||
309 | bool "Enable 32KB cache size for SH7705" | ||
310 | depends on CPU_SUBTYPE_SH7705 | ||
311 | default y | ||
312 | |||
313 | config 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 | |||
325 | choice | ||
326 | prompt "HugeTLB page size" | ||
327 | depends on HUGETLB_PAGE && CPU_SH4 && MMU | ||
328 | default HUGETLB_PAGE_SIZE_64K | ||
329 | |||
330 | config HUGETLB_PAGE_SIZE_64K | ||
331 | bool "64K" | ||
332 | |||
333 | config HUGETLB_PAGE_SIZE_1MB | ||
334 | bool "1MB" | ||
335 | |||
336 | endchoice | ||
337 | |||
338 | config CMDLINE_BOOL | ||
339 | bool "Default bootloader kernel arguments" | ||
340 | |||
341 | config 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 | ||
347 | config 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 | |||
365 | config 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 | |||
379 | config 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. | ||
390 | config MEMORY_OVERRIDE | ||
391 | bool "Override default load address and memory size" | ||
392 | |||
393 | # XXX: break these out into the board-specific configs below | ||
394 | config 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 | |||
410 | choice | ||
411 | prompt "Compact Flash Connection Area" | ||
412 | depends on CF_ENABLER | ||
413 | default CF_AREA6 | ||
414 | |||
415 | config 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 | |||
426 | config CF_AREA6 | ||
427 | bool "Area6" | ||
428 | |||
429 | endchoice | ||
430 | |||
431 | config 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 | ||
438 | config 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 | |||
448 | config 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 | |||
458 | config 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 | |||
469 | config 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 | |||
479 | config SH_HP600 | ||
480 | bool | ||
481 | depends on SH_HP620 || SH_HP680 || SH_HP690 | ||
482 | default y | ||
483 | |||
484 | config CPU_SUBTYPE_ST40 | ||
485 | bool | ||
486 | depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1 | ||
487 | default y | ||
488 | |||
489 | config 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 | |||
499 | config 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 | ||
507 | config ST40_LMI_MEMORY | ||
508 | bool "Memory on LMI" | ||
509 | depends on CPU_SUBTYPE_ST40STB1 | ||
510 | |||
511 | config MEMORY_START | ||
512 | hex | ||
513 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
514 | default "0x08000000" | ||
515 | |||
516 | config MEMORY_SIZE | ||
517 | hex | ||
518 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
519 | default "0x00400000" | ||
520 | |||
521 | config MEMORY_SET | ||
522 | bool | ||
523 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
524 | default y | ||
525 | |||
526 | config 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 | |||
534 | config 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 | |||
541 | config PREEMPT | ||
542 | bool "Preemptible Kernel (EXPERIMENTAL)" | ||
543 | depends on EXPERIMENTAL | ||
544 | |||
545 | config 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 | |||
555 | config 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 | |||
568 | config 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 | |||
579 | config 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 | |||
586 | config 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 | |||
608 | config 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 | |||
621 | config HS7751RVOIP_CODEC | ||
622 | bool "Support VoIP Codec section" | ||
623 | depends on SH_HS7751RVOIP | ||
624 | help | ||
625 | Selecting this option will support CODEC section. | ||
626 | |||
627 | config 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 | |||
633 | config 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 | |||
642 | config 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 | |||
658 | menu "CPU Frequency scaling" | ||
659 | |||
660 | source "drivers/cpufreq/Kconfig" | ||
661 | |||
662 | config 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 | |||
674 | endmenu | ||
675 | |||
676 | source "arch/sh/drivers/dma/Kconfig" | ||
677 | |||
678 | source "arch/sh/cchips/Kconfig" | ||
679 | |||
680 | config 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 | |||
688 | config 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 | |||
694 | endmenu | ||
695 | |||
696 | |||
697 | menu "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. | ||
706 | config 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 | |||
716 | config 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 | |||
731 | config 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 | |||
739 | config SBUS | ||
740 | bool | ||
741 | |||
742 | config MAPLE | ||
743 | tristate "Maple Bus support" | ||
744 | depends on SH_DREAMCAST | ||
745 | default y | ||
746 | |||
747 | source "arch/sh/drivers/pci/Kconfig" | ||
748 | |||
749 | source "drivers/pci/Kconfig" | ||
750 | |||
751 | source "drivers/pcmcia/Kconfig" | ||
752 | |||
753 | source "drivers/pci/hotplug/Kconfig" | ||
754 | |||
755 | endmenu | ||
756 | |||
757 | menu "Executable file formats" | ||
758 | |||
759 | source "fs/Kconfig.binfmt" | ||
760 | |||
761 | endmenu | ||
762 | |||
763 | menu "SH initrd options" | ||
764 | depends on BLK_DEV_INITRD | ||
765 | |||
766 | config EMBEDDED_RAMDISK | ||
767 | bool "Embed root filesystem ramdisk into the kernel" | ||
768 | |||
769 | config 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 | |||
779 | endmenu | ||
780 | |||
781 | source "drivers/Kconfig" | ||
782 | |||
783 | source "fs/Kconfig" | ||
784 | |||
785 | source "arch/sh/oprofile/Kconfig" | ||
786 | |||
787 | source "arch/sh/Kconfig.debug" | ||
788 | |||
789 | source "security/Kconfig" | ||
790 | |||
791 | source "crypto/Kconfig" | ||
792 | |||
793 | source "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 @@ | |||
1 | menu "Kernel hacking" | ||
2 | |||
3 | source "lib/Kconfig.debug" | ||
4 | |||
5 | config 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 | |||
18 | config EARLY_SCIF_CONSOLE | ||
19 | bool "Use early SCIF console" | ||
20 | depends on CPU_SH4 | ||
21 | |||
22 | config 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 | |||
33 | config 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 | |||
40 | menu "KGDB configuration options" | ||
41 | depends on KGDB | ||
42 | |||
43 | config 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 | |||
50 | config COMPILE_OPTIONS | ||
51 | string "Additional compile arguments" | ||
52 | depends on MORE_COMPILE_OPTIONS | ||
53 | |||
54 | config KGDB_NMI | ||
55 | bool "Enter KGDB on NMI" | ||
56 | default n | ||
57 | |||
58 | config KGDB_THREAD | ||
59 | bool "Include KGDB thread support" | ||
60 | default y | ||
61 | |||
62 | config SH_KGDB_CONSOLE | ||
63 | bool "Console messages through GDB" | ||
64 | default n | ||
65 | |||
66 | config KGDB_SYSRQ | ||
67 | bool "Allow SysRq 'G' to enter KGDB" | ||
68 | default y | ||
69 | |||
70 | config KGDB_KERNEL_ASSERTS | ||
71 | bool "Include KGDB kernel assertions" | ||
72 | default n | ||
73 | |||
74 | comment "Serial port setup" | ||
75 | |||
76 | config KGDB_DEFPORT | ||
77 | int "Port number (ttySCn)" | ||
78 | default "1" | ||
79 | |||
80 | config KGDB_DEFBAUD | ||
81 | int "Baud rate" | ||
82 | default "115200" | ||
83 | |||
84 | choice | ||
85 | prompt "Parity" | ||
86 | depends on KGDB | ||
87 | default KGDB_DEFPARITY_N | ||
88 | |||
89 | config KGDB_DEFPARITY_N | ||
90 | bool "None" | ||
91 | |||
92 | config KGDB_DEFPARITY_E | ||
93 | bool "Even" | ||
94 | |||
95 | config KGDB_DEFPARITY_O | ||
96 | bool "Odd" | ||
97 | |||
98 | endchoice | ||
99 | |||
100 | choice | ||
101 | prompt "Data bits" | ||
102 | depends on KGDB | ||
103 | default KGDB_DEFBITS_8 | ||
104 | |||
105 | config KGDB_DEFBITS_8 | ||
106 | bool "8" | ||
107 | |||
108 | config KGDB_DEFBITS_7 | ||
109 | bool "7" | ||
110 | |||
111 | endchoice | ||
112 | |||
113 | endmenu | ||
114 | |||
115 | config 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 | |||
124 | endmenu | ||
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 | |||
17 | cflags-y := -mb | ||
18 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml | ||
19 | |||
20 | cflags-$(CONFIG_CPU_SH2) += -m2 | ||
21 | cflags-$(CONFIG_CPU_SH3) += -m3 | ||
22 | cflags-$(CONFIG_CPU_SH4) += -m4 \ | ||
23 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) | ||
24 | |||
25 | cflags-$(CONFIG_SH_DSP) += -Wa,-dsp | ||
26 | cflags-$(CONFIG_SH_KGDB) += -g | ||
27 | |||
28 | cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ | ||
29 | $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') | ||
30 | |||
31 | OBJCOPYFLAGS := -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 | # | ||
38 | KBUILD_DEFCONFIG := rts7751r2d_defconfig | ||
39 | |||
40 | # | ||
41 | # Choosing incompatible machines durings configuration will result in | ||
42 | # error messages during linking. | ||
43 | # | ||
44 | LDFLAGS_vmlinux += -e _stext | ||
45 | |||
46 | ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
47 | LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64' | ||
48 | LDFLAGS += -EL | ||
49 | else | ||
50 | LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4' | ||
51 | LDFLAGS += -EB | ||
52 | endif | ||
53 | |||
54 | CFLAGS += -pipe $(cflags-y) | ||
55 | AFLAGS += $(cflags-y) | ||
56 | |||
57 | head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o | ||
58 | |||
59 | LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) | ||
60 | |||
61 | core-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 | # | ||
69 | core-$(CONFIG_EMBEDDED_RAMDISK) += arch/sh/ramdisk/ | ||
70 | |||
71 | # Boards | ||
72 | machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x | ||
73 | machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 | ||
74 | machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 | ||
75 | machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 | ||
76 | machdir-$(CONFIG_SH_STB1_HARP) := harp | ||
77 | machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive | ||
78 | machdir-$(CONFIG_SH_HP620) := hp6xx/hp620 | ||
79 | machdir-$(CONFIG_SH_HP680) := hp6xx/hp680 | ||
80 | machdir-$(CONFIG_SH_HP690) := hp6xx/hp690 | ||
81 | machdir-$(CONFIG_SH_CQREEK) := cqreek | ||
82 | machdir-$(CONFIG_SH_DMIDA) := dmida | ||
83 | machdir-$(CONFIG_SH_EC3104) := ec3104 | ||
84 | machdir-$(CONFIG_SH_SATURN) := saturn | ||
85 | machdir-$(CONFIG_SH_DREAMCAST) := dreamcast | ||
86 | machdir-$(CONFIG_SH_CAT68701) := cat68701 | ||
87 | machdir-$(CONFIG_SH_BIGSUR) := bigsur | ||
88 | machdir-$(CONFIG_SH_SH2000) := sh2000 | ||
89 | machdir-$(CONFIG_SH_ADX) := adx | ||
90 | machdir-$(CONFIG_SH_MPC1211) := mpc1211 | ||
91 | machdir-$(CONFIG_SH_SH03) := sh03 | ||
92 | machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear | ||
93 | machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip | ||
94 | machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d | ||
95 | machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh | ||
96 | machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705 | ||
97 | machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev | ||
98 | machdir-$(CONFIG_SH_UNKNOWN) := unknown | ||
99 | |||
100 | incdir-y := $(notdir $(machdir-y)) | ||
101 | |||
102 | incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se | ||
103 | incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751 | ||
104 | incdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se7300 | ||
105 | incdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se73180 | ||
106 | incdir-$(CONFIG_SH_HP600) := hp6xx | ||
107 | |||
108 | ifneq ($(machdir-y),) | ||
109 | core-y += arch/sh/boards/$(machdir-y)/ | ||
110 | endif | ||
111 | |||
112 | # Companion chips | ||
113 | core-$(CONFIG_HD64461) += arch/sh/cchips/hd6446x/hd64461/ | ||
114 | core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ | ||
115 | core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ | ||
116 | |||
117 | cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 | ||
118 | cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3 | ||
119 | cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4 | ||
120 | |||
121 | libs-y := arch/sh/lib/ $(libs-y) $(LIBGCC) | ||
122 | |||
123 | drivers-y += arch/sh/drivers/ | ||
124 | drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/ | ||
125 | |||
126 | boot := arch/sh/boot | ||
127 | |||
128 | CPPFLAGS_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 | |||
134 | include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER | ||
135 | @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' | ||
136 | ifneq ($(KBUILD_SRC),) | ||
137 | $(Q)mkdir -p include/asm-sh | ||
138 | $(Q)ln -fsn $(srctree)/include/asm-sh/$(cpuincdir-y) include/asm-sh/cpu | ||
139 | else | ||
140 | $(Q)ln -fsn $(cpuincdir-y) include/asm-sh/cpu | ||
141 | endif | ||
142 | @touch $@ | ||
143 | |||
144 | include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER | ||
145 | @echo ' SYMLINK include/asm-sh/mach -> include/asm-sh/$(incdir-y)' | ||
146 | ifneq ($(KBUILD_SRC),) | ||
147 | $(Q)mkdir -p include/asm-sh | ||
148 | $(Q)ln -fsn $(srctree)/include/asm-sh/$(incdir-y) include/asm-sh/mach | ||
149 | else | ||
150 | $(Q)ln -fsn $(incdir-y) include/asm-sh/mach | ||
151 | endif | ||
152 | @touch $@ | ||
153 | |||
154 | |||
155 | prepare: maketools include/asm-sh/.cpu include/asm-sh/.mach | ||
156 | |||
157 | .PHONY: maketools FORCE | ||
158 | maketools: include/asm-sh/asm-offsets.h include/linux/version.h FORCE | ||
159 | $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h | ||
160 | |||
161 | all: zImage | ||
162 | |||
163 | zImage: vmlinux | ||
164 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | ||
165 | |||
166 | compressed: zImage | ||
167 | |||
168 | archclean: | ||
169 | $(Q)$(MAKE) $(clean)=$(boot) | ||
170 | |||
171 | CLEAN_FILES += include/asm-sh/machtypes.h include/asm-sh/asm-offsets.h | ||
172 | |||
173 | arch/sh/kernel/asm-offsets.s: include/asm include/linux/version.h \ | ||
174 | include/asm-sh/.cpu include/asm-sh/.mach | ||
175 | |||
176 | include/asm-sh/asm-offsets.h: arch/sh/kernel/asm-offsets.s | ||
177 | $(call filechk,gen-asm-offsets) | ||
178 | |||
179 | |||
180 | define archhelp | ||
181 | @echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)' | ||
182 | endef | ||
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 | |||
5 | obj-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 | |||
16 | void 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? */ | ||
28 | unsigned short *irq_mask_register = 0; | ||
29 | |||
30 | /* forward declaration */ | ||
31 | static unsigned int startup_maskreg_irq(unsigned int irq); | ||
32 | static void shutdown_maskreg_irq(unsigned int irq); | ||
33 | static void enable_maskreg_irq(unsigned int irq); | ||
34 | static void disable_maskreg_irq(unsigned int irq); | ||
35 | static void mask_and_ack_maskreg(unsigned int); | ||
36 | static void end_maskreg_irq(unsigned int irq); | ||
37 | |||
38 | /* hw_interrupt_type */ | ||
39 | static 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 */ | ||
50 | static unsigned int startup_maskreg_irq(unsigned int irq) | ||
51 | { | ||
52 | enable_maskreg_irq(irq); | ||
53 | return 0; /* never anything pending */ | ||
54 | } | ||
55 | |||
56 | static void shutdown_maskreg_irq(unsigned int irq) | ||
57 | { | ||
58 | disable_maskreg_irq(irq); | ||
59 | } | ||
60 | |||
61 | static 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 | |||
76 | static 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 | |||
91 | static void mask_and_ack_maskreg(unsigned int irq) | ||
92 | { | ||
93 | disable_maskreg_irq(irq); | ||
94 | } | ||
95 | |||
96 | static 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 | |||
102 | void 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 | |||
17 | extern void init_adx_IRQ(void); | ||
18 | extern void *cf_io_base; | ||
19 | |||
20 | const char *get_system_type(void) | ||
21 | { | ||
22 | return "A&D ADX"; | ||
23 | } | ||
24 | |||
25 | unsigned 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 | |||
44 | struct 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 | }; | ||
49 | ALIAS_MV(adx) | ||
50 | |||
51 | int __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 | |||
5 | obj-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) | ||
29 | static u32 bigsur_iomap_lo[BIGSUR_IOMAP_LO_NMAP]; | ||
30 | static 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) | ||
37 | static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP]; | ||
38 | static 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 | |||
44 | void 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 | } | ||
69 | EXPORT_SYMBOL(bigsur_port_map); | ||
70 | |||
71 | void 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 | } | ||
89 | EXPORT_SYMBOL(bigsur_port_unmap); | ||
90 | |||
91 | unsigned 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 | ||
53 | extern 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 */ | ||
62 | static 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 | |||
84 | static 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 */ | ||
108 | const 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 */ | ||
111 | const u32 bigsur_l2irq_reg[] = | ||
112 | { 2, 2, 3, 3, 1, 2, 1, 0, 1, 1, 3, 2}; | ||
113 | /* Level2 to Level 1 IRQ map */ | ||
114 | const 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) */ | ||
117 | const u32 bigsur_l2_inactv_state[] = {0x00, 0xBE, 0xFC, 0xF7}; | ||
118 | |||
119 | /* CPLD external status and mask registers base and offsets */ | ||
120 | static const u32 isr_base = BIGSUR_IRQ0; | ||
121 | static const u32 isr_offset = BIGSUR_IRQ0 - BIGSUR_IRQ1; | ||
122 | static const u32 imr_base = BIGSUR_IMR0; | ||
123 | static 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 */ | ||
128 | static 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 | |||
150 | static 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 | |||
172 | static 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 | |||
181 | static 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 | |||
192 | static 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 | |||
220 | static 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 */ | ||
230 | static 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 | |||
240 | static 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 | |||
251 | static 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 | |||
268 | static 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 | |||
292 | int 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 | /*===========================================================*/ | ||
328 | void __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 | |||
18 | static 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 */ | ||
35 | void 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 | |||
45 | const char *get_system_type(void) | ||
46 | { | ||
47 | return "Big Sur"; | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * The Machine Vector | ||
52 | */ | ||
53 | extern void heartbeat_bigsur(void); | ||
54 | extern void init_bigsur_IRQ(void); | ||
55 | |||
56 | struct 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 | }; | ||
67 | ALIAS_MV(bigsur) | ||
68 | |||
69 | int __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 | |||
5 | obj-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 | |||
17 | int cat68701_irq_demux(int irq) | ||
18 | { | ||
19 | if(irq==13) return 14; | ||
20 | if(irq==7) return 10; | ||
21 | return irq; | ||
22 | } | ||
23 | |||
24 | void 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 | |||
23 | const char *get_system_type(void) | ||
24 | { | ||
25 | return "CAT-68701"; | ||
26 | } | ||
27 | |||
28 | #ifdef CONFIG_HEARTBEAT | ||
29 | void 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 | |||
49 | unsigned 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 | |||
70 | struct 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 | }; | ||
80 | ALIAS_MV(cat68701) | ||
81 | |||
82 | int __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 | |||
5 | obj-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 | |||
22 | struct 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 | }; | ||
27 | static struct cqreek_irq_data cqreek_irq_data[NR_IRQS]; | ||
28 | |||
29 | static 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 | |||
43 | static 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 | |||
57 | static 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 | |||
68 | static 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 | |||
74 | static unsigned int startup_cqreek_irq(unsigned int irq) | ||
75 | { | ||
76 | enable_cqreek_irq(irq); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static void shutdown_cqreek_irq(unsigned int irq) | ||
81 | { | ||
82 | disable_cqreek_irq(irq); | ||
83 | } | ||
84 | |||
85 | static 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 | |||
95 | int 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 */ | ||
99 | void __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 | |||
26 | const char *get_system_type(void) | ||
27 | { | ||
28 | return "CqREEK"; | ||
29 | } | ||
30 | |||
31 | static 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 | */ | ||
44 | struct 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 | }; | ||
57 | ALIAS_MV(cqreek) | ||
58 | |||
59 | /* | ||
60 | * Initialize the board | ||
61 | */ | ||
62 | void __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 | |||
6 | obj-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 | |||
32 | struct 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 | }; | ||
58 | ALIAS_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 | |||
5 | obj-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 */ | ||
58 | static 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 */ | ||
72 | static 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 */ | ||
86 | static 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 */ | ||
94 | static 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 | |||
100 | static unsigned int startup_systemasic_irq(unsigned int irq) | ||
101 | { | ||
102 | enable_systemasic_irq(irq); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static void shutdown_systemasic_irq(unsigned int irq) | ||
108 | { | ||
109 | disable_systemasic_irq(irq); | ||
110 | } | ||
111 | |||
112 | struct 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 | */ | ||
125 | int 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 | |||
16 | extern void (*rtc_get_time)(struct timespec *); | ||
17 | extern 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 | */ | ||
35 | void 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 | */ | ||
58 | int 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 | |||
76 | void 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 | |||
32 | extern struct hw_interrupt_type systemasic_int; | ||
33 | /* XXX: Move this into it's proper header. */ | ||
34 | extern void (*board_time_init)(void); | ||
35 | extern void aica_time_init(void); | ||
36 | extern int gapspci_init(void); | ||
37 | extern int systemasic_irq_demux(int); | ||
38 | |||
39 | void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, int); | ||
40 | int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t); | ||
41 | |||
42 | const char *get_system_type(void) | ||
43 | { | ||
44 | return "Sega Dreamcast"; | ||
45 | } | ||
46 | |||
47 | struct 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 | }; | ||
57 | ALIAS_MV(dreamcast) | ||
58 | |||
59 | int __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 | |||
5 | obj-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 | |||
33 | static 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 | |||
49 | unsigned char ec3104_inb(unsigned long port) | ||
50 | { | ||
51 | u8 ret; | ||
52 | |||
53 | ret = *(volatile u8 *)port2addr(port); | ||
54 | |||
55 | return ret; | ||
56 | } | ||
57 | |||
58 | unsigned short ec3104_inw(unsigned long port) | ||
59 | { | ||
60 | BUG(); | ||
61 | } | ||
62 | |||
63 | unsigned long ec3104_inl(unsigned long port) | ||
64 | { | ||
65 | BUG(); | ||
66 | } | ||
67 | |||
68 | void ec3104_outb(unsigned char data, unsigned long port) | ||
69 | { | ||
70 | *(volatile u8 *)port2addr(port) = data; | ||
71 | } | ||
72 | |||
73 | void ec3104_outw(unsigned short data, unsigned long port) | ||
74 | { | ||
75 | BUG(); | ||
76 | } | ||
77 | |||
78 | void 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 | |||
54 | static 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 | |||
91 | int 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 | |||
110 | static inline u32 ec3104_irq2mask(unsigned int irq) | ||
111 | { | ||
112 | return (1 << (irq - EC3104_IRQBASE)); | ||
113 | } | ||
114 | |||
115 | static 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 | |||
126 | static 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 | |||
137 | static void disable_ec3104_irq(unsigned int irq) | ||
138 | { | ||
139 | mask_ec3104_irq(irq); | ||
140 | } | ||
141 | |||
142 | static void enable_ec3104_irq(unsigned int irq) | ||
143 | { | ||
144 | unmask_ec3104_irq(irq); | ||
145 | } | ||
146 | |||
147 | static void mask_and_ack_ec3104_irq(unsigned int irq) | ||
148 | { | ||
149 | mask_ec3104_irq(irq); | ||
150 | } | ||
151 | |||
152 | static 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 | |||
158 | static unsigned int startup_ec3104_irq(unsigned int irq) | ||
159 | { | ||
160 | unmask_ec3104_irq(irq); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static void shutdown_ec3104_irq(unsigned int irq) | ||
166 | { | ||
167 | mask_ec3104_irq(irq); | ||
168 | |||
169 | } | ||
170 | |||
171 | static 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 */ | ||
182 | int 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 | |||
30 | const char *get_system_type(void) | ||
31 | { | ||
32 | return "EC3104"; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * The Machine Vector | ||
37 | */ | ||
38 | |||
39 | struct 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 | |||
52 | ALIAS_MV(ec3104) | ||
53 | |||
54 | int __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 | |||
5 | obj-y := irq.o setup.o mach.o led.o | ||
6 | |||
7 | obj-$(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 | |||
26 | static void enable_harp_irq(unsigned int irq); | ||
27 | static void disable_harp_irq(unsigned int irq); | ||
28 | |||
29 | /* shutdown is same as "disable" */ | ||
30 | #define shutdown_harp_irq disable_harp_irq | ||
31 | |||
32 | static void mask_and_ack_harp(unsigned int); | ||
33 | static void end_harp_irq(unsigned int irq); | ||
34 | |||
35 | static unsigned int startup_harp_irq(unsigned int irq) | ||
36 | { | ||
37 | enable_harp_irq(irq); | ||
38 | return 0; /* never anything pending */ | ||
39 | } | ||
40 | |||
41 | static 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 | |||
51 | static 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 | |||
80 | static 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 */ | ||
114 | static 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 | |||
121 | static void mask_and_ack_harp(unsigned int irq) | ||
122 | { | ||
123 | disable_harp_irq(irq); | ||
124 | } | ||
125 | |||
126 | static void end_harp_irq(unsigned int irq) | ||
127 | { | ||
128 | enable_harp_irq(irq); | ||
129 | } | ||
130 | |||
131 | void __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 */ | ||
19 | static 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... */ | ||
33 | void 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 | |||
20 | void setup_harp(void); | ||
21 | void init_harp_irq(void); | ||
22 | void heartbeat_harp(void); | ||
23 | |||
24 | /* | ||
25 | * The Machine Vector | ||
26 | */ | ||
27 | |||
28 | struct 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 | |||
62 | ALIAS_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 | |||
18 | void *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 | |||
36 | void 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 | |||
18 | const char *get_system_type(void) | ||
19 | { | ||
20 | return "STB1 Harp"; | ||
21 | } | ||
22 | |||
23 | /* | ||
24 | * Initialize the board | ||
25 | */ | ||
26 | int __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 | |||
71 | int __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 | |||
5 | obj-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 | |||
26 | struct 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 | }; | ||
52 | ALIAS_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 | |||
20 | const char *get_system_type(void) | ||
21 | { | ||
22 | return "HP620"; | ||
23 | } | ||
24 | |||
25 | int __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 | |||
5 | obj-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 | |||
23 | struct 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 | |||
53 | ALIAS_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 | |||
19 | const char *get_system_type(void) | ||
20 | { | ||
21 | return "HP680"; | ||
22 | } | ||
23 | |||
24 | int __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 | |||
5 | obj-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 | |||
22 | struct 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 | }; | ||
48 | ALIAS_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 | |||
5 | obj-y := setup.o rtc.o led.o | ||
6 | |||
7 | obj-$(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 | |||
11 | static 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 */ | ||
27 | void 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 | |||
30 | static struct resource mpcpci_io_resource = { | ||
31 | "MPCPCI IO", | ||
32 | 0x00000000, | ||
33 | 0xffffffff, | ||
34 | IORESOURCE_IO | ||
35 | }; | ||
36 | |||
37 | static struct resource mpcpci_mem_resource = { | ||
38 | "MPCPCI mem", | ||
39 | 0x00000000, | ||
40 | 0xffffffff, | ||
41 | IORESOURCE_MEM | ||
42 | }; | ||
43 | |||
44 | static struct pci_ops pci_direct_conf1; | ||
45 | struct 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 | */ | ||
60 | static 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 | */ | ||
124 | static 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 | |||
156 | static struct pci_ops pci_direct_conf1 = { | ||
157 | .read = pci_conf1_read, | ||
158 | .write = pci_conf1_write, | ||
159 | }; | ||
160 | |||
161 | static 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 | } | ||
179 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_ports); | ||
180 | |||
181 | char * __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 | |||
191 | void __init pcibios_fixup_bus(struct pci_bus *b) | ||
192 | { | ||
193 | pci_read_bridge_bases(b); | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * IRQ functions | ||
198 | */ | ||
199 | static inline u8 bridge_swizzle(u8 pin, u8 slot) | ||
200 | { | ||
201 | return (((pin-1) + slot) % 4) + 1; | ||
202 | } | ||
203 | |||
204 | static inline u8 bridge_swizzle_pci_1(u8 pin, u8 slot) | ||
205 | { | ||
206 | return (((pin-1) - slot) & 3) + 1; | ||
207 | } | ||
208 | |||
209 | static 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 | |||
239 | static 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 | |||
270 | void __init pcibios_fixup_irqs(void) | ||
271 | { | ||
272 | pci_fixup_irqs(mpc1211_swizzle, map_mpc1211_irq); | ||
273 | } | ||
274 | |||
275 | void 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 */ | ||
23 | unsigned 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 | |||
64 | void 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 | */ | ||
82 | static 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 | |||
140 | int mpc1211_rtc_settimeofday(const struct timeval *tv) | ||
141 | { | ||
142 | unsigned long nowtime = tv->tv_sec; | ||
143 | |||
144 | return set_rtc_mmss(nowtime); | ||
145 | } | ||
146 | |||
147 | void 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 | |||
54 | const char *get_system_type(void) | ||
55 | { | ||
56 | return "Interface MPC-1211(CTP/PCI/MPC-SH02)"; | ||
57 | } | ||
58 | |||
59 | static 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 | |||
78 | static unsigned char m_irq_mask = 0xfb; | ||
79 | static unsigned char s_irq_mask = 0xff; | ||
80 | volatile unsigned long irq_err_count; | ||
81 | |||
82 | static 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 | |||
98 | static 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 | |||
114 | static 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 | |||
133 | static 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 | |||
169 | static void end_mpc1211_irq(unsigned int irq) | ||
170 | { | ||
171 | enable_mpc1211_irq(irq); | ||
172 | } | ||
173 | |||
174 | static unsigned int startup_mpc1211_irq(unsigned int irq) | ||
175 | { | ||
176 | enable_mpc1211_irq(irq); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static void shutdown_mpc1211_irq(unsigned int irq) | ||
181 | { | ||
182 | disable_mpc1211_irq(irq); | ||
183 | } | ||
184 | |||
185 | static 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 | |||
195 | static 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 | |||
204 | int 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 | |||
223 | void __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 | |||
264 | static void delay (void) | ||
265 | { | ||
266 | volatile unsigned short tmp; | ||
267 | tmp = *(volatile unsigned short *) 0xa0000000; | ||
268 | } | ||
269 | |||
270 | static void delay1000 (void) | ||
271 | { | ||
272 | int i; | ||
273 | |||
274 | for (i=0; i<1000; i++) | ||
275 | delay (); | ||
276 | } | ||
277 | |||
278 | static 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 | |||
322 | struct 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 | |||
332 | ALIAS_MV(mpc1211) | ||
333 | |||
334 | /* arch/sh/boards/mpc1211/rtc.c */ | ||
335 | void mpc1211_time_init(void); | ||
336 | |||
337 | int __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 | |||
5 | obj-y := mach.o setup.o io.o irq.o led.o time.o | ||
6 | |||
7 | obj-$(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 | |||
35 | static 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 | |||
123 | static const unsigned char __init fpgacode[] = { | ||
124 | #include "./overdrive.ttf" /* Code from maxplus2 compiler */ | ||
125 | , 0, 0 | ||
126 | }; | ||
127 | |||
128 | |||
129 | int __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 | |||
122 | static 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 | |||
136 | static 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 */ | ||
144 | static 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 | */ | ||
197 | int __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 | */ | ||
294 | static 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 | |||
309 | static 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 | |||
328 | static 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 | |||
344 | static 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 | |||
358 | static 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 | |||
369 | static 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 | |||
379 | static 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 | |||
389 | static 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 */ | ||
400 | static struct pci_bus *pci_root_bus; | ||
401 | |||
402 | |||
403 | static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) | ||
404 | { | ||
405 | return PCI_SLOT(dev->devfn); | ||
406 | } | ||
407 | |||
408 | static 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 | |||
431 | void __init | ||
432 | pcibios_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 | |||
440 | static 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 | } | ||
458 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
459 | |||
460 | void __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 | |||
493 | char * __init pcibios_setup(char *str) | ||
494 | { | ||
495 | return str; | ||
496 | } | ||
497 | |||
498 | |||
499 | |||
500 | int 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 */ | ||
533 | void __init pcibios_fixup_bus(struct pci_bus *bus) | ||
534 | { | ||
535 | |||
536 | } | ||
537 | |||
538 | void pcibios_align_resource(void *data, struct resource *res, | ||
539 | unsigned long size) | ||
540 | { | ||
541 | } | ||
542 | |||
543 | void __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, ®); | ||
559 | reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); | ||
560 | pci_write_config_dword(dev, where, reg); | ||
561 | } | ||
562 | |||
563 | |||
564 | void __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 | */ | ||
574 | unsigned int pcibios_max_latency = 255; | ||
575 | |||
576 | void 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 | |||
33 | unsigned char od_inb(unsigned long port) | ||
34 | { | ||
35 | dprintk("od_inb(%x)\n", port); | ||
36 | return readb(io_addr(port)) & 0xff; | ||
37 | } | ||
38 | |||
39 | |||
40 | unsigned short od_inw(unsigned long port) | ||
41 | { | ||
42 | dprintk("od_inw(%x)\n", port); | ||
43 | return readw(io_addr(port)) & 0xffff; | ||
44 | } | ||
45 | |||
46 | unsigned int od_inl(unsigned long port) | ||
47 | { | ||
48 | dprintk("od_inl(%x)\n", port); | ||
49 | return readl(io_addr(port)); | ||
50 | } | ||
51 | |||
52 | void od_outb(unsigned char value, unsigned long port) | ||
53 | { | ||
54 | dprintk("od_outb(%x, %x)\n", value, port); | ||
55 | writeb(value, io_addr(port)); | ||
56 | } | ||
57 | |||
58 | void od_outw(unsigned short value, unsigned long port) | ||
59 | { | ||
60 | dprintk("od_outw(%x, %x)\n", value, port); | ||
61 | writew(value, io_addr(port)); | ||
62 | } | ||
63 | |||
64 | void od_outl(unsigned int value, unsigned long port) | ||
65 | { | ||
66 | dprintk("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) \ | ||
74 | void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();} | ||
75 | |||
76 | #define IN_DELAY(x,type) \ | ||
77 | unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;} | ||
78 | |||
79 | |||
80 | OUT_DELAY(b,char) | ||
81 | OUT_DELAY(w,short) | ||
82 | OUT_DELAY(l,int) | ||
83 | |||
84 | IN_DELAY(b,char) | ||
85 | IN_DELAY(w,short) | ||
86 | IN_DELAY(l,int) | ||
87 | |||
88 | |||
89 | /* Now for the string version of these functions */ | ||
90 | void 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 | |||
101 | void 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 | |||
118 | void 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 | |||
131 | void 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 | |||
145 | void 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 | |||
159 | void 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 | |||
21 | struct 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 | */ | ||
46 | static 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 | |||
66 | static 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 | |||
73 | static void enable_od_irq(unsigned int irq); | ||
74 | void disable_od_irq(unsigned int irq); | ||
75 | |||
76 | /* shutdown is same as "disable" */ | ||
77 | #define shutdown_od_irq disable_od_irq | ||
78 | |||
79 | static void mask_and_ack_od(unsigned int); | ||
80 | static void end_od_irq(unsigned int irq); | ||
81 | |||
82 | static unsigned int startup_od_irq(unsigned int irq) | ||
83 | { | ||
84 | enable_od_irq(irq); | ||
85 | return 0; /* never anything pending */ | ||
86 | } | ||
87 | |||
88 | static 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 | |||
98 | static 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 | |||
122 | static 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 */ | ||
150 | static 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 | |||
158 | static void mask_and_ack_od(unsigned int irq) | ||
159 | { | ||
160 | disable_od_irq(irq); | ||
161 | } | ||
162 | |||
163 | static void end_od_irq(unsigned int irq) | ||
164 | { | ||
165 | enable_od_irq(irq); | ||
166 | } | ||
167 | |||
168 | void __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 | |||
17 | static 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... */ | ||
40 | void 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 | |||
22 | void heartbeat_od(void); | ||
23 | void init_overdrive_irq(void); | ||
24 | void galileo_pcibios_init(void); | ||
25 | |||
26 | /* | ||
27 | * The Machine Vector | ||
28 | */ | ||
29 | |||
30 | struct 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 | |||
62 | ALIAS_MV(od) | ||
diff --git a/arch/sh/boards/overdrive/pcidma.c b/arch/sh/boards/overdrive/pcidma.c new file mode 100644 index 000000000000..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 | |||
20 | void *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 | |||
42 | void 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 | |||
20 | extern void od_time_init(void); | ||
21 | |||
22 | const char *get_system_type(void) | ||
23 | { | ||
24 | return "SH7750 Overdrive"; | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | * Initialize the board | ||
29 | */ | ||
30 | int __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 | |||
13 | void 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 | |||
9 | obj-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 */ | ||
24 | unsigned 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 | */ | ||
43 | unsigned 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 | |||
51 | unsigned int sh_edosk7705_inl(unsigned long port) | ||
52 | { | ||
53 | return *(volatile unsigned long *)port; | ||
54 | } | ||
55 | |||
56 | void 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 | |||
65 | void sh_edosk7705_outl(unsigned int value, unsigned long port) | ||
66 | { | ||
67 | *(volatile unsigned long *)port = value; | ||
68 | } | ||
69 | |||
70 | void 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 | |||
76 | void 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 | |||
83 | void 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 | |||
89 | void 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 | |||
18 | static void init_edosk7705(void); | ||
19 | |||
20 | /* | ||
21 | * The Machine Vector | ||
22 | */ | ||
23 | |||
24 | struct 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 | }; | ||
43 | ALIAS_MV(edosk7705) | ||
44 | |||
45 | static void __init init_edosk7705(void) | ||
46 | { | ||
47 | /* This is the Ethernet interrupt */ | ||
48 | make_imask_irq(0x09); | ||
49 | } | ||
50 | |||
51 | const char *get_system_type(void) | ||
52 | { | ||
53 | return "EDOSK7705"; | ||
54 | } | ||
55 | |||
56 | void __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 | |||
9 | obj-y := mach.o setup.o io.o irq.o led.o | ||
10 | |||
11 | obj-$(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 | |||
25 | extern void *area5_io8_base; /* Area 5 8bit I/O Base address */ | ||
26 | extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ | ||
27 | extern void *area5_io16_base; /* Area 5 16bit I/O Base address */ | ||
28 | extern 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 | |||
52 | static inline void delay(void) | ||
53 | { | ||
54 | ctrl_inw(0xa0000000); | ||
55 | } | ||
56 | |||
57 | static 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 */ | ||
72 | static 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) | ||
82 | static inline int | ||
83 | codec_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 | */ | ||
110 | unsigned 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 | |||
124 | unsigned 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 | |||
142 | unsigned 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 | |||
153 | unsigned 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 | |||
164 | void 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 | |||
179 | void 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 | |||
194 | void 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 | |||
204 | void 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 | |||
214 | void 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 | |||
233 | void 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 | |||
246 | void 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 | |||
256 | void 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 | |||
275 | void 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 | |||
288 | void 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 | |||
298 | void *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 | } | ||
305 | EXPORT_SYMBOL(hs7751rvoip_ioremap); | ||
306 | |||
307 | unsigned 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 | |||
20 | static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7}; | ||
21 | |||
22 | static void enable_hs7751rvoip_irq(unsigned int irq); | ||
23 | static void disable_hs7751rvoip_irq(unsigned int irq); | ||
24 | |||
25 | /* shutdown is same as "disable" */ | ||
26 | #define shutdown_hs7751rvoip_irq disable_hs7751rvoip_irq | ||
27 | |||
28 | static void ack_hs7751rvoip_irq(unsigned int irq); | ||
29 | static void end_hs7751rvoip_irq(unsigned int irq); | ||
30 | |||
31 | static unsigned int startup_hs7751rvoip_irq(unsigned int irq) | ||
32 | { | ||
33 | enable_hs7751rvoip_irq(irq); | ||
34 | return 0; /* never anything pending */ | ||
35 | } | ||
36 | |||
37 | static 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 | |||
51 | static 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 | |||
65 | static void ack_hs7751rvoip_irq(unsigned int irq) | ||
66 | { | ||
67 | disable_hs7751rvoip_irq(irq); | ||
68 | } | ||
69 | |||
70 | static 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 | |||
76 | static 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 | |||
86 | static 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 | */ | ||
96 | void __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 | |||
17 | extern unsigned int debug_counter; | ||
18 | |||
19 | void 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 | |||
20 | extern void init_hs7751rvoip_IRQ(void); | ||
21 | extern void *hs7751rvoip_ioremap(unsigned long, unsigned long); | ||
22 | |||
23 | /* | ||
24 | * The Machine Vector | ||
25 | */ | ||
26 | |||
27 | struct 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 | }; | ||
55 | ALIAS_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 | */ | ||
40 | int __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 | |||
117 | int __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 | |||
130 | static 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 | |||
137 | static 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 | |||
144 | extern struct pci_ops sh7751_pci_ops; | ||
145 | |||
146 | struct pci_channel board_pci_channels[] = { | ||
147 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
148 | { NULL, NULL, NULL, 0, 0 }, | ||
149 | }; | ||
150 | EXPORT_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 */ | ||
26 | extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); | ||
27 | |||
28 | unsigned int debug_counter; | ||
29 | |||
30 | const char *get_system_type(void) | ||
31 | { | ||
32 | return "HS7751RVoIP"; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * Initialize the board | ||
37 | */ | ||
38 | void __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 | |||
45 | void *area5_io8_base; | ||
46 | void *area6_io8_base; | ||
47 | void *area5_io16_base; | ||
48 | void *area6_io16_base; | ||
49 | |||
50 | int __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 | |||
9 | obj-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 | |||
42 | static inline void delay(void) | ||
43 | { | ||
44 | ctrl_inw(0xa0000000); | ||
45 | } | ||
46 | |||
47 | static 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 | |||
60 | static 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 */ | ||
75 | static 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 | */ | ||
109 | unsigned 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 | |||
121 | unsigned 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 | |||
138 | unsigned 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 | |||
152 | unsigned 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 | |||
166 | void 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 | |||
178 | void 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 | |||
191 | void 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 | |||
203 | void 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 | |||
215 | void 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 | |||
234 | void 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 | |||
249 | void 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 | |||
261 | void 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 | |||
280 | void 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 | |||
295 | void 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 | |||
307 | void *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 | } | ||
314 | EXPORT_SYMBOL(rts7751r2d_ioremap); | ||
315 | |||
316 | unsigned 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) | ||
20 | static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; | ||
21 | #else | ||
22 | static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; | ||
23 | #endif | ||
24 | |||
25 | extern int voyagergx_irq_demux(int irq); | ||
26 | extern void setup_voyagergx_irq(void); | ||
27 | |||
28 | static void enable_rts7751r2d_irq(unsigned int irq); | ||
29 | static void disable_rts7751r2d_irq(unsigned int irq); | ||
30 | |||
31 | /* shutdown is same as "disable" */ | ||
32 | #define shutdown_rts7751r2d_irq disable_rts7751r2d_irq | ||
33 | |||
34 | static void ack_rts7751r2d_irq(unsigned int irq); | ||
35 | static void end_rts7751r2d_irq(unsigned int irq); | ||
36 | |||
37 | static unsigned int startup_rts7751r2d_irq(unsigned int irq) | ||
38 | { | ||
39 | enable_rts7751r2d_irq(irq); | ||
40 | return 0; /* never anything pending */ | ||
41 | } | ||
42 | |||
43 | static 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 | |||
57 | static 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 | |||
71 | int rts7751r2d_irq_demux(int irq) | ||
72 | { | ||
73 | int demux_irq; | ||
74 | |||
75 | demux_irq = voyagergx_irq_demux(irq); | ||
76 | return demux_irq; | ||
77 | } | ||
78 | |||
79 | static void ack_rts7751r2d_irq(unsigned int irq) | ||
80 | { | ||
81 | disable_rts7751r2d_irq(irq); | ||
82 | } | ||
83 | |||
84 | static 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 | |||
90 | static 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 | |||
100 | static 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 | */ | ||
110 | void __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 | |||
16 | extern 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 */ | ||
23 | void 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 | |||
54 | void rts7751r2d_led(unsigned short value) | ||
55 | { | ||
56 | ctrl_outw(value, PA_OUTPORT); | ||
57 | } | ||
58 | |||
59 | void 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 | |||
21 | extern void heartbeat_rts7751r2d(void); | ||
22 | extern void init_rts7751r2d_IRQ(void); | ||
23 | extern void *rts7751r2d_ioremap(unsigned long, unsigned long); | ||
24 | extern int rts7751r2d_irq_demux(int irq); | ||
25 | |||
26 | extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int); | ||
27 | extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); | ||
28 | |||
29 | /* | ||
30 | * The Machine Vector | ||
31 | */ | ||
32 | |||
33 | struct 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 | }; | ||
70 | ALIAS_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 | |||
16 | unsigned int debug_counter; | ||
17 | |||
18 | const char *get_system_type(void) | ||
19 | { | ||
20 | return "RTS7751R2D"; | ||
21 | } | ||
22 | |||
23 | /* | ||
24 | * Initialize the board | ||
25 | */ | ||
26 | void __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 | |||
5 | obj-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 | |||
11 | obj-$(CONFIG_PCI) += pci.o | ||
12 | pci-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 | |||
39 | static inline void delay(void) | ||
40 | { | ||
41 | ctrl_inw(0xa0000000); | ||
42 | } | ||
43 | |||
44 | static inline volatile __u16 * | ||
45 | port2adr(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 | */ | ||
75 | unsigned 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 | |||
87 | unsigned 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 | |||
103 | unsigned 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 | |||
118 | unsigned 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 | |||
133 | void 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 | |||
146 | void 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 | |||
159 | void 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 | |||
173 | void 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 | |||
183 | void 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 | |||
189 | void 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 | |||
195 | void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) | ||
196 | { | ||
197 | maybebadio(insl, port); | ||
198 | } | ||
199 | |||
200 | void 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 | |||
206 | void 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 | |||
212 | void 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 | |||
221 | unsigned char sh7751systemh_readb(unsigned long addr) | ||
222 | { | ||
223 | return *(volatile unsigned char*)addr; | ||
224 | } | ||
225 | |||
226 | unsigned short sh7751systemh_readw(unsigned long addr) | ||
227 | { | ||
228 | return *(volatile unsigned short*)addr; | ||
229 | } | ||
230 | |||
231 | unsigned int sh7751systemh_readl(unsigned long addr) | ||
232 | { | ||
233 | return *(volatile unsigned long*)addr; | ||
234 | } | ||
235 | |||
236 | void sh7751systemh_writeb(unsigned char b, unsigned long addr) | ||
237 | { | ||
238 | *(volatile unsigned char*)addr = b; | ||
239 | } | ||
240 | |||
241 | void sh7751systemh_writew(unsigned short b, unsigned long addr) | ||
242 | { | ||
243 | *(volatile unsigned short*)addr = b; | ||
244 | } | ||
245 | |||
246 | void 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. */ | ||
256 | static __u32 sh_isa_memmap[256]; | ||
257 | |||
258 | #if 0 | ||
259 | static int | ||
260 | sh_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 | |||
275 | unsigned long | ||
276 | sh7751systemh_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? */ | ||
25 | static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; | ||
26 | static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; | ||
27 | |||
28 | /* forward declaration */ | ||
29 | static unsigned int startup_systemh_irq(unsigned int irq); | ||
30 | static void shutdown_systemh_irq(unsigned int irq); | ||
31 | static void enable_systemh_irq(unsigned int irq); | ||
32 | static void disable_systemh_irq(unsigned int irq); | ||
33 | static void mask_and_ack_systemh(unsigned int); | ||
34 | static void end_systemh_irq(unsigned int irq); | ||
35 | |||
36 | /* hw_interrupt_type */ | ||
37 | static 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 | |||
47 | static unsigned int startup_systemh_irq(unsigned int irq) | ||
48 | { | ||
49 | enable_systemh_irq(irq); | ||
50 | return 0; /* never anything pending */ | ||
51 | } | ||
52 | |||
53 | static void shutdown_systemh_irq(unsigned int irq) | ||
54 | { | ||
55 | disable_systemh_irq(irq); | ||
56 | } | ||
57 | |||
58 | static 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 | |||
79 | static 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 | |||
94 | static void mask_and_ack_systemh(unsigned int irq) | ||
95 | { | ||
96 | disable_systemh_irq(irq); | ||
97 | } | ||
98 | |||
99 | static 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 | |||
105 | void 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 | |||
22 | extern void make_systemh_irq(unsigned int irq); | ||
23 | |||
24 | const char *get_system_type(void) | ||
25 | { | ||
26 | return "7751 SystemH"; | ||
27 | } | ||
28 | |||
29 | /* | ||
30 | * Initialize IRQ setting | ||
31 | */ | ||
32 | void __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 | |||
39 | struct 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 | }; | ||
74 | ALIAS_MV(7751systemh) | ||
75 | |||
76 | int __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 | |||
5 | obj-y := setup.o io.o irq.o | ||
6 | |||
7 | obj-$(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 | |||
13 | unsigned long saturn_isa_port2addr(unsigned long offset) | ||
14 | { | ||
15 | return offset; | ||
16 | } | ||
17 | |||
18 | void *saturn_ioremap(unsigned long offset, unsigned long size) | ||
19 | { | ||
20 | return (void *)offset; | ||
21 | } | ||
22 | |||
23 | void 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 | |||
41 | static 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 | |||
52 | static 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 | |||
61 | static 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 | |||
70 | static void disable_saturn_irq(unsigned int irq_nr) | ||
71 | { | ||
72 | mask_saturn_irq(irq_nr); | ||
73 | } | ||
74 | |||
75 | static void enable_saturn_irq(unsigned int irq_nr) | ||
76 | { | ||
77 | unmask_saturn_irq(irq_nr); | ||
78 | } | ||
79 | |||
80 | static void mask_and_ack_saturn_irq(unsigned int irq_nr) | ||
81 | { | ||
82 | mask_saturn_irq(irq_nr); | ||
83 | } | ||
84 | |||
85 | static 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 | |||
91 | static unsigned int startup_saturn_irq(unsigned int irq_nr) | ||
92 | { | ||
93 | unmask_saturn_irq(irq_nr); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static void shutdown_saturn_irq(unsigned int irq_nr) | ||
99 | { | ||
100 | mask_saturn_irq(irq_nr); | ||
101 | } | ||
102 | |||
103 | static 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 | |||
113 | int 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 | |||
17 | extern int saturn_irq_demux(int irq_nr); | ||
18 | |||
19 | const char *get_system_type(void) | ||
20 | { | ||
21 | return "Sega Saturn"; | ||
22 | } | ||
23 | |||
24 | /* | ||
25 | * The Machine Vector | ||
26 | */ | ||
27 | struct 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 | |||
37 | ALIAS_MV(saturn) | ||
38 | |||
39 | int __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 | |||
16 | extern void start_secondary(void); | ||
17 | |||
18 | void __smp_send_ipi(unsigned int cpu, unsigned int action) | ||
19 | { | ||
20 | /* Nothing here yet .. */ | ||
21 | } | ||
22 | |||
23 | unsigned 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 | */ | ||
37 | static 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 | |||
46 | static 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 | |||
54 | void __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 | |||
5 | obj-y := setup.o io.o irq.o | ||
6 | |||
7 | obj-$(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 | |||
18 | struct 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 | |||
28 | struct iop * | ||
29 | simple_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 | |||
37 | struct iop * | ||
38 | ide_check(struct iop *p, unsigned long port) | ||
39 | { | ||
40 | if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) | ||
41 | return p; | ||
42 | return NULL; | ||
43 | } | ||
44 | |||
45 | unsigned char | ||
46 | simple_inb(struct iop *p, unsigned long port) | ||
47 | { | ||
48 | return *(unsigned char *) (p->base + port); | ||
49 | } | ||
50 | |||
51 | unsigned short | ||
52 | simple_inw(struct iop *p, unsigned long port) | ||
53 | { | ||
54 | return *(unsigned short *) (p->base + port); | ||
55 | } | ||
56 | |||
57 | void | ||
58 | simple_outb(struct iop *p, unsigned char value, unsigned long port) | ||
59 | { | ||
60 | *(unsigned char *) (p->base + port) = value; | ||
61 | } | ||
62 | |||
63 | void | ||
64 | simple_outw(struct iop *p, unsigned short value, unsigned long port) | ||
65 | { | ||
66 | *(unsigned short *) (p->base + port) = value; | ||
67 | } | ||
68 | |||
69 | unsigned char | ||
70 | pcc_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 | |||
81 | void | ||
82 | pcc_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 | |||
91 | unsigned char | ||
92 | bad_inb(struct iop *p, unsigned long port) | ||
93 | { | ||
94 | badio(inb, port); | ||
95 | } | ||
96 | |||
97 | void | ||
98 | bad_outb(struct iop *p, unsigned char value, unsigned long port) | ||
99 | { | ||
100 | badio(inw, port); | ||
101 | } | ||
102 | |||
103 | /* MSTLANEX01 LAN at 0xb400:0000 */ | ||
104 | static 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 */ | ||
116 | static 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 */ | ||
128 | static 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 | |||
137 | static __inline__ struct iop * | ||
138 | port2iop(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 | |||
157 | static inline void | ||
158 | delay(void) | ||
159 | { | ||
160 | ctrl_inw(0xac000000); | ||
161 | ctrl_inw(0xac000000); | ||
162 | } | ||
163 | |||
164 | unsigned char | ||
165 | sh7300se_inb(unsigned long port) | ||
166 | { | ||
167 | struct iop *p = port2iop(port); | ||
168 | return (p->inb) (p, port); | ||
169 | } | ||
170 | |||
171 | unsigned char | ||
172 | sh7300se_inb_p(unsigned long port) | ||
173 | { | ||
174 | unsigned char v = sh7300se_inb(port); | ||
175 | delay(); | ||
176 | return v; | ||
177 | } | ||
178 | |||
179 | unsigned short | ||
180 | sh7300se_inw(unsigned long port) | ||
181 | { | ||
182 | struct iop *p = port2iop(port); | ||
183 | return (p->inw) (p, port); | ||
184 | } | ||
185 | |||
186 | unsigned int | ||
187 | sh7300se_inl(unsigned long port) | ||
188 | { | ||
189 | badio(inl, port); | ||
190 | } | ||
191 | |||
192 | void | ||
193 | sh7300se_outb(unsigned char value, unsigned long port) | ||
194 | { | ||
195 | struct iop *p = port2iop(port); | ||
196 | (p->outb) (p, value, port); | ||
197 | } | ||
198 | |||
199 | void | ||
200 | sh7300se_outb_p(unsigned char value, unsigned long port) | ||
201 | { | ||
202 | sh7300se_outb(value, port); | ||
203 | delay(); | ||
204 | } | ||
205 | |||
206 | void | ||
207 | sh7300se_outw(unsigned short value, unsigned long port) | ||
208 | { | ||
209 | struct iop *p = port2iop(port); | ||
210 | (p->outw) (p, value, port); | ||
211 | } | ||
212 | |||
213 | void | ||
214 | sh7300se_outl(unsigned int value, unsigned long port) | ||
215 | { | ||
216 | badio(outl, port); | ||
217 | } | ||
218 | |||
219 | void | ||
220 | sh7300se_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 | |||
228 | void | ||
229 | sh7300se_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 | |||
237 | void | ||
238 | sh7300se_insl(unsigned long port, void *addr, unsigned long count) | ||
239 | { | ||
240 | badio(insl, port); | ||
241 | } | ||
242 | |||
243 | void | ||
244 | sh7300se_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 | |||
252 | void | ||
253 | sh7300se_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 | |||
261 | void | ||
262 | sh7300se_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 | */ | ||
20 | void __init | ||
21 | init_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 | |||
18 | static void | ||
19 | mach_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 */ | ||
32 | void | ||
33 | heartbeat_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 | |||
16 | void heartbeat_7300se(void); | ||
17 | void init_7300se_IRQ(void); | ||
18 | |||
19 | const char * | ||
20 | get_system_type(void) | ||
21 | { | ||
22 | return "SolutionEngine 7300"; | ||
23 | } | ||
24 | |||
25 | /* | ||
26 | * The Machine Vector | ||
27 | */ | ||
28 | |||
29 | struct 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 | |||
58 | ALIAS_MV(7300se) | ||
59 | /* | ||
60 | * Initialize the board | ||
61 | */ | ||
62 | void __init | ||
63 | platform_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 | |||
5 | obj-y := setup.o io.o irq.o | ||
6 | |||
7 | obj-$(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 | |||
18 | struct 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 | |||
28 | struct iop * | ||
29 | simple_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 | |||
37 | struct iop * | ||
38 | ide_check(struct iop *p, unsigned long port) | ||
39 | { | ||
40 | if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) | ||
41 | return p; | ||
42 | return NULL; | ||
43 | } | ||
44 | |||
45 | unsigned char | ||
46 | simple_inb(struct iop *p, unsigned long port) | ||
47 | { | ||
48 | return *(unsigned char *) (p->base + port); | ||
49 | } | ||
50 | |||
51 | unsigned short | ||
52 | simple_inw(struct iop *p, unsigned long port) | ||
53 | { | ||
54 | return *(unsigned short *) (p->base + port); | ||
55 | } | ||
56 | |||
57 | void | ||
58 | simple_outb(struct iop *p, unsigned char value, unsigned long port) | ||
59 | { | ||
60 | *(unsigned char *) (p->base + port) = value; | ||
61 | } | ||
62 | |||
63 | void | ||
64 | simple_outw(struct iop *p, unsigned short value, unsigned long port) | ||
65 | { | ||
66 | *(unsigned short *) (p->base + port) = value; | ||
67 | } | ||
68 | |||
69 | unsigned char | ||
70 | pcc_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 | |||
81 | void | ||
82 | pcc_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 | |||
91 | unsigned char | ||
92 | bad_inb(struct iop *p, unsigned long port) | ||
93 | { | ||
94 | badio(inb, port); | ||
95 | } | ||
96 | |||
97 | void | ||
98 | bad_outb(struct iop *p, unsigned char value, unsigned long port) | ||
99 | { | ||
100 | badio(inw, port); | ||
101 | } | ||
102 | |||
103 | /* MSTLANEX01 LAN at 0xb400:0000 */ | ||
104 | static 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 */ | ||
116 | static 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 */ | ||
128 | static 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 | |||
137 | static __inline__ struct iop * | ||
138 | port2iop(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 | |||
157 | static inline void | ||
158 | delay(void) | ||
159 | { | ||
160 | ctrl_inw(0xac000000); | ||
161 | ctrl_inw(0xac000000); | ||
162 | } | ||
163 | |||
164 | unsigned char | ||
165 | sh73180se_inb(unsigned long port) | ||
166 | { | ||
167 | struct iop *p = port2iop(port); | ||
168 | return (p->inb) (p, port); | ||
169 | } | ||
170 | |||
171 | unsigned char | ||
172 | sh73180se_inb_p(unsigned long port) | ||
173 | { | ||
174 | unsigned char v = sh73180se_inb(port); | ||
175 | delay(); | ||
176 | return v; | ||
177 | } | ||
178 | |||
179 | unsigned short | ||
180 | sh73180se_inw(unsigned long port) | ||
181 | { | ||
182 | struct iop *p = port2iop(port); | ||
183 | return (p->inw) (p, port); | ||
184 | } | ||
185 | |||
186 | unsigned int | ||
187 | sh73180se_inl(unsigned long port) | ||
188 | { | ||
189 | badio(inl, port); | ||
190 | } | ||
191 | |||
192 | void | ||
193 | sh73180se_outb(unsigned char value, unsigned long port) | ||
194 | { | ||
195 | struct iop *p = port2iop(port); | ||
196 | (p->outb) (p, value, port); | ||
197 | } | ||
198 | |||
199 | void | ||
200 | sh73180se_outb_p(unsigned char value, unsigned long port) | ||
201 | { | ||
202 | sh73180se_outb(value, port); | ||
203 | delay(); | ||
204 | } | ||
205 | |||
206 | void | ||
207 | sh73180se_outw(unsigned short value, unsigned long port) | ||
208 | { | ||
209 | struct iop *p = port2iop(port); | ||
210 | (p->outw) (p, value, port); | ||
211 | } | ||
212 | |||
213 | void | ||
214 | sh73180se_outl(unsigned int value, unsigned long port) | ||
215 | { | ||
216 | badio(outl, port); | ||
217 | } | ||
218 | |||
219 | void | ||
220 | sh73180se_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 | |||
228 | void | ||
229 | sh73180se_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 | |||
237 | void | ||
238 | sh73180se_insl(unsigned long port, void *addr, unsigned long count) | ||
239 | { | ||
240 | badio(insl, port); | ||
241 | } | ||
242 | |||
243 | void | ||
244 | sh73180se_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 | |||
252 | void | ||
253 | sh73180se_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 | |||
261 | void | ||
262 | sh73180se_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 | |||
20 | static int | ||
21 | intreq2irq(int i) | ||
22 | { | ||
23 | if (i == 5) | ||
24 | return 10; | ||
25 | return 32 + 7 - i; | ||
26 | } | ||
27 | |||
28 | static int | ||
29 | irq2intreq(int irq) | ||
30 | { | ||
31 | if (irq == 10) | ||
32 | return 5; | ||
33 | return 7 - (irq - 32); | ||
34 | } | ||
35 | |||
36 | static void | ||
37 | disable_intreq_irq(unsigned int irq) | ||
38 | { | ||
39 | ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSK0); | ||
40 | } | ||
41 | |||
42 | static void | ||
43 | enable_intreq_irq(unsigned int irq) | ||
44 | { | ||
45 | ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSKCLR0); | ||
46 | } | ||
47 | |||
48 | static void | ||
49 | mask_and_ack_intreq_irq(unsigned int irq) | ||
50 | { | ||
51 | disable_intreq_irq(irq); | ||
52 | } | ||
53 | |||
54 | static unsigned int | ||
55 | startup_intreq_irq(unsigned int irq) | ||
56 | { | ||
57 | enable_intreq_irq(irq); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static void | ||
62 | shutdown_intreq_irq(unsigned int irq) | ||
63 | { | ||
64 | disable_intreq_irq(irq); | ||
65 | } | ||
66 | |||
67 | static void | ||
68 | end_intreq_irq(unsigned int irq) | ||
69 | { | ||
70 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
71 | enable_intreq_irq(irq); | ||
72 | } | ||
73 | |||
74 | static 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 | |||
84 | void | ||
85 | make_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 | |||
92 | int | ||
93 | shmse_irq_demux(int irq) | ||
94 | { | ||
95 | if (irq == IRQ5_IRQ) | ||
96 | return 10; | ||
97 | return irq; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Initialize IRQ setting | ||
102 | */ | ||
103 | void __init | ||
104 | init_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 | |||
18 | static void | ||
19 | mach_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 */ | ||
31 | void | ||
32 | heartbeat_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 | |||
18 | void heartbeat_73180se(void); | ||
19 | void init_73180se_IRQ(void); | ||
20 | |||
21 | const char * | ||
22 | get_system_type(void) | ||
23 | { | ||
24 | return "SolutionEngine 73180"; | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | * The Machine Vector | ||
29 | */ | ||
30 | |||
31 | struct 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 | |||
60 | ALIAS_MV(73180se) | ||
61 | /* | ||
62 | * Initialize the board | ||
63 | */ | ||
64 | void __init | ||
65 | platform_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 | |||
5 | obj-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. */ | ||
17 | int sh_pcic_io_wbase = 0xb8400000; | ||
18 | int sh_pcic_io_start; | ||
19 | int sh_pcic_io_stop; | ||
20 | int sh_pcic_io_type; | ||
21 | int sh_pcic_io_dummy; | ||
22 | |||
23 | static 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 | |||
32 | static inline volatile __u16 * | ||
33 | port2adr(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 | |||
45 | static inline int | ||
46 | shifted_port(unsigned long port) | ||
47 | { | ||
48 | /* For IDE registers, value is not shifted */ | ||
49 | if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) | ||
50 | return 0; | ||
51 | else | ||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | #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 | |||
59 | unsigned 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 | |||
69 | unsigned 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 | |||
83 | unsigned 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 | |||
93 | unsigned int se_inl(unsigned long port) | ||
94 | { | ||
95 | maybebadio(inl, port); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | void 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 | |||
109 | void 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 | |||
120 | void 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 | |||
129 | void se_outl(unsigned int value, unsigned long port) | ||
130 | { | ||
131 | maybebadio(outl, port); | ||
132 | } | ||
133 | |||
134 | void 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 | |||
152 | void 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 | |||
160 | void se_insl(unsigned long port, void *addr, unsigned long count) | ||
161 | { | ||
162 | maybebadio(insl, port); | ||
163 | } | ||
164 | |||
165 | void 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 | |||
183 | void 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 | |||
191 | void 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. */ | ||
199 | static __u32 sh_isa_memmap[256]; | ||
200 | |||
201 | static int | ||
202 | 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 | |||
218 | unsigned long | ||
219 | se_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 | */ | ||
20 | void __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 | |||
15 | static 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 */ | ||
31 | void 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 | |||
21 | void heartbeat_se(void); | ||
22 | void setup_se(void); | ||
23 | void init_se_IRQ(void); | ||
24 | |||
25 | /* | ||
26 | * The Machine Vector | ||
27 | */ | ||
28 | |||
29 | struct 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 | }; | ||
68 | ALIAS_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 | */ | ||
24 | static void __init smsc_config(int index, int data) | ||
25 | { | ||
26 | outb_p(index, INDEX_PORT); | ||
27 | outb_p(data, DATA_PORT); | ||
28 | } | ||
29 | |||
30 | static 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 | |||
73 | const char *get_system_type(void) | ||
74 | { | ||
75 | return "SolutionEngine"; | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Initialize the board | ||
80 | */ | ||
81 | void __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 | |||
5 | obj-y := mach.o setup.o io.o irq.o led.o | ||
6 | |||
7 | obj-$(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. */ | ||
33 | int sh_pcic_io_wbase = 0xb8400000; | ||
34 | int sh_pcic_io_start; | ||
35 | int sh_pcic_io_stop; | ||
36 | int sh_pcic_io_type; | ||
37 | int 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 | |||
59 | static inline void delay(void) | ||
60 | { | ||
61 | ctrl_inw(0xa0000000); | ||
62 | } | ||
63 | |||
64 | static inline volatile __u16 * | ||
65 | port2adr(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 */ | ||
81 | static inline int | ||
82 | shifted_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 | */ | ||
110 | unsigned 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 | |||
120 | unsigned 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 | |||
134 | unsigned 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 | |||
147 | unsigned 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 | |||
160 | void 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 | |||
171 | void 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 | |||
182 | void 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 | |||
194 | void 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 | |||
204 | void sh7751se_insl(unsigned long port, void *addr, unsigned long count) | ||
205 | { | ||
206 | maybebadio(insl, port); | ||
207 | } | ||
208 | |||
209 | void 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. */ | ||
217 | static __u32 sh_isa_memmap[256]; | ||
218 | |||
219 | #if 0 | ||
220 | static int | ||
221 | sh_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 | |||
236 | unsigned long | ||
237 | sh7751se_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 | */ | ||
21 | void __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 | |||
15 | static 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 */ | ||
31 | void 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 | |||
21 | void heartbeat_7751se(void); | ||
22 | void init_7751se_IRQ(void); | ||
23 | |||
24 | /* | ||
25 | * The Machine Vector | ||
26 | */ | ||
27 | |||
28 | struct 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 | }; | ||
55 | ALIAS_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 | */ | ||
38 | int __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 | |||
114 | int __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 | |||
128 | static 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 | |||
135 | static 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 | |||
142 | extern struct pci_ops sh7751_pci_ops; | ||
143 | |||
144 | struct 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. */ | ||
31 | static void __init smsc_config(int index, int data) | ||
32 | { | ||
33 | outb_p(index, INDEX_PORT); | ||
34 | outb_p(data, DATA_PORT); | ||
35 | } | ||
36 | |||
37 | static 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 | |||
81 | const char *get_system_type(void) | ||
82 | { | ||
83 | return "7751 SolutionEngine"; | ||
84 | } | ||
85 | |||
86 | #ifdef CONFIG_SH_KGDB | ||
87 | static int kgdb_uart_setup(void); | ||
88 | static struct kgdb_sermap kgdb_uart_sermap = | ||
89 | { "ttyS", 0, kgdb_uart_setup, NULL }; | ||
90 | #endif | ||
91 | |||
92 | /* | ||
93 | * Initialize the board | ||
94 | */ | ||
95 | void __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 | |||
126 | struct uart_port { | ||
127 | int base; | ||
128 | }; | ||
129 | #define UART_NPORTS 2 | ||
130 | struct uart_port uart_ports[] = { | ||
131 | { COM1_PORT }, | ||
132 | { COM2_PORT }, | ||
133 | }; | ||
134 | struct 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) | ||
141 | static 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 | |||
156 | static 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 | */ | ||
167 | static 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 | |||
5 | obj-y := setup.o rtc.o | ||
6 | obj-$(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 */ | ||
13 | void 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 | |||
44 | extern void (*rtc_get_time)(struct timespec *); | ||
45 | extern int (*rtc_set_time)(const time_t); | ||
46 | extern spinlock_t rtc_lock; | ||
47 | |||
48 | unsigned 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 | |||
92 | void sh03_rtc_gettimeofday(struct timespec *tv) | ||
93 | { | ||
94 | |||
95 | tv->tv_sec = get_cmos_time(); | ||
96 | tv->tv_nsec = 0; | ||
97 | } | ||
98 | |||
99 | static 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 | |||
133 | int sh03_rtc_settimeofday(const time_t secs) | ||
134 | { | ||
135 | unsigned long nowtime = secs; | ||
136 | |||
137 | return set_rtc_mmss(nowtime); | ||
138 | } | ||
139 | |||
140 | void 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 | |||
19 | extern void (*board_time_init)(void); | ||
20 | |||
21 | const char *get_system_type(void) | ||
22 | { | ||
23 | return "Interface CTP/PCI-SH03)"; | ||
24 | } | ||
25 | |||
26 | void 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 | |||
36 | extern void *cf_io_base; | ||
37 | |||
38 | unsigned 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 | |||
53 | struct 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 | |||
63 | ALIAS_MV(sh03) | ||
64 | |||
65 | /* arch/sh/boards/sh03/rtc.c */ | ||
66 | void sh03_time_init(void); | ||
67 | |||
68 | int __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 | |||
5 | obj-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 | |||
30 | const char *get_system_type(void) | ||
31 | { | ||
32 | return "sh2000"; | ||
33 | } | ||
34 | |||
35 | static 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 | */ | ||
47 | struct sh_machine_vector mv_sh2000 __initmv = { | ||
48 | .mv_nr_irqs = 80, | ||
49 | .mv_isa_port2addr = sh2000_isa_port2addr, | ||
50 | }; | ||
51 | ALIAS_MV(sh2000) | ||
52 | |||
53 | /* | ||
54 | * Initialize the board | ||
55 | */ | ||
56 | int __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 | |||
5 | obj-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 | ||
25 | unsigned 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 | |||
47 | static inline void delay(void) | ||
48 | { | ||
49 | ctrl_inw(0xa0000000); | ||
50 | } | ||
51 | |||
52 | |||
53 | static 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 | |||
83 | unsigned 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 | |||
94 | unsigned 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 | |||
109 | unsigned 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 | |||
123 | unsigned 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 | |||
137 | void 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 | |||
149 | void 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 | |||
161 | void 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 | |||
174 | void 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 | |||
184 | void snapgear_insl(unsigned long port, void *addr, unsigned long count) | ||
185 | { | ||
186 | maybebadio(insl, port); | ||
187 | } | ||
188 | |||
189 | void 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. */ | ||
198 | static __u32 sh_isa_memmap[256]; | ||
199 | |||
200 | |||
201 | #if 0 | ||
202 | static 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 | |||
219 | unsigned 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 | |||
27 | static 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 | |||
56 | static 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 | |||
67 | static 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 | |||
80 | static 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 | |||
103 | static 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 | |||
121 | static 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 | |||
133 | static inline int bcd2int(int val) | ||
134 | { | ||
135 | return((((val & 0xf0) >> 4) * 10) + (val & 0xf)); | ||
136 | } | ||
137 | |||
138 | static 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 | |||
149 | void snapgear_rtc_gettimeofday(struct timespec *); | ||
150 | int snapgear_rtc_settimeofday(const time_t); | ||
151 | |||
152 | void __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 | |||
186 | void 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 | |||
202 | bad_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 | |||
227 | int 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 | |||
279 | unsigned 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 | |||
307 | void 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 | |||
32 | extern void (*board_time_init)(void); | ||
33 | extern void secureedge5410_rtc_init(void); | ||
34 | extern void pcibios_init(void); | ||
35 | |||
36 | /****************************************************************************/ | ||
37 | /* | ||
38 | * EraseConfig handling functions | ||
39 | */ | ||
40 | |||
41 | static 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 | |||
50 | static 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 | |||
64 | module_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 | |||
76 | static 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 | ||
118 | static 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 | |||
131 | unsigned 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 | |||
140 | static 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 | |||
174 | const char *get_system_type(void) | ||
175 | { | ||
176 | return "SnapGear SecureEdge5410"; | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * The Machine Vector | ||
181 | */ | ||
182 | |||
183 | struct 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 | }; | ||
204 | ALIAS_MV(snapgear) | ||
205 | |||
206 | /* | ||
207 | * Initialize the board | ||
208 | */ | ||
209 | |||
210 | int __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 | |||
5 | obj-y := setup.o irq.o io.o | ||
6 | |||
7 | obj-$(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 | |||
58 | static 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 | |||
70 | unsigned 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 | |||
79 | unsigned 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 | |||
88 | unsigned 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 | |||
97 | void 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 | |||
161 | void 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 | |||
172 | void 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 | |||
183 | unsigned char microdev_inb_p(unsigned long port) | ||
184 | { | ||
185 | unsigned char v = microdev_inb(port); | ||
186 | delay(); | ||
187 | return v; | ||
188 | } | ||
189 | |||
190 | unsigned short microdev_inw_p(unsigned long port) | ||
191 | { | ||
192 | unsigned short v = microdev_inw(port); | ||
193 | delay(); | ||
194 | return v; | ||
195 | } | ||
196 | |||
197 | unsigned int microdev_inl_p(unsigned long port) | ||
198 | { | ||
199 | unsigned int v = microdev_inl(port); | ||
200 | delay(); | ||
201 | return v; | ||
202 | } | ||
203 | |||
204 | void microdev_outb_p(unsigned char b, unsigned long port) | ||
205 | { | ||
206 | microdev_outb(b, port); | ||
207 | delay(); | ||
208 | } | ||
209 | |||
210 | void microdev_outw_p(unsigned short b, unsigned long port) | ||
211 | { | ||
212 | microdev_outw(b, port); | ||
213 | delay(); | ||
214 | } | ||
215 | |||
216 | void microdev_outl_p(unsigned int b, unsigned long port) | ||
217 | { | ||
218 | microdev_outl(b, port); | ||
219 | delay(); | ||
220 | } | ||
221 | |||
222 | void 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 | |||
233 | void 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 | |||
244 | void 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 | |||
255 | void 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 | |||
266 | void 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 | |||
277 | void 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 | */ | ||
291 | unsigned 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 | |||
23 | static 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 | |||
70 | static void enable_microdev_irq(unsigned int irq); | ||
71 | static void disable_microdev_irq(unsigned int irq); | ||
72 | |||
73 | /* shutdown is same as "disable" */ | ||
74 | #define shutdown_microdev_irq disable_microdev_irq | ||
75 | |||
76 | static void mask_and_ack_microdev(unsigned int); | ||
77 | static void end_microdev_irq(unsigned int irq); | ||
78 | |||
79 | static unsigned int startup_microdev_irq(unsigned int irq) | ||
80 | { | ||
81 | enable_microdev_irq(irq); | ||
82 | return 0; /* never anything pending */ | ||
83 | } | ||
84 | |||
85 | static 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 | |||
95 | static 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 | |||
115 | static 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 */ | ||
147 | static void __init make_microdev_irq(unsigned int irq) | ||
148 | { | ||
149 | disable_irq_nosync(irq); | ||
150 | irq_desc[irq].handler = µdev_irq_type; | ||
151 | disable_microdev_irq(irq); | ||
152 | } | ||
153 | |||
154 | static void mask_and_ack_microdev(unsigned int irq) | ||
155 | { | ||
156 | disable_microdev_irq(irq); | ||
157 | } | ||
158 | |||
159 | static 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 | |||
167 | extern 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 | |||
180 | extern 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 | |||
17 | static 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 | |||
27 | static 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 | |||
41 | static 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 | |||
59 | static 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... */ | ||
80 | void 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 | |||
24 | extern void microdev_heartbeat(void); | ||
25 | |||
26 | /* | ||
27 | * The Machine Vector | ||
28 | */ | ||
29 | |||
30 | struct 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 | }; | ||
62 | ALIAS_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 */ | ||
118 | int microdev_kbd_controller_present = 1; | ||
119 | |||
120 | const char *get_system_type(void) | ||
121 | { | ||
122 | return "SH4-202 MicroDev"; | ||
123 | } | ||
124 | |||
125 | static 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 | |||
138 | static struct platform_device smc91x_device = { | ||
139 | .name = "smc91x", | ||
140 | .id = -1, | ||
141 | .num_resources = ARRAY_SIZE(smc91x_resources), | ||
142 | .resource = smc91x_resources, | ||
143 | }; | ||
144 | |||
145 | static 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 | */ | ||
155 | void __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 | */ | ||
172 | static 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 | |||
5 | obj-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 | |||
12 | static 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 | |||
20 | UNKNOWN_ALIAS(inb) | ||
21 | UNKNOWN_ALIAS(inw) | ||
22 | UNKNOWN_ALIAS(inl) | ||
23 | UNKNOWN_ALIAS(outb) | ||
24 | UNKNOWN_ALIAS(outw) | ||
25 | UNKNOWN_ALIAS(outl) | ||
26 | UNKNOWN_ALIAS(inb_p) | ||
27 | UNKNOWN_ALIAS(inw_p) | ||
28 | UNKNOWN_ALIAS(inl_p) | ||
29 | UNKNOWN_ALIAS(outb_p) | ||
30 | UNKNOWN_ALIAS(outw_p) | ||
31 | UNKNOWN_ALIAS(outl_p) | ||
32 | UNKNOWN_ALIAS(insb) | ||
33 | UNKNOWN_ALIAS(insw) | ||
34 | UNKNOWN_ALIAS(insl) | ||
35 | UNKNOWN_ALIAS(outsb) | ||
36 | UNKNOWN_ALIAS(outsw) | ||
37 | UNKNOWN_ALIAS(outsl) | ||
38 | UNKNOWN_ALIAS(readb) | ||
39 | UNKNOWN_ALIAS(readw) | ||
40 | UNKNOWN_ALIAS(readl) | ||
41 | UNKNOWN_ALIAS(writeb) | ||
42 | UNKNOWN_ALIAS(writew) | ||
43 | UNKNOWN_ALIAS(writel) | ||
44 | UNKNOWN_ALIAS(isa_port2addr) | ||
45 | UNKNOWN_ALIAS(ioremap) | ||
46 | UNKNOWN_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 | |||
25 | struct 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 | }; | ||
67 | ALIAS_MV(unknown) | ||
diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c new file mode 100644 index 000000000000..7d772a6f8865 --- /dev/null +++ b/arch/sh/boards/unknown/setup.c | |||
@@ -0,0 +1,23 @@ | |||
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 | |||
15 | const char *get_system_type(void) | ||
16 | { | ||
17 | return "Unknown"; | ||
18 | } | ||
19 | |||
20 | void __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 | |||
11 | targets := zImage | ||
12 | subdir- := 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 | |||
7 | targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o | ||
8 | EXTRA_AFLAGS := -traditional | ||
9 | |||
10 | OBJECTS = $(obj)/head.o $(obj)/misc.o | ||
11 | |||
12 | ifdef CONFIG_SH_STANDARD_BIOS | ||
13 | OBJECTS += $(obj)/../../kernel/sh_bios.o | ||
14 | endif | ||
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 | # | ||
21 | CONFIG_MEMORY_START ?= 0x0c000000 | ||
22 | CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 | ||
23 | IMAGE_OFFSET := $(shell printf "0x%8x" $$[0x80000000+$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) | ||
24 | |||
25 | LDFLAGS_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 | |||
37 | LDFLAGS_piggy.o := -r --format binary --oformat elf32-sh-linux -T | ||
38 | OBJCOPYFLAGS += -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 | ||
14 | startup: | ||
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 | ||
31 | 3: | ||
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 | ||
60 | 1: .long 1b | ||
61 | 2: .long clear_bss | ||
62 | text_start_addr: | ||
63 | .long startup | ||
64 | |||
65 | /* Clear BSS */ | ||
66 | clear_bss: | ||
67 | mov.l end_addr, r1 | ||
68 | mov.l bss_start_addr, r2 | ||
69 | mov #0, r0 | ||
70 | l1: | ||
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 | ||
90 | bss_start_addr: | ||
91 | .long __bss_start | ||
92 | end_addr: | ||
93 | .long _end | ||
94 | init_sr: | ||
95 | .long 0x400000F0 /* Privileged mode, Bank=0, Block=0, IMASK=0xF */ | ||
96 | init_stack_addr: | ||
97 | .long stack_start | ||
98 | decompress_kernel_addr: | ||
99 | .long decompress_kernel | ||
100 | kernel_start_addr: | ||
101 | .long _text+0x1000 | ||
102 | |||
103 | .align 9 | ||
104 | fake_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 | |||
26 | if [ -x /sbin/installkernel ]; then | ||
27 | exec /sbin/installkernel "$@" | ||
28 | fi | ||
29 | |||
30 | if [ "$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 | ||
43 | else | ||
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 | ||
56 | fi | ||
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 | |||
31 | typedef unsigned char uch; | ||
32 | typedef unsigned short ush; | ||
33 | typedef unsigned long ulg; | ||
34 | |||
35 | #define WSIZE 0x8000 /* Window size must be at least 32k, */ | ||
36 | /* and a power of two */ | ||
37 | |||
38 | static uch *inbuf; /* input buffer */ | ||
39 | static uch window[WSIZE]; /* Sliding window buffer */ | ||
40 | |||
41 | static unsigned insize = 0; /* valid bytes in inbuf */ | ||
42 | static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ | ||
43 | static 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 | |||
73 | static int fill_inbuf(void); | ||
74 | static void flush_window(void); | ||
75 | static void error(char *m); | ||
76 | static void gzip_mark(void **); | ||
77 | static void gzip_release(void **); | ||
78 | |||
79 | extern char input_data[]; | ||
80 | extern int input_len; | ||
81 | |||
82 | static long bytes_out = 0; | ||
83 | static uch *output_data; | ||
84 | static unsigned long output_ptr = 0; | ||
85 | |||
86 | static void *malloc(int size); | ||
87 | static void free(void *where); | ||
88 | static void error(char *m); | ||
89 | static void gzip_mark(void **); | ||
90 | static void gzip_release(void **); | ||
91 | |||
92 | int puts(const char *); | ||
93 | |||
94 | extern int _text; /* Defined in vmlinux.lds.S */ | ||
95 | extern int _end; | ||
96 | static unsigned long free_mem_ptr; | ||
97 | static unsigned long free_mem_end_ptr; | ||
98 | |||
99 | #define HEAP_SIZE 0x10000 | ||
100 | |||
101 | #include "../../../../lib/inflate.c" | ||
102 | |||
103 | static 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 | |||
121 | static void free(void *where) | ||
122 | { /* Don't care */ | ||
123 | } | ||
124 | |||
125 | static void gzip_mark(void **ptr) | ||
126 | { | ||
127 | *ptr = (void *) free_mem_ptr; | ||
128 | } | ||
129 | |||
130 | static void gzip_release(void **ptr) | ||
131 | { | ||
132 | free_mem_ptr = (long) *ptr; | ||
133 | } | ||
134 | |||
135 | #ifdef CONFIG_SH_STANDARD_BIOS | ||
136 | size_t strlen(const char *s) | ||
137 | { | ||
138 | int i = 0; | ||
139 | |||
140 | while (*s++) | ||
141 | i++; | ||
142 | return i; | ||
143 | } | ||
144 | |||
145 | int puts(const char *s) | ||
146 | { | ||
147 | int len = strlen(s); | ||
148 | sh_bios_console_write(s, len); | ||
149 | return len; | ||
150 | } | ||
151 | #else | ||
152 | int puts(const char *s) | ||
153 | { | ||
154 | /* This should be updated to use the sh-sci routines */ | ||
155 | return 0; | ||
156 | } | ||
157 | #endif | ||
158 | |||
159 | void* 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 | |||
168 | void* 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 | */ | ||
182 | static 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 | */ | ||
198 | static 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 | |||
216 | static 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) | ||
226 | long user_stack [STACK_SIZE]; | ||
227 | long* stack_start = &user_stack[STACK_SIZE]; | ||
228 | |||
229 | void 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 @@ | |||
1 | SECTIONS | ||
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 @@ | |||
1 | menu "Companion Chips" | ||
2 | |||
3 | config 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 | ||
17 | config HD6446X_SERIES | ||
18 | bool "HD6446x support" | ||
19 | default n | ||
20 | |||
21 | choice | ||
22 | prompt "HD6446x options" | ||
23 | depends on HD6446X_SERIES | ||
24 | default HD64461 | ||
25 | |||
26 | config 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 | |||
41 | config 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 | |||
56 | endchoice | ||
57 | |||
58 | # These will also be split into the Kconfig's below | ||
59 | config 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 | |||
68 | config 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 | |||
77 | config 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 | |||
86 | config 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 | |||
95 | endmenu | ||
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 | |||
5 | obj-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 | |||
13 | static __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 | |||
58 | static inline void delay(void) | ||
59 | { | ||
60 | ctrl_inw(0xa0000000); | ||
61 | } | ||
62 | |||
63 | unsigned char hd64461_inb(unsigned long port) | ||
64 | { | ||
65 | return *(volatile unsigned char*)PORT2ADDR(port); | ||
66 | } | ||
67 | |||
68 | unsigned char hd64461_inb_p(unsigned long port) | ||
69 | { | ||
70 | unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); | ||
71 | delay(); | ||
72 | return v; | ||
73 | } | ||
74 | |||
75 | unsigned short hd64461_inw(unsigned long port) | ||
76 | { | ||
77 | return *(volatile unsigned short*)PORT2ADDR(port); | ||
78 | } | ||
79 | |||
80 | unsigned int hd64461_inl(unsigned long port) | ||
81 | { | ||
82 | return *(volatile unsigned long*)PORT2ADDR(port); | ||
83 | } | ||
84 | |||
85 | void hd64461_outb(unsigned char b, unsigned long port) | ||
86 | { | ||
87 | *(volatile unsigned char*)PORT2ADDR(port) = b; | ||
88 | } | ||
89 | |||
90 | void hd64461_outb_p(unsigned char b, unsigned long port) | ||
91 | { | ||
92 | *(volatile unsigned char*)PORT2ADDR(port) = b; | ||
93 | delay(); | ||
94 | } | ||
95 | |||
96 | void hd64461_outw(unsigned short b, unsigned long port) | ||
97 | { | ||
98 | *(volatile unsigned short*)PORT2ADDR(port) = b; | ||
99 | } | ||
100 | |||
101 | void hd64461_outl(unsigned int b, unsigned long port) | ||
102 | { | ||
103 | *(volatile unsigned long*)PORT2ADDR(port) = b; | ||
104 | } | ||
105 | |||
106 | void 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 | |||
113 | void 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 | |||
120 | void 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 | |||
127 | void 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 | |||
134 | void 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 | |||
141 | void 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 | |||
148 | unsigned short hd64461_readw(unsigned long addr) | ||
149 | { | ||
150 | return *(volatile unsigned short*)(MEM_BASE+addr); | ||
151 | } | ||
152 | |||
153 | void 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 | |||
21 | static 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 | |||
34 | static 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 | |||
47 | static 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 | |||
56 | static 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 | |||
62 | static unsigned int startup_hd64461_irq(unsigned int irq) | ||
63 | { | ||
64 | enable_hd64461_irq(irq); | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static void shutdown_hd64461_irq(unsigned int irq) | ||
69 | { | ||
70 | disable_hd64461_irq(irq); | ||
71 | } | ||
72 | |||
73 | static 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 | |||
83 | static 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 | |||
92 | static struct { | ||
93 | int (*func) (int, void *); | ||
94 | void *dev; | ||
95 | } hd64461_demux[HD64461_IRQ_NUM]; | ||
96 | |||
97 | void 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 | |||
104 | EXPORT_SYMBOL(hd64461_register_irq_demux); | ||
105 | |||
106 | void hd64461_unregister_irq_demux(int irq) | ||
107 | { | ||
108 | hd64461_demux[irq - HD64461_IRQBASE].func = 0; | ||
109 | } | ||
110 | |||
111 | EXPORT_SYMBOL(hd64461_unregister_irq_demux); | ||
112 | |||
113 | int 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 | |||
137 | static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64461", NULL, NULL }; | ||
138 | |||
139 | int __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 | |||
171 | module_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 | |||
5 | obj-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 | |||
30 | EXPORT_SYMBOL(hd64465_gpio_configure); | ||
31 | EXPORT_SYMBOL(hd64465_gpio_get_pin); | ||
32 | EXPORT_SYMBOL(hd64465_gpio_get_port); | ||
33 | EXPORT_SYMBOL(hd64465_gpio_register_irq); | ||
34 | EXPORT_SYMBOL(hd64465_gpio_set_pin); | ||
35 | EXPORT_SYMBOL(hd64465_gpio_set_port); | ||
36 | EXPORT_SYMBOL(hd64465_gpio_unregister_irq); | ||
37 | |||
38 | /* TODO: each port should be protected with a spinlock */ | ||
39 | |||
40 | |||
41 | void 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 | |||
52 | void 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 | |||
65 | unsigned 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 | |||
72 | void hd64465_gpio_set_port(int port, unsigned int value) | ||
73 | { | ||
74 | outw(value, GPIO_DR(port)); | ||
75 | } | ||
76 | |||
77 | unsigned int hd64465_gpio_get_port(int port) | ||
78 | { | ||
79 | return inw(GPIO_DR(port)); | ||
80 | } | ||
81 | |||
82 | |||
83 | static struct { | ||
84 | void (*func)(int portpin, void *dev); | ||
85 | void *dev; | ||
86 | } handlers[GPIO_NPORTS * 8]; | ||
87 | |||
88 | static 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 | |||
114 | void 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 | |||
148 | void 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 | |||
168 | static 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 | |||
180 | out_irqfailed: | ||
181 | release_region(HD64465_REG_GPACR, 0x1000); | ||
182 | |||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | static void __exit hd64465_gpio_exit(void) | ||
187 | { | ||
188 | release_region(HD64465_REG_GPACR, 0x1000); | ||
189 | free_irq(HD64465_IRQ_GPIO, 0); | ||
190 | } | ||
191 | |||
192 | module_init(hd64465_gpio_init); | ||
193 | module_exit(hd64465_gpio_exit); | ||
194 | |||
195 | MODULE_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 */ | ||
32 | int hd64465_io_debug; | ||
33 | EXPORT_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) | ||
40 | static unsigned long hd64465_iomap_lo[HD64465_IOMAP_LO_NMAP]; | ||
41 | static 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) | ||
48 | static unsigned long hd64465_iomap_hi[HD64465_IOMAP_HI_NMAP]; | ||
49 | static 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 | |||
57 | void 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 | } | ||
83 | EXPORT_SYMBOL(hd64465_port_map); | ||
84 | |||
85 | void 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 | } | ||
104 | EXPORT_SYMBOL(hd64465_port_unmap); | ||
105 | |||
106 | unsigned 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 | |||
141 | static inline void delay(void) | ||
142 | { | ||
143 | ctrl_inw(0xa0000000); | ||
144 | } | ||
145 | |||
146 | unsigned 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 | |||
155 | unsigned 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 | |||
166 | unsigned 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 | |||
174 | unsigned 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 | |||
182 | void 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 | |||
191 | void 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 | |||
201 | void 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 | |||
209 | void 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 | |||
27 | static 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 | |||
42 | static 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 | |||
57 | static void mask_and_ack_hd64465(unsigned int irq) | ||
58 | { | ||
59 | disable_hd64465_irq(irq); | ||
60 | } | ||
61 | |||
62 | |||
63 | static 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 | |||
70 | static unsigned int startup_hd64465_irq(unsigned int irq) | ||
71 | { | ||
72 | enable_hd64465_irq(irq); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | |||
77 | static void shutdown_hd64465_irq(unsigned int irq) | ||
78 | { | ||
79 | disable_hd64465_irq(irq); | ||
80 | } | ||
81 | |||
82 | |||
83 | static 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 | |||
94 | static 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 | */ | ||
113 | static struct | ||
114 | { | ||
115 | int (*func)(int, void *); | ||
116 | void *dev; | ||
117 | } hd64465_demux[HD64465_IRQ_NUM]; | ||
118 | |||
119 | void 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 | } | ||
125 | EXPORT_SYMBOL(hd64465_register_irq_demux); | ||
126 | |||
127 | void hd64465_unregister_irq_demux(int irq) | ||
128 | { | ||
129 | hd64465_demux[irq - HD64465_IRQ_BASE].func = 0; | ||
130 | } | ||
131 | EXPORT_SYMBOL(hd64465_unregister_irq_demux); | ||
132 | |||
133 | |||
134 | |||
135 | int 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 | |||
157 | static struct irqaction irq0 = { hd64465_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "HD64465", NULL, NULL}; | ||
158 | |||
159 | |||
160 | static 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 | |||
202 | module_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 | |||
5 | obj-y := irq.o setup.o | ||
6 | |||
7 | obj-$(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 | |||
20 | struct voya_alloc_entry { | ||
21 | struct list_head list; | ||
22 | unsigned long ofs; | ||
23 | unsigned long len; | ||
24 | }; | ||
25 | |||
26 | static DEFINE_SPINLOCK(voya_list_lock); | ||
27 | static 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 | |||
33 | void *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) { | ||
82 | out: | ||
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 | |||
97 | int 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 | |||
124 | EXPORT_SYMBOL(voyagergx_consistent_alloc); | ||
125 | EXPORT_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 | |||
39 | static 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 | |||
53 | static 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 | |||
67 | static void mask_and_ack_voyagergx(unsigned int irq) | ||
68 | { | ||
69 | disable_voyagergx_irq(irq); | ||
70 | } | ||
71 | |||
72 | static 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 | |||
78 | static unsigned int startup_voyagergx_irq(unsigned int irq) | ||
79 | { | ||
80 | enable_voyagergx_irq(irq); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static void shutdown_voyagergx_irq(unsigned int irq) | ||
85 | { | ||
86 | disable_voyagergx_irq(irq); | ||
87 | } | ||
88 | |||
89 | static 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 | |||
99 | static 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 | |||
110 | static struct { | ||
111 | int (*func)(int, void *); | ||
112 | void *dev; | ||
113 | } voyagergx_demux[VOYAGER_IRQ_NUM]; | ||
114 | |||
115 | void 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 | |||
122 | void voyagergx_unregister_irq_demux(int irq) | ||
123 | { | ||
124 | voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0; | ||
125 | } | ||
126 | |||
127 | int 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 | |||
166 | static struct irqaction irq0 = { voyagergx_interrupt, SA_INTERRUPT, 0, "VOYAGERGX", NULL, NULL}; | ||
167 | |||
168 | void __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 | |||
18 | static 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 | |||
37 | module_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | CONFIG_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 | ||
29 | CONFIG_LOG_BUF_SHIFT=14 | ||
30 | # CONFIG_HOTPLUG is not set | ||
31 | # CONFIG_IKCONFIG is not set | ||
32 | # CONFIG_EMBEDDED is not set | ||
33 | CONFIG_KALLSYMS=y | ||
34 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
35 | CONFIG_FUTEX=y | ||
36 | CONFIG_EPOLL=y | ||
37 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
38 | CONFIG_SHMEM=y | ||
39 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
40 | CONFIG_CC_ALIGN_LABELS=0 | ||
41 | CONFIG_CC_ALIGN_LOOPS=0 | ||
42 | CONFIG_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 | ||
71 | CONFIG_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 | ||
82 | CONFIG_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 | ||
89 | CONFIG_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 | ||
96 | CONFIG_MMU=y | ||
97 | # CONFIG_CMDLINE_BOOL is not set | ||
98 | CONFIG_MEMORY_START=0x08000000 | ||
99 | CONFIG_MEMORY_SIZE=0x00400000 | ||
100 | CONFIG_MEMORY_SET=y | ||
101 | # CONFIG_MEMORY_OVERRIDE is not set | ||
102 | CONFIG_CF_ENABLER=y | ||
103 | # CONFIG_CF_AREA5 is not set | ||
104 | CONFIG_CF_AREA6=y | ||
105 | CONFIG_CF_BASE_ADDR=0xb8000000 | ||
106 | CONFIG_SH_RTC=y | ||
107 | CONFIG_SH_FPU=y | ||
108 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
109 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
110 | CONFIG_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 | ||
117 | CONFIG_SH_PCLK_CALC=y | ||
118 | CONFIG_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 | # | ||
156 | CONFIG_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 | # | ||
172 | CONFIG_STANDALONE=y | ||
173 | CONFIG_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 | ||
196 | CONFIG_BLK_DEV_RAM=y | ||
197 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
198 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
199 | CONFIG_BLK_DEV_INITRD=y | ||
200 | CONFIG_INITRAMFS_SOURCE="" | ||
201 | # CONFIG_LBD is not set | ||
202 | # CONFIG_CDROM_PKTCDVD is not set | ||
203 | |||
204 | # | ||
205 | # IO Schedulers | ||
206 | # | ||
207 | CONFIG_IOSCHED_NOOP=y | ||
208 | CONFIG_IOSCHED_AS=y | ||
209 | CONFIG_IOSCHED_DEADLINE=y | ||
210 | CONFIG_IOSCHED_CFQ=y | ||
211 | |||
212 | # | ||
213 | # ATA/ATAPI/MFM/RLL support | ||
214 | # | ||
215 | CONFIG_IDE=y | ||
216 | CONFIG_IDE_MAX_HWIFS=4 | ||
217 | CONFIG_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 | ||
223 | CONFIG_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 | # | ||
233 | CONFIG_IDE_GENERIC=y | ||
234 | CONFIG_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 | # | ||
281 | CONFIG_INPUT=y | ||
282 | |||
283 | # | ||
284 | # Userland interfaces | ||
285 | # | ||
286 | CONFIG_INPUT_MOUSEDEV=y | ||
287 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
288 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
289 | CONFIG_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 | ||
299 | CONFIG_SOUND_GAMEPORT=y | ||
300 | CONFIG_SERIO=y | ||
301 | CONFIG_SERIO_I8042=y | ||
302 | CONFIG_SERIO_SERPORT=y | ||
303 | # CONFIG_SERIO_CT82C710 is not set | ||
304 | CONFIG_SERIO_LIBPS2=y | ||
305 | # CONFIG_SERIO_RAW is not set | ||
306 | |||
307 | # | ||
308 | # Input Device Drivers | ||
309 | # | ||
310 | CONFIG_INPUT_KEYBOARD=y | ||
311 | CONFIG_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 | ||
316 | CONFIG_INPUT_MOUSE=y | ||
317 | CONFIG_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 | # | ||
327 | CONFIG_VT=y | ||
328 | CONFIG_VT_CONSOLE=y | ||
329 | CONFIG_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 | ||
341 | CONFIG_UNIX98_PTYS=y | ||
342 | CONFIG_LEGACY_PTYS=y | ||
343 | CONFIG_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 | # | ||
396 | CONFIG_VGA_CONSOLE=y | ||
397 | CONFIG_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 | # | ||
432 | CONFIG_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 | ||
446 | CONFIG_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 | # | ||
466 | CONFIG_PROC_FS=y | ||
467 | # CONFIG_PROC_KCORE is not set | ||
468 | CONFIG_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 | ||
474 | CONFIG_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 | ||
497 | CONFIG_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 | ||
514 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | CONFIG_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 | ||
29 | CONFIG_LOG_BUF_SHIFT=14 | ||
30 | # CONFIG_HOTPLUG is not set | ||
31 | # CONFIG_IKCONFIG is not set | ||
32 | # CONFIG_EMBEDDED is not set | ||
33 | CONFIG_KALLSYMS=y | ||
34 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
35 | CONFIG_FUTEX=y | ||
36 | CONFIG_EPOLL=y | ||
37 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
38 | CONFIG_SHMEM=y | ||
39 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
40 | CONFIG_CC_ALIGN_LABELS=0 | ||
41 | CONFIG_CC_ALIGN_LOOPS=0 | ||
42 | CONFIG_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=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 | ||
81 | CONFIG_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 | ||
87 | CONFIG_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 | ||
96 | CONFIG_MMU=y | ||
97 | # CONFIG_CMDLINE_BOOL is not set | ||
98 | CONFIG_MEMORY_START=0x0c000000 | ||
99 | CONFIG_MEMORY_SIZE=0x00400000 | ||
100 | # CONFIG_MEMORY_OVERRIDE is not set | ||
101 | CONFIG_SH_RTC=y | ||
102 | CONFIG_SH_DSP=y | ||
103 | CONFIG_SH_ADC=y | ||
104 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
105 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
106 | CONFIG_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 | ||
112 | CONFIG_SH_PCLK_CALC=y | ||
113 | CONFIG_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 | # | ||
151 | CONFIG_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 | # | ||
167 | CONFIG_STANDALONE=y | ||
168 | CONFIG_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 | ||
191 | CONFIG_BLK_DEV_RAM=y | ||
192 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
193 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
194 | CONFIG_BLK_DEV_INITRD=y | ||
195 | CONFIG_INITRAMFS_SOURCE="" | ||
196 | # CONFIG_LBD is not set | ||
197 | # CONFIG_CDROM_PKTCDVD is not set | ||
198 | |||
199 | # | ||
200 | # IO Schedulers | ||
201 | # | ||
202 | CONFIG_IOSCHED_NOOP=y | ||
203 | CONFIG_IOSCHED_AS=y | ||
204 | CONFIG_IOSCHED_DEADLINE=y | ||
205 | CONFIG_IOSCHED_CFQ=y | ||
206 | |||
207 | # | ||
208 | # ATA/ATAPI/MFM/RLL support | ||
209 | # | ||
210 | CONFIG_IDE=y | ||
211 | CONFIG_IDE_MAX_HWIFS=4 | ||
212 | CONFIG_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 | ||
218 | CONFIG_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 | # | ||
228 | CONFIG_IDE_GENERIC=y | ||
229 | CONFIG_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 | # | ||
276 | CONFIG_INPUT=y | ||
277 | |||
278 | # | ||
279 | # Userland interfaces | ||
280 | # | ||
281 | CONFIG_INPUT_MOUSEDEV=y | ||
282 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
283 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
284 | CONFIG_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 | ||
294 | CONFIG_SOUND_GAMEPORT=y | ||
295 | CONFIG_SERIO=y | ||
296 | CONFIG_SERIO_I8042=y | ||
297 | CONFIG_SERIO_SERPORT=y | ||
298 | # CONFIG_SERIO_CT82C710 is not set | ||
299 | CONFIG_SERIO_LIBPS2=y | ||
300 | # CONFIG_SERIO_RAW is not set | ||
301 | |||
302 | # | ||
303 | # Input Device Drivers | ||
304 | # | ||
305 | CONFIG_INPUT_KEYBOARD=y | ||
306 | CONFIG_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 | ||
311 | CONFIG_INPUT_MOUSE=y | ||
312 | CONFIG_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 | # | ||
322 | CONFIG_VT=y | ||
323 | CONFIG_VT_CONSOLE=y | ||
324 | CONFIG_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 | ||
336 | CONFIG_UNIX98_PTYS=y | ||
337 | CONFIG_LEGACY_PTYS=y | ||
338 | CONFIG_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 | # | ||
391 | CONFIG_VGA_CONSOLE=y | ||
392 | CONFIG_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 | # | ||
427 | CONFIG_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 | ||
441 | CONFIG_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 | # | ||
461 | CONFIG_PROC_FS=y | ||
462 | # CONFIG_PROC_KCORE is not set | ||
463 | CONFIG_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 | ||
469 | CONFIG_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 | ||
492 | CONFIG_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 | ||
509 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | CONFIG_LOCK_KERNEL=y | ||
20 | |||
21 | # | ||
22 | # General setup | ||
23 | # | ||
24 | CONFIG_LOCALVERSION="" | ||
25 | CONFIG_SWAP=y | ||
26 | CONFIG_SYSVIPC=y | ||
27 | # CONFIG_POSIX_MQUEUE is not set | ||
28 | CONFIG_BSD_PROCESS_ACCT=y | ||
29 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
30 | CONFIG_SYSCTL=y | ||
31 | # CONFIG_AUDIT is not set | ||
32 | CONFIG_LOG_BUF_SHIFT=14 | ||
33 | CONFIG_HOTPLUG=y | ||
34 | CONFIG_KOBJECT_UEVENT=y | ||
35 | # CONFIG_IKCONFIG is not set | ||
36 | CONFIG_EMBEDDED=y | ||
37 | CONFIG_KALLSYMS=y | ||
38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
39 | CONFIG_FUTEX=y | ||
40 | CONFIG_EPOLL=y | ||
41 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
42 | CONFIG_SHMEM=y | ||
43 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
44 | CONFIG_CC_ALIGN_LABELS=0 | ||
45 | CONFIG_CC_ALIGN_LOOPS=0 | ||
46 | CONFIG_CC_ALIGN_JUMPS=0 | ||
47 | # CONFIG_TINY_SHMEM is not set | ||
48 | |||
49 | # | ||
50 | # Loadable module support | ||
51 | # | ||
52 | CONFIG_MODULES=y | ||
53 | CONFIG_MODULE_UNLOAD=y | ||
54 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
55 | CONFIG_OBSOLETE_MODPARM=y | ||
56 | # CONFIG_MODVERSIONS is not set | ||
57 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
58 | CONFIG_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 | ||
77 | CONFIG_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 | ||
92 | CONFIG_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 | ||
99 | CONFIG_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 | ||
106 | CONFIG_MMU=y | ||
107 | CONFIG_HUGETLB_PAGE_SIZE_64K=y | ||
108 | # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set | ||
109 | # CONFIG_CMDLINE_BOOL is not set | ||
110 | CONFIG_MEMORY_START=0x0c000000 | ||
111 | CONFIG_MEMORY_SIZE=0x01000000 | ||
112 | CONFIG_MEMORY_SET=y | ||
113 | # CONFIG_MEMORY_OVERRIDE is not set | ||
114 | CONFIG_SH_FPU=y | ||
115 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
116 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
117 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
118 | CONFIG_PREEMPT=y | ||
119 | # CONFIG_UBC_WAKEUP is not set | ||
120 | # CONFIG_SH_WRITETHROUGH is not set | ||
121 | CONFIG_SH_OCRAM=y | ||
122 | CONFIG_SH_STORE_QUEUES=y | ||
123 | # CONFIG_SMP is not set | ||
124 | CONFIG_SH_PCLK_CALC=y | ||
125 | CONFIG_SH_PCLK_FREQ=49876504 | ||
126 | |||
127 | # | ||
128 | # CPU Frequency scaling | ||
129 | # | ||
130 | CONFIG_CPU_FREQ=y | ||
131 | # CONFIG_CPU_FREQ_DEBUG is not set | ||
132 | CONFIG_CPU_FREQ_STAT=y | ||
133 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set | ||
134 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y | ||
135 | # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set | ||
136 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | ||
137 | CONFIG_CPU_FREQ_GOV_POWERSAVE=y | ||
138 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | ||
139 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set | ||
140 | CONFIG_CPU_FREQ_TABLE=y | ||
141 | CONFIG_SH_CPU_FREQ=y | ||
142 | |||
143 | # | ||
144 | # DMA support | ||
145 | # | ||
146 | CONFIG_SH_DMA=y | ||
147 | CONFIG_NR_ONCHIP_DMA_CHANNELS=4 | ||
148 | CONFIG_NR_DMA_CHANNELS_BOOL=y | ||
149 | CONFIG_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 | # | ||
159 | CONFIG_MAPLE=y | ||
160 | CONFIG_PCI=y | ||
161 | # CONFIG_SH_PCIDMA_NONCOHERENT is not set | ||
162 | CONFIG_PCI_AUTO=y | ||
163 | CONFIG_PCI_LEGACY_PROC=y | ||
164 | CONFIG_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 | # | ||
183 | CONFIG_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 | ||
200 | CONFIG_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 | ||
229 | CONFIG_BLK_DEV_RAM=y | ||
230 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
231 | CONFIG_BLK_DEV_RAM_SIZE=1024 | ||
232 | CONFIG_BLK_DEV_INITRD=y | ||
233 | CONFIG_INITRAMFS_SOURCE="" | ||
234 | # CONFIG_LBD is not set | ||
235 | # CONFIG_CDROM_PKTCDVD is not set | ||
236 | |||
237 | # | ||
238 | # IO Schedulers | ||
239 | # | ||
240 | CONFIG_IOSCHED_NOOP=y | ||
241 | CONFIG_IOSCHED_AS=y | ||
242 | CONFIG_IOSCHED_DEADLINE=y | ||
243 | CONFIG_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 | # | ||
278 | CONFIG_NET=y | ||
279 | |||
280 | # | ||
281 | # Networking options | ||
282 | # | ||
283 | CONFIG_PACKET=y | ||
284 | # CONFIG_PACKET_MMAP is not set | ||
285 | # CONFIG_NETLINK_DEV is not set | ||
286 | CONFIG_UNIX=y | ||
287 | # CONFIG_NET_KEY is not set | ||
288 | CONFIG_INET=y | ||
289 | # CONFIG_IP_MULTICAST is not set | ||
290 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
291 | CONFIG_IP_PNP=y | ||
292 | CONFIG_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 | ||
303 | CONFIG_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 | ||
340 | CONFIG_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 | # | ||
354 | CONFIG_NET_ETHERNET=y | ||
355 | CONFIG_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 | ||
367 | CONFIG_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 | ||
380 | CONFIG_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 | # | ||
445 | CONFIG_INPUT=y | ||
446 | |||
447 | # | ||
448 | # Userland interfaces | ||
449 | # | ||
450 | CONFIG_INPUT_MOUSEDEV=y | ||
451 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
452 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
453 | CONFIG_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 | ||
463 | CONFIG_SOUND_GAMEPORT=y | ||
464 | CONFIG_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 | ||
469 | CONFIG_SERIO_LIBPS2=y | ||
470 | # CONFIG_SERIO_RAW is not set | ||
471 | |||
472 | # | ||
473 | # Input Device Drivers | ||
474 | # | ||
475 | CONFIG_INPUT_KEYBOARD=y | ||
476 | CONFIG_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 | ||
482 | CONFIG_INPUT_MOUSE=y | ||
483 | CONFIG_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 | # | ||
494 | CONFIG_VT=y | ||
495 | CONFIG_VT_CONSOLE=y | ||
496 | CONFIG_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 | # | ||
507 | CONFIG_SERIAL_SH_SCI=y | ||
508 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
509 | CONFIG_SERIAL_CORE=y | ||
510 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
511 | CONFIG_UNIX98_PTYS=y | ||
512 | CONFIG_LEGACY_PTYS=y | ||
513 | CONFIG_LEGACY_PTY_COUNT=256 | ||
514 | |||
515 | # | ||
516 | # IPMI | ||
517 | # | ||
518 | # CONFIG_IPMI_HANDLER is not set | ||
519 | |||
520 | # | ||
521 | # Watchdog Cards | ||
522 | # | ||
523 | CONFIG_WATCHDOG=y | ||
524 | # CONFIG_WATCHDOG_NOWAYOUT is not set | ||
525 | |||
526 | # | ||
527 | # Watchdog Device Drivers | ||
528 | # | ||
529 | # CONFIG_SOFT_WATCHDOG is not set | ||
530 | CONFIG_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 | # | ||
576 | CONFIG_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 | ||
584 | CONFIG_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 | ||
605 | CONFIG_DUMMY_CONSOLE=y | ||
606 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
607 | CONFIG_FONTS=y | ||
608 | CONFIG_FONT_8x8=y | ||
609 | CONFIG_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 | # | ||
620 | CONFIG_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 | ||
626 | CONFIG_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 | ||
638 | CONFIG_USB_ARCH_HAS_HCD=y | ||
639 | CONFIG_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 | ||
674 | CONFIG_ROMFS_FS=y | ||
675 | # CONFIG_QUOTA is not set | ||
676 | CONFIG_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 | # | ||
696 | CONFIG_PROC_FS=y | ||
697 | CONFIG_PROC_KCORE=y | ||
698 | CONFIG_SYSFS=y | ||
699 | CONFIG_DEVFS_FS=y | ||
700 | CONFIG_DEVFS_MOUNT=y | ||
701 | # CONFIG_DEVFS_DEBUG is not set | ||
702 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
703 | CONFIG_TMPFS=y | ||
704 | # CONFIG_TMPFS_XATTR is not set | ||
705 | CONFIG_HUGETLBFS=y | ||
706 | CONFIG_HUGETLB_PAGE=y | ||
707 | CONFIG_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 | ||
719 | CONFIG_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 | # | ||
729 | CONFIG_NFS_FS=y | ||
730 | CONFIG_NFS_V3=y | ||
731 | # CONFIG_NFS_V4 is not set | ||
732 | # CONFIG_NFS_DIRECTIO is not set | ||
733 | # CONFIG_NFSD is not set | ||
734 | CONFIG_ROOT_NFS=y | ||
735 | CONFIG_LOCKD=y | ||
736 | CONFIG_LOCKD_V4=y | ||
737 | CONFIG_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 | ||
750 | CONFIG_MSDOS_PARTITION=y | ||
751 | |||
752 | # | ||
753 | # Native Language Support | ||
754 | # | ||
755 | # CONFIG_NLS is not set | ||
756 | |||
757 | # | ||
758 | # Profiling support | ||
759 | # | ||
760 | CONFIG_PROFILING=y | ||
761 | CONFIG_OPROFILE=y | ||
762 | |||
763 | # | ||
764 | # Kernel hacking | ||
765 | # | ||
766 | # CONFIG_DEBUG_KERNEL is not set | ||
767 | CONFIG_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 | ||
792 | CONFIG_CRC32=y | ||
793 | # CONFIG_LIBCRC32C is not set | ||
794 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | # CONFIG_CLEAN_COMPILE is not set | ||
18 | CONFIG_BROKEN=y | ||
19 | CONFIG_BROKEN_ON_SMP=y | ||
20 | |||
21 | # | ||
22 | # General setup | ||
23 | # | ||
24 | CONFIG_LOCALVERSION="" | ||
25 | CONFIG_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 | ||
30 | CONFIG_LOG_BUF_SHIFT=14 | ||
31 | # CONFIG_HOTPLUG is not set | ||
32 | # CONFIG_IKCONFIG is not set | ||
33 | # CONFIG_EMBEDDED is not set | ||
34 | CONFIG_KALLSYMS=y | ||
35 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
36 | CONFIG_FUTEX=y | ||
37 | CONFIG_EPOLL=y | ||
38 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
39 | CONFIG_SHMEM=y | ||
40 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
41 | CONFIG_CC_ALIGN_LABELS=0 | ||
42 | CONFIG_CC_ALIGN_LOOPS=0 | ||
43 | CONFIG_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 | ||
62 | CONFIG_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 | ||
82 | CONFIG_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 | ||
89 | CONFIG_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 | ||
97 | CONFIG_MMU=y | ||
98 | # CONFIG_CMDLINE_BOOL is not set | ||
99 | CONFIG_MEMORY_START=0x0c000000 | ||
100 | CONFIG_MEMORY_SIZE=0x00400000 | ||
101 | CONFIG_MEMORY_SET=y | ||
102 | # CONFIG_MEMORY_OVERRIDE is not set | ||
103 | CONFIG_SH_RTC=y | ||
104 | # CONFIG_SH_DSP is not set | ||
105 | CONFIG_SH_ADC=y | ||
106 | CONFIG_SH_HP600=y | ||
107 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
108 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
109 | CONFIG_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 | ||
115 | CONFIG_SH_PCLK_CALC=y | ||
116 | CONFIG_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 | # | ||
131 | CONFIG_HD6446X_SERIES=y | ||
132 | CONFIG_HD64461=y | ||
133 | # CONFIG_HD64465 is not set | ||
134 | CONFIG_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 | # | ||
158 | CONFIG_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 | ||
175 | CONFIG_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 | ||
198 | CONFIG_BLK_DEV_RAM=y | ||
199 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
200 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
201 | CONFIG_BLK_DEV_INITRD=y | ||
202 | CONFIG_INITRAMFS_SOURCE="" | ||
203 | # CONFIG_LBD is not set | ||
204 | # CONFIG_CDROM_PKTCDVD is not set | ||
205 | |||
206 | # | ||
207 | # IO Schedulers | ||
208 | # | ||
209 | CONFIG_IOSCHED_NOOP=y | ||
210 | CONFIG_IOSCHED_AS=y | ||
211 | CONFIG_IOSCHED_DEADLINE=y | ||
212 | CONFIG_IOSCHED_CFQ=y | ||
213 | |||
214 | # | ||
215 | # ATA/ATAPI/MFM/RLL support | ||
216 | # | ||
217 | CONFIG_IDE=y | ||
218 | CONFIG_IDE_MAX_HWIFS=4 | ||
219 | CONFIG_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 | ||
225 | CONFIG_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 | # | ||
235 | CONFIG_IDE_GENERIC=y | ||
236 | CONFIG_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 | # | ||
284 | CONFIG_INPUT=y | ||
285 | |||
286 | # | ||
287 | # Userland interfaces | ||
288 | # | ||
289 | CONFIG_INPUT_MOUSEDEV=y | ||
290 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
291 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
292 | CONFIG_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 | ||
302 | CONFIG_SOUND_GAMEPORT=y | ||
303 | CONFIG_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 | # | ||
321 | CONFIG_VT=y | ||
322 | CONFIG_VT_CONSOLE=y | ||
323 | CONFIG_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 | ||
335 | CONFIG_UNIX98_PTYS=y | ||
336 | CONFIG_LEGACY_PTYS=y | ||
337 | CONFIG_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 | # | ||
385 | CONFIG_FB=y | ||
386 | # CONFIG_FB_MODE_HELPERS is not set | ||
387 | # CONFIG_FB_TILEBLITTING is not set | ||
388 | # CONFIG_FB_EPSON1355 is not set | ||
389 | CONFIG_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 | ||
396 | CONFIG_DUMMY_CONSOLE=y | ||
397 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
398 | CONFIG_FONTS=y | ||
399 | # CONFIG_FONT_8x8 is not set | ||
400 | # CONFIG_FONT_8x16 is not set | ||
401 | # CONFIG_FONT_6x11 is not set | ||
402 | CONFIG_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 | # | ||
447 | CONFIG_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 | ||
461 | CONFIG_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 | # | ||
481 | CONFIG_PROC_FS=y | ||
482 | CONFIG_PROC_KCORE=y | ||
483 | CONFIG_SYSFS=y | ||
484 | CONFIG_DEVFS_FS=y | ||
485 | CONFIG_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 | ||
491 | CONFIG_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 | ||
514 | CONFIG_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 | ||
553 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | CONFIG_LOCK_KERNEL=y | ||
20 | |||
21 | # | ||
22 | # General setup | ||
23 | # | ||
24 | CONFIG_LOCALVERSION="" | ||
25 | CONFIG_SWAP=y | ||
26 | # CONFIG_SYSVIPC is not set | ||
27 | # CONFIG_POSIX_MQUEUE is not set | ||
28 | CONFIG_BSD_PROCESS_ACCT=y | ||
29 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
30 | CONFIG_SYSCTL=y | ||
31 | # CONFIG_AUDIT is not set | ||
32 | CONFIG_LOG_BUF_SHIFT=14 | ||
33 | CONFIG_HOTPLUG=y | ||
34 | CONFIG_KOBJECT_UEVENT=y | ||
35 | # CONFIG_IKCONFIG is not set | ||
36 | CONFIG_EMBEDDED=y | ||
37 | CONFIG_KALLSYMS=y | ||
38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
39 | CONFIG_FUTEX=y | ||
40 | CONFIG_EPOLL=y | ||
41 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
42 | CONFIG_SHMEM=y | ||
43 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
44 | CONFIG_CC_ALIGN_LABELS=0 | ||
45 | CONFIG_CC_ALIGN_LOOPS=0 | ||
46 | CONFIG_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 | ||
82 | CONFIG_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 | ||
86 | CONFIG_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 | ||
99 | CONFIG_CPU_SUBTYPE_SH4_202=y | ||
100 | CONFIG_MMU=y | ||
101 | CONFIG_CMDLINE_BOOL=y | ||
102 | CONFIG_CMDLINE="console=ttySC0,115200" | ||
103 | CONFIG_MEMORY_START=0x08000000 | ||
104 | CONFIG_MEMORY_SIZE=0x04000000 | ||
105 | CONFIG_MEMORY_SET=y | ||
106 | # CONFIG_MEMORY_OVERRIDE is not set | ||
107 | CONFIG_SH_RTC=y | ||
108 | CONFIG_SH_FPU=y | ||
109 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
110 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
111 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
112 | CONFIG_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 | ||
118 | CONFIG_SH_PCLK_CALC=y | ||
119 | CONFIG_SH_PCLK_FREQ=65986048 | ||
120 | |||
121 | # | ||
122 | # CPU Frequency scaling | ||
123 | # | ||
124 | # CONFIG_CPU_FREQ is not set | ||
125 | |||
126 | # | ||
127 | # DMA support | ||
128 | # | ||
129 | CONFIG_SH_DMA=y | ||
130 | CONFIG_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 | ||
137 | CONFIG_HEARTBEAT=y | ||
138 | |||
139 | # | ||
140 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | ||
141 | # | ||
142 | CONFIG_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 | # | ||
153 | CONFIG_PCMCIA_PROBE=y | ||
154 | |||
155 | # | ||
156 | # PCI Hotplug Support | ||
157 | # | ||
158 | |||
159 | # | ||
160 | # Executable file formats | ||
161 | # | ||
162 | CONFIG_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 | # | ||
178 | CONFIG_STANDALONE=y | ||
179 | CONFIG_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 | ||
205 | CONFIG_BLK_DEV_RAM=y | ||
206 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
207 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
208 | CONFIG_BLK_DEV_INITRD=y | ||
209 | CONFIG_INITRAMFS_SOURCE="" | ||
210 | # CONFIG_LBD is not set | ||
211 | # CONFIG_CDROM_PKTCDVD is not set | ||
212 | |||
213 | # | ||
214 | # IO Schedulers | ||
215 | # | ||
216 | CONFIG_IOSCHED_NOOP=y | ||
217 | CONFIG_IOSCHED_AS=y | ||
218 | CONFIG_IOSCHED_DEADLINE=y | ||
219 | CONFIG_IOSCHED_CFQ=y | ||
220 | # CONFIG_ATA_OVER_ETH is not set | ||
221 | |||
222 | # | ||
223 | # ATA/ATAPI/MFM/RLL support | ||
224 | # | ||
225 | CONFIG_IDE=y | ||
226 | CONFIG_IDE_MAX_HWIFS=1 | ||
227 | CONFIG_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 | ||
233 | CONFIG_BLK_DEV_IDEDISK=y | ||
234 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
235 | CONFIG_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 | # | ||
243 | CONFIG_IDE_GENERIC=y | ||
244 | CONFIG_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 | # | ||
281 | CONFIG_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 | ||
290 | CONFIG_INET=y | ||
291 | # CONFIG_IP_MULTICAST is not set | ||
292 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
293 | CONFIG_IP_PNP=y | ||
294 | CONFIG_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 | ||
305 | CONFIG_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 | ||
342 | CONFIG_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 | # | ||
356 | CONFIG_NET_ETHERNET=y | ||
357 | CONFIG_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 | ||
362 | CONFIG_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 | ||
421 | CONFIG_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 | # | ||
443 | CONFIG_SERIAL_SH_SCI=y | ||
444 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
445 | CONFIG_SERIAL_CORE=y | ||
446 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
447 | CONFIG_UNIX98_PTYS=y | ||
448 | CONFIG_LEGACY_PTYS=y | ||
449 | CONFIG_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 | ||
460 | CONFIG_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 | # | ||
532 | CONFIG_EXT2_FS=y | ||
533 | # CONFIG_EXT2_FS_XATTR is not set | ||
534 | CONFIG_EXT3_FS=y | ||
535 | CONFIG_EXT3_FS_XATTR=y | ||
536 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
537 | # CONFIG_EXT3_FS_SECURITY is not set | ||
538 | CONFIG_JBD=y | ||
539 | # CONFIG_JBD_DEBUG is not set | ||
540 | CONFIG_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 | ||
551 | CONFIG_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 | # | ||
564 | CONFIG_FAT_FS=y | ||
565 | # CONFIG_MSDOS_FS is not set | ||
566 | CONFIG_VFAT_FS=y | ||
567 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
568 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
569 | # CONFIG_NTFS_FS is not set | ||
570 | |||
571 | # | ||
572 | # Pseudo filesystems | ||
573 | # | ||
574 | CONFIG_PROC_FS=y | ||
575 | CONFIG_PROC_KCORE=y | ||
576 | CONFIG_SYSFS=y | ||
577 | CONFIG_DEVFS_FS=y | ||
578 | CONFIG_DEVFS_MOUNT=y | ||
579 | # CONFIG_DEVFS_DEBUG is not set | ||
580 | CONFIG_DEVPTS_FS_XATTR=y | ||
581 | # CONFIG_DEVPTS_FS_SECURITY is not set | ||
582 | CONFIG_TMPFS=y | ||
583 | # CONFIG_TMPFS_XATTR is not set | ||
584 | # CONFIG_HUGETLBFS is not set | ||
585 | # CONFIG_HUGETLB_PAGE is not set | ||
586 | CONFIG_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 | # | ||
608 | CONFIG_NFS_FS=y | ||
609 | CONFIG_NFS_V3=y | ||
610 | CONFIG_NFS_V4=y | ||
611 | # CONFIG_NFS_DIRECTIO is not set | ||
612 | # CONFIG_NFSD is not set | ||
613 | CONFIG_ROOT_NFS=y | ||
614 | CONFIG_LOCKD=y | ||
615 | CONFIG_LOCKD_V4=y | ||
616 | CONFIG_SUNRPC=y | ||
617 | CONFIG_SUNRPC_GSS=y | ||
618 | CONFIG_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 | ||
630 | CONFIG_MSDOS_PARTITION=y | ||
631 | |||
632 | # | ||
633 | # Native Language Support | ||
634 | # | ||
635 | CONFIG_NLS=y | ||
636 | CONFIG_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 | ||
685 | CONFIG_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 | # | ||
700 | CONFIG_CRYPTO=y | ||
701 | # CONFIG_CRYPTO_HMAC is not set | ||
702 | # CONFIG_CRYPTO_NULL is not set | ||
703 | # CONFIG_CRYPTO_MD4 is not set | ||
704 | CONFIG_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 | ||
709 | CONFIG_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 | ||
733 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | CONFIG_SWAP=y | ||
25 | CONFIG_SYSVIPC=y | ||
26 | # CONFIG_POSIX_MQUEUE is not set | ||
27 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
28 | CONFIG_SYSCTL=y | ||
29 | # CONFIG_AUDIT is not set | ||
30 | CONFIG_LOG_BUF_SHIFT=14 | ||
31 | CONFIG_HOTPLUG=y | ||
32 | CONFIG_KOBJECT_UEVENT=y | ||
33 | # CONFIG_IKCONFIG is not set | ||
34 | CONFIG_EMBEDDED=y | ||
35 | CONFIG_KALLSYMS=y | ||
36 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
37 | CONFIG_FUTEX=y | ||
38 | CONFIG_EPOLL=y | ||
39 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
40 | CONFIG_SHMEM=y | ||
41 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
42 | CONFIG_CC_ALIGN_LABELS=0 | ||
43 | CONFIG_CC_ALIGN_LOOPS=0 | ||
44 | CONFIG_CC_ALIGN_JUMPS=0 | ||
45 | # CONFIG_TINY_SHMEM is not set | ||
46 | |||
47 | # | ||
48 | # Loadable module support | ||
49 | # | ||
50 | CONFIG_MODULES=y | ||
51 | # CONFIG_MODULE_UNLOAD is not set | ||
52 | CONFIG_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 | ||
83 | CONFIG_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 | ||
89 | CONFIG_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 | ||
97 | CONFIG_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 | ||
103 | CONFIG_MMU=y | ||
104 | CONFIG_CMDLINE_BOOL=y | ||
105 | CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1" | ||
106 | CONFIG_MEMORY_START=0x0c000000 | ||
107 | CONFIG_MEMORY_SIZE=0x04000000 | ||
108 | CONFIG_MEMORY_SET=y | ||
109 | # CONFIG_MEMORY_OVERRIDE is not set | ||
110 | CONFIG_SH_RTC=y | ||
111 | CONFIG_SH_FPU=y | ||
112 | CONFIG_ZERO_PAGE_OFFSET=0x00010000 | ||
113 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
114 | CONFIG_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 | ||
121 | CONFIG_RTS7751R2D_REV11=y | ||
122 | CONFIG_SH_PCLK_CALC=y | ||
123 | CONFIG_SH_PCLK_FREQ=60000000 | ||
124 | |||
125 | # | ||
126 | # CPU Frequency scaling | ||
127 | # | ||
128 | # CONFIG_CPU_FREQ is not set | ||
129 | |||
130 | # | ||
131 | # DMA support | ||
132 | # | ||
133 | CONFIG_SH_DMA=y | ||
134 | CONFIG_NR_ONCHIP_DMA_CHANNELS=8 | ||
135 | # CONFIG_NR_DMA_CHANNELS_BOOL is not set | ||
136 | |||
137 | # | ||
138 | # Companion Chips | ||
139 | # | ||
140 | CONFIG_VOYAGERGX=y | ||
141 | # CONFIG_HD6446X_SERIES is not set | ||
142 | CONFIG_HEARTBEAT=y | ||
143 | CONFIG_RTC_9701JE=y | ||
144 | |||
145 | # | ||
146 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | ||
147 | # | ||
148 | CONFIG_PCI=y | ||
149 | CONFIG_SH_PCIDMA_NONCOHERENT=y | ||
150 | CONFIG_PCI_AUTO=y | ||
151 | CONFIG_PCI_AUTO_UPDATE_RESOURCES=y | ||
152 | # CONFIG_PCI_LEGACY_PROC is not set | ||
153 | CONFIG_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 | # | ||
167 | CONFIG_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 | # | ||
175 | CONFIG_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 | # | ||
186 | CONFIG_STANDALONE=y | ||
187 | CONFIG_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 | ||
216 | CONFIG_BLK_DEV_RAM=y | ||
217 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
218 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
219 | # CONFIG_BLK_DEV_INITRD is not set | ||
220 | CONFIG_INITRAMFS_SOURCE="" | ||
221 | # CONFIG_LBD is not set | ||
222 | # CONFIG_CDROM_PKTCDVD is not set | ||
223 | |||
224 | # | ||
225 | # IO Schedulers | ||
226 | # | ||
227 | CONFIG_IOSCHED_NOOP=y | ||
228 | CONFIG_IOSCHED_AS=y | ||
229 | CONFIG_IOSCHED_DEADLINE=y | ||
230 | CONFIG_IOSCHED_CFQ=y | ||
231 | # CONFIG_ATA_OVER_ETH is not set | ||
232 | |||
233 | # | ||
234 | # ATA/ATAPI/MFM/RLL support | ||
235 | # | ||
236 | CONFIG_IDE=y | ||
237 | CONFIG_IDE_MAX_HWIFS=4 | ||
238 | CONFIG_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 | ||
244 | CONFIG_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 | # | ||
254 | CONFIG_IDE_GENERIC=y | ||
255 | # CONFIG_BLK_DEV_IDEPCI is not set | ||
256 | CONFIG_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 | # | ||
289 | CONFIG_NET=y | ||
290 | |||
291 | # | ||
292 | # Networking options | ||
293 | # | ||
294 | CONFIG_PACKET=y | ||
295 | # CONFIG_PACKET_MMAP is not set | ||
296 | # CONFIG_NETLINK_DEV is not set | ||
297 | CONFIG_UNIX=y | ||
298 | # CONFIG_NET_KEY is not set | ||
299 | CONFIG_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 | ||
311 | CONFIG_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 | ||
348 | CONFIG_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 | # | ||
362 | CONFIG_NET_ETHERNET=y | ||
363 | CONFIG_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 | ||
375 | CONFIG_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 | ||
388 | CONFIG_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 | # | ||
427 | CONFIG_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 | # | ||
437 | CONFIG_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 | ||
447 | CONFIG_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 | ||
483 | CONFIG_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 | ||
507 | CONFIG_LEGACY_PTYS=y | ||
508 | CONFIG_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 | # | ||
563 | CONFIG_SOUND=y | ||
564 | |||
565 | # | ||
566 | # Advanced Linux Sound Architecture | ||
567 | # | ||
568 | CONFIG_SND=m | ||
569 | CONFIG_SND_TIMER=m | ||
570 | CONFIG_SND_PCM=m | ||
571 | CONFIG_SND_HWDEP=m | ||
572 | CONFIG_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 | # | ||
582 | CONFIG_SND_MPU401_UART=m | ||
583 | CONFIG_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 | # | ||
592 | CONFIG_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 | ||
614 | CONFIG_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 | # | ||
635 | CONFIG_SOUND_PRIME=m | ||
636 | # CONFIG_SOUND_BT878 is not set | ||
637 | CONFIG_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 | ||
657 | CONFIG_SOUND_VOYAGERGX=m | ||
658 | |||
659 | # | ||
660 | # USB support | ||
661 | # | ||
662 | # CONFIG_USB is not set | ||
663 | CONFIG_USB_ARCH_HAS_HCD=y | ||
664 | CONFIG_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 | # | ||
688 | CONFIG_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 | ||
699 | CONFIG_MINIX_FS=y | ||
700 | # CONFIG_ROMFS_FS is not set | ||
701 | # CONFIG_QUOTA is not set | ||
702 | CONFIG_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 | # | ||
715 | CONFIG_FAT_FS=y | ||
716 | CONFIG_MSDOS_FS=y | ||
717 | CONFIG_VFAT_FS=y | ||
718 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
719 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
720 | # CONFIG_NTFS_FS is not set | ||
721 | |||
722 | # | ||
723 | # Pseudo filesystems | ||
724 | # | ||
725 | CONFIG_PROC_FS=y | ||
726 | CONFIG_PROC_KCORE=y | ||
727 | CONFIG_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 | ||
732 | CONFIG_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 | ||
766 | CONFIG_MSDOS_PARTITION=y | ||
767 | |||
768 | # | ||
769 | # Native Language Support | ||
770 | # | ||
771 | CONFIG_NLS=y | ||
772 | CONFIG_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 | ||
790 | CONFIG_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 | # | ||
815 | CONFIG_PROFILING=y | ||
816 | CONFIG_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 | ||
846 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | # CONFIG_SWAP is not set | ||
25 | # CONFIG_SYSVIPC is not set | ||
26 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
27 | CONFIG_SYSCTL=y | ||
28 | # CONFIG_AUDIT is not set | ||
29 | CONFIG_LOG_BUF_SHIFT=14 | ||
30 | # CONFIG_HOTPLUG is not set | ||
31 | # CONFIG_IKCONFIG is not set | ||
32 | CONFIG_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 | ||
37 | CONFIG_SHMEM=y | ||
38 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
39 | CONFIG_CC_ALIGN_LABELS=0 | ||
40 | CONFIG_CC_ALIGN_LOOPS=0 | ||
41 | CONFIG_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 | ||
54 | CONFIG_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 | ||
80 | CONFIG_CPU_SH3=y | ||
81 | # CONFIG_CPU_SH4 is not set | ||
82 | # CONFIG_CPU_SUBTYPE_SH7604 is not set | ||
83 | CONFIG_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 | ||
95 | CONFIG_MMU=y | ||
96 | CONFIG_CMDLINE_BOOL=y | ||
97 | CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram0" | ||
98 | CONFIG_MEMORY_START=0x0c000000 | ||
99 | CONFIG_MEMORY_SIZE=0x04000000 | ||
100 | # CONFIG_MEMORY_OVERRIDE is not set | ||
101 | CONFIG_SH_DSP=y | ||
102 | # CONFIG_SH_ADC is not set | ||
103 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
104 | CONFIG_BOOT_LINK_OFFSET=0x00210000 | ||
105 | CONFIG_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 | ||
112 | CONFIG_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 | ||
128 | CONFIG_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 | # | ||
151 | CONFIG_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=y | ||
159 | CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz" | ||
160 | |||
161 | # | ||
162 | # Device Drivers | ||
163 | # | ||
164 | |||
165 | # | ||
166 | # Generic Driver Options | ||
167 | # | ||
168 | CONFIG_STANDALONE=y | ||
169 | CONFIG_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 | ||
192 | CONFIG_BLK_DEV_RAM=y | ||
193 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
194 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
195 | CONFIG_BLK_DEV_INITRD=y | ||
196 | CONFIG_INITRAMFS_SOURCE="" | ||
197 | # CONFIG_LBD is not set | ||
198 | # CONFIG_CDROM_PKTCDVD is not set | ||
199 | |||
200 | # | ||
201 | # IO Schedulers | ||
202 | # | ||
203 | CONFIG_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 | # | ||
254 | CONFIG_INPUT=y | ||
255 | |||
256 | # | ||
257 | # Userland interfaces | ||
258 | # | ||
259 | CONFIG_INPUT_MOUSEDEV=y | ||
260 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
261 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
262 | CONFIG_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 | ||
272 | CONFIG_SOUND_GAMEPORT=y | ||
273 | CONFIG_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 | # | ||
303 | CONFIG_SERIAL_SH_SCI=y | ||
304 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
305 | CONFIG_SERIAL_CORE=y | ||
306 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
307 | # CONFIG_UNIX98_PTYS is not set | ||
308 | # CONFIG_LEGACY_PTYS is not set | ||
309 | |||
310 | # | ||
311 | # IPMI | ||
312 | # | ||
313 | CONFIG_IPMI_HANDLER=y | ||
314 | # CONFIG_IPMI_PANIC_EVENT is not set | ||
315 | CONFIG_IPMI_DEVICE_INTERFACE=y | ||
316 | # CONFIG_IPMI_SI is not set | ||
317 | CONFIG_IPMI_WATCHDOG=y | ||
318 | # CONFIG_IPMI_POWEROFF is not set | ||
319 | |||
320 | # | ||
321 | # Watchdog Cards | ||
322 | # | ||
323 | CONFIG_WATCHDOG=y | ||
324 | # CONFIG_WATCHDOG_NOWAYOUT is not set | ||
325 | |||
326 | # | ||
327 | # Watchdog Device Drivers | ||
328 | # | ||
329 | CONFIG_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 | # | ||
403 | CONFIG_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 | ||
417 | CONFIG_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 | # | ||
437 | CONFIG_PROC_FS=y | ||
438 | CONFIG_PROC_KCORE=y | ||
439 | CONFIG_SYSFS=y | ||
440 | CONFIG_DEVFS_FS=y | ||
441 | CONFIG_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 | ||
446 | CONFIG_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 | ||
469 | CONFIG_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 | ||
486 | CONFIG_SH_STANDARD_BIOS=y | ||
487 | CONFIG_EARLY_PRINTK=y | ||
488 | CONFIG_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 | # | ||
503 | CONFIG_KGDB_DEFPORT=1 | ||
504 | CONFIG_KGDB_DEFBAUD=115200 | ||
505 | CONFIG_KGDB_DEFPARITY_N=y | ||
506 | # CONFIG_KGDB_DEFPARITY_E is not set | ||
507 | # CONFIG_KGDB_DEFPARITY_O is not set | ||
508 | CONFIG_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 | ||
530 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | CONFIG_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 | ||
29 | CONFIG_LOG_BUF_SHIFT=14 | ||
30 | # CONFIG_HOTPLUG is not set | ||
31 | # CONFIG_IKCONFIG is not set | ||
32 | CONFIG_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 | ||
37 | CONFIG_SHMEM=y | ||
38 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
39 | CONFIG_CC_ALIGN_LABELS=0 | ||
40 | CONFIG_CC_ALIGN_LOOPS=0 | ||
41 | CONFIG_CC_ALIGN_JUMPS=0 | ||
42 | # CONFIG_TINY_SHMEM is not set | ||
43 | |||
44 | # | ||
45 | # Loadable module support | ||
46 | # | ||
47 | CONFIG_MODULES=y | ||
48 | # CONFIG_MODULE_UNLOAD is not set | ||
49 | CONFIG_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 | ||
60 | CONFIG_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 | ||
86 | CONFIG_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=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 | ||
100 | CONFIG_MMU=y | ||
101 | CONFIG_CMDLINE_BOOL=y | ||
102 | CONFIG_CMDLINE="console=ttySC0,38400 root=/dev/ram" | ||
103 | CONFIG_MEMORY_START=0x0c000000 | ||
104 | CONFIG_MEMORY_SIZE=0x02000000 | ||
105 | # CONFIG_MEMORY_OVERRIDE is not set | ||
106 | # CONFIG_SH_FPU is not set | ||
107 | CONFIG_ZERO_PAGE_OFFSET=0x00010000 | ||
108 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
109 | CONFIG_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 | ||
117 | CONFIG_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 | ||
133 | CONFIG_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 | # | ||
156 | CONFIG_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=y | ||
164 | CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz" | ||
165 | |||
166 | # | ||
167 | # Device Drivers | ||
168 | # | ||
169 | |||
170 | # | ||
171 | # Generic Driver Options | ||
172 | # | ||
173 | CONFIG_STANDALONE=y | ||
174 | CONFIG_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 | ||
196 | CONFIG_BLK_DEV_LOOP=y | ||
197 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
198 | CONFIG_BLK_DEV_RAM=y | ||
199 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
200 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
201 | CONFIG_BLK_DEV_INITRD=y | ||
202 | CONFIG_INITRAMFS_SOURCE="" | ||
203 | # CONFIG_LBD is not set | ||
204 | # CONFIG_CDROM_PKTCDVD is not set | ||
205 | |||
206 | # | ||
207 | # IO Schedulers | ||
208 | # | ||
209 | CONFIG_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 | ||
270 | CONFIG_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 | # | ||
292 | CONFIG_SERIAL_SH_SCI=y | ||
293 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
294 | CONFIG_SERIAL_CORE=y | ||
295 | CONFIG_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 | # | ||
307 | CONFIG_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 | # | ||
387 | CONFIG_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 | ||
401 | CONFIG_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 | # | ||
421 | CONFIG_PROC_FS=y | ||
422 | CONFIG_PROC_KCORE=y | ||
423 | # CONFIG_SYSFS is not set | ||
424 | CONFIG_DEVFS_FS=y | ||
425 | CONFIG_DEVFS_MOUNT=y | ||
426 | # CONFIG_DEVFS_DEBUG is not set | ||
427 | CONFIG_TMPFS=y | ||
428 | # CONFIG_TMPFS_XATTR is not set | ||
429 | # CONFIG_HUGETLBFS is not set | ||
430 | # CONFIG_HUGETLB_PAGE is not set | ||
431 | CONFIG_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 | ||
454 | CONFIG_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 | ||
471 | CONFIG_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 | ||
495 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | CONFIG_LOCK_KERNEL=y | ||
20 | |||
21 | # | ||
22 | # General setup | ||
23 | # | ||
24 | CONFIG_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 | ||
31 | CONFIG_LOG_BUF_SHIFT=14 | ||
32 | # CONFIG_HOTPLUG is not set | ||
33 | CONFIG_KOBJECT_UEVENT=y | ||
34 | # CONFIG_IKCONFIG is not set | ||
35 | CONFIG_EMBEDDED=y | ||
36 | # CONFIG_KALLSYMS is not set | ||
37 | CONFIG_FUTEX=y | ||
38 | CONFIG_EPOLL=y | ||
39 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
40 | CONFIG_SHMEM=y | ||
41 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
42 | CONFIG_CC_ALIGN_LABELS=0 | ||
43 | CONFIG_CC_ALIGN_LOOPS=0 | ||
44 | CONFIG_CC_ALIGN_JUMPS=0 | ||
45 | # CONFIG_TINY_SHMEM is not set | ||
46 | |||
47 | # | ||
48 | # Loadable module support | ||
49 | # | ||
50 | CONFIG_MODULES=y | ||
51 | # CONFIG_MODULE_UNLOAD is not set | ||
52 | CONFIG_OBSOLETE_MODPARM=y | ||
53 | # CONFIG_MODVERSIONS is not set | ||
54 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
55 | CONFIG_KMOD=y | ||
56 | |||
57 | # | ||
58 | # System type | ||
59 | # | ||
60 | CONFIG_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 | ||
88 | CONFIG_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 | ||
92 | CONFIG_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 | ||
103 | CONFIG_SH7705_CACHE_32KB=y | ||
104 | CONFIG_MMU=y | ||
105 | # CONFIG_CMDLINE_BOOL is not set | ||
106 | CONFIG_MEMORY_START=0x0c000000 | ||
107 | CONFIG_MEMORY_SIZE=0x02000000 | ||
108 | CONFIG_MEMORY_SET=y | ||
109 | # CONFIG_MEMORY_OVERRIDE is not set | ||
110 | # CONFIG_CF_ENABLER is not set | ||
111 | CONFIG_SH_RTC=y | ||
112 | # CONFIG_SH_DSP is not set | ||
113 | # CONFIG_SH_ADC is not set | ||
114 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
115 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
116 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
117 | CONFIG_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 | ||
122 | CONFIG_SH_PCLK_CALC=y | ||
123 | CONFIG_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 | ||
139 | CONFIG_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 | # | ||
162 | CONFIG_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 | # | ||
178 | CONFIG_STANDALONE=y | ||
179 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
180 | # CONFIG_FW_LOADER is not set | ||
181 | |||
182 | # | ||
183 | # Memory Technology Devices (MTD) | ||
184 | # | ||
185 | CONFIG_MTD=y | ||
186 | # CONFIG_MTD_DEBUG is not set | ||
187 | CONFIG_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 | # | ||
195 | CONFIG_MTD_CHAR=y | ||
196 | CONFIG_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 | # | ||
204 | CONFIG_MTD_CFI=y | ||
205 | # CONFIG_MTD_JEDECPROBE is not set | ||
206 | CONFIG_MTD_GEN_PROBE=y | ||
207 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
208 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
209 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
210 | CONFIG_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 | ||
214 | CONFIG_MTD_CFI_I1=y | ||
215 | CONFIG_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 | ||
219 | CONFIG_MTD_CFI_AMDSTD=y | ||
220 | CONFIG_MTD_CFI_AMDSTD_RETRY=0 | ||
221 | # CONFIG_MTD_CFI_STAA is not set | ||
222 | CONFIG_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 | ||
232 | CONFIG_MTD_SOLUTIONENGINE=y | ||
233 | CONFIG_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 | ||
274 | CONFIG_BLK_DEV_RAM=y | ||
275 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
276 | CONFIG_BLK_DEV_RAM_SIZE=8192 | ||
277 | CONFIG_BLK_DEV_INITRD=y | ||
278 | CONFIG_INITRAMFS_SOURCE="" | ||
279 | # CONFIG_LBD is not set | ||
280 | # CONFIG_CDROM_PKTCDVD is not set | ||
281 | |||
282 | # | ||
283 | # IO Schedulers | ||
284 | # | ||
285 | CONFIG_IOSCHED_NOOP=y | ||
286 | CONFIG_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 | # | ||
321 | CONFIG_NET=y | ||
322 | |||
323 | # | ||
324 | # Networking options | ||
325 | # | ||
326 | CONFIG_PACKET=y | ||
327 | # CONFIG_PACKET_MMAP is not set | ||
328 | # CONFIG_NETLINK_DEV is not set | ||
329 | CONFIG_UNIX=y | ||
330 | # CONFIG_NET_KEY is not set | ||
331 | CONFIG_INET=y | ||
332 | # CONFIG_IP_MULTICAST is not set | ||
333 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
334 | CONFIG_IP_PNP=y | ||
335 | CONFIG_IP_PNP_DHCP=y | ||
336 | CONFIG_IP_PNP_BOOTP=y | ||
337 | CONFIG_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 | ||
346 | CONFIG_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 | ||
383 | CONFIG_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 | # | ||
392 | CONFIG_NET_ETHERNET=y | ||
393 | # CONFIG_MII is not set | ||
394 | CONFIG_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 | ||
418 | CONFIG_PPP=y | ||
419 | # CONFIG_PPP_MULTILINK is not set | ||
420 | # CONFIG_PPP_FILTER is not set | ||
421 | CONFIG_PPP_ASYNC=y | ||
422 | # CONFIG_PPP_SYNC_TTY is not set | ||
423 | CONFIG_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 | # | ||
443 | CONFIG_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 | ||
458 | CONFIG_SOUND_GAMEPORT=y | ||
459 | CONFIG_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 | # | ||
489 | CONFIG_SERIAL_SH_SCI=y | ||
490 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
491 | CONFIG_SERIAL_CORE=y | ||
492 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
493 | CONFIG_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 | # | ||
578 | CONFIG_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 | ||
592 | CONFIG_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 | # | ||
612 | CONFIG_PROC_FS=y | ||
613 | CONFIG_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 | ||
620 | CONFIG_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 | ||
633 | CONFIG_JFFS2_FS=y | ||
634 | CONFIG_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 | ||
638 | CONFIG_JFFS2_ZLIB=y | ||
639 | CONFIG_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 | # | ||
651 | CONFIG_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 | ||
656 | CONFIG_ROOT_NFS=y | ||
657 | CONFIG_LOCKD=y | ||
658 | CONFIG_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 | ||
671 | CONFIG_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 | ||
687 | CONFIG_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 | # | ||
710 | CONFIG_CRC_CCITT=y | ||
711 | CONFIG_CRC32=y | ||
712 | # CONFIG_LIBCRC32C is not set | ||
713 | CONFIG_ZLIB_INFLATE=y | ||
714 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | # CONFIG_SWAP is not set | ||
25 | CONFIG_SYSVIPC=y | ||
26 | # CONFIG_POSIX_MQUEUE is not set | ||
27 | CONFIG_BSD_PROCESS_ACCT=y | ||
28 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
29 | CONFIG_SYSCTL=y | ||
30 | # CONFIG_AUDIT is not set | ||
31 | CONFIG_LOG_BUF_SHIFT=14 | ||
32 | # CONFIG_HOTPLUG is not set | ||
33 | CONFIG_KOBJECT_UEVENT=y | ||
34 | CONFIG_IKCONFIG=y | ||
35 | CONFIG_IKCONFIG_PROC=y | ||
36 | CONFIG_EMBEDDED=y | ||
37 | CONFIG_KALLSYMS=y | ||
38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
39 | CONFIG_FUTEX=y | ||
40 | CONFIG_EPOLL=y | ||
41 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
42 | CONFIG_SHMEM=y | ||
43 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
44 | CONFIG_CC_ALIGN_LABELS=0 | ||
45 | CONFIG_CC_ALIGN_LOOPS=0 | ||
46 | CONFIG_CC_ALIGN_JUMPS=0 | ||
47 | # CONFIG_TINY_SHMEM is not set | ||
48 | |||
49 | # | ||
50 | # Loadable module support | ||
51 | # | ||
52 | CONFIG_MODULES=y | ||
53 | # CONFIG_MODULE_UNLOAD is not set | ||
54 | CONFIG_OBSOLETE_MODPARM=y | ||
55 | # CONFIG_MODVERSIONS is not set | ||
56 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
57 | CONFIG_KMOD=y | ||
58 | |||
59 | # | ||
60 | # System type | ||
61 | # | ||
62 | CONFIG_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 | ||
91 | CONFIG_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 | ||
98 | CONFIG_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 | ||
105 | CONFIG_MMU=y | ||
106 | CONFIG_CMDLINE_BOOL=y | ||
107 | CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp" | ||
108 | CONFIG_MEMORY_START=0x0c000000 | ||
109 | CONFIG_MEMORY_SIZE=0x02000000 | ||
110 | CONFIG_MEMORY_SET=y | ||
111 | # CONFIG_MEMORY_OVERRIDE is not set | ||
112 | CONFIG_CF_ENABLER=y | ||
113 | # CONFIG_CF_AREA5 is not set | ||
114 | CONFIG_CF_AREA6=y | ||
115 | CONFIG_CF_BASE_ADDR=0xb8000000 | ||
116 | CONFIG_SH_RTC=y | ||
117 | CONFIG_SH_FPU=y | ||
118 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
119 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
120 | CONFIG_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 | ||
127 | CONFIG_SH_PCLK_CALC=y | ||
128 | CONFIG_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 | ||
144 | CONFIG_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 | # | ||
167 | CONFIG_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 | # | ||
178 | CONFIG_STANDALONE=y | ||
179 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
180 | # CONFIG_FW_LOADER is not set | ||
181 | |||
182 | # | ||
183 | # Memory Technology Devices (MTD) | ||
184 | # | ||
185 | CONFIG_MTD=y | ||
186 | # CONFIG_MTD_DEBUG is not set | ||
187 | CONFIG_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 | # | ||
195 | CONFIG_MTD_CHAR=y | ||
196 | CONFIG_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 | # | ||
204 | CONFIG_MTD_CFI=y | ||
205 | # CONFIG_MTD_JEDECPROBE is not set | ||
206 | CONFIG_MTD_GEN_PROBE=y | ||
207 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
208 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
209 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
210 | CONFIG_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 | ||
214 | CONFIG_MTD_CFI_I1=y | ||
215 | CONFIG_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 | ||
219 | CONFIG_MTD_CFI_AMDSTD=y | ||
220 | CONFIG_MTD_CFI_AMDSTD_RETRY=0 | ||
221 | # CONFIG_MTD_CFI_STAA is not set | ||
222 | CONFIG_MTD_CFI_UTIL=y | ||
223 | # CONFIG_MTD_RAM is not set | ||
224 | CONFIG_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 | ||
232 | CONFIG_MTD_SOLUTIONENGINE=y | ||
233 | CONFIG_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 | ||
275 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
276 | CONFIG_INITRAMFS_SOURCE="" | ||
277 | # CONFIG_LBD is not set | ||
278 | # CONFIG_CDROM_PKTCDVD is not set | ||
279 | |||
280 | # | ||
281 | # IO Schedulers | ||
282 | # | ||
283 | CONFIG_IOSCHED_NOOP=y | ||
284 | CONFIG_IOSCHED_AS=y | ||
285 | CONFIG_IOSCHED_DEADLINE=y | ||
286 | CONFIG_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 | # | ||
319 | CONFIG_NET=y | ||
320 | |||
321 | # | ||
322 | # Networking options | ||
323 | # | ||
324 | CONFIG_PACKET=y | ||
325 | # CONFIG_PACKET_MMAP is not set | ||
326 | # CONFIG_NETLINK_DEV is not set | ||
327 | CONFIG_UNIX=y | ||
328 | # CONFIG_NET_KEY is not set | ||
329 | CONFIG_INET=y | ||
330 | CONFIG_IP_MULTICAST=y | ||
331 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
332 | CONFIG_IP_PNP=y | ||
333 | # CONFIG_IP_PNP_DHCP is not set | ||
334 | CONFIG_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 | ||
345 | CONFIG_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 | ||
382 | CONFIG_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 | # | ||
391 | CONFIG_NET_ETHERNET=y | ||
392 | # CONFIG_MII is not set | ||
393 | CONFIG_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 | ||
445 | CONFIG_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 | # | ||
462 | CONFIG_SERIAL_8250=y | ||
463 | # CONFIG_SERIAL_8250_CONSOLE is not set | ||
464 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
465 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
466 | |||
467 | # | ||
468 | # Non-8250 serial port support | ||
469 | # | ||
470 | CONFIG_SERIAL_SH_SCI=y | ||
471 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
472 | CONFIG_SERIAL_CORE=y | ||
473 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
474 | CONFIG_UNIX98_PTYS=y | ||
475 | CONFIG_LEGACY_PTYS=y | ||
476 | CONFIG_LEGACY_PTY_COUNT=256 | ||
477 | |||
478 | # | ||
479 | # IPMI | ||
480 | # | ||
481 | # CONFIG_IPMI_HANDLER is not set | ||
482 | |||
483 | # | ||
484 | # Watchdog Cards | ||
485 | # | ||
486 | CONFIG_WATCHDOG=y | ||
487 | # CONFIG_WATCHDOG_NOWAYOUT is not set | ||
488 | |||
489 | # | ||
490 | # Watchdog Device Drivers | ||
491 | # | ||
492 | # CONFIG_SOFT_WATCHDOG is not set | ||
493 | CONFIG_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 | ||
580 | CONFIG_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 | # | ||
600 | CONFIG_PROC_FS=y | ||
601 | CONFIG_PROC_KCORE=y | ||
602 | CONFIG_SYSFS=y | ||
603 | # CONFIG_DEVFS_FS is not set | ||
604 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
605 | CONFIG_TMPFS=y | ||
606 | # CONFIG_TMPFS_XATTR is not set | ||
607 | # CONFIG_HUGETLBFS is not set | ||
608 | # CONFIG_HUGETLB_PAGE is not set | ||
609 | CONFIG_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 | ||
622 | CONFIG_JFFS2_FS=y | ||
623 | CONFIG_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 | ||
627 | CONFIG_JFFS2_ZLIB=y | ||
628 | CONFIG_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 | # | ||
640 | CONFIG_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 | ||
645 | CONFIG_ROOT_NFS=y | ||
646 | CONFIG_LOCKD=y | ||
647 | CONFIG_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 | # | ||
659 | CONFIG_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 | ||
710 | CONFIG_CRC32=y | ||
711 | # CONFIG_LIBCRC32C is not set | ||
712 | CONFIG_ZLIB_INFLATE=y | ||
713 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | CONFIG_SWAP=y | ||
25 | CONFIG_SYSVIPC=y | ||
26 | # CONFIG_POSIX_MQUEUE is not set | ||
27 | CONFIG_BSD_PROCESS_ACCT=y | ||
28 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
29 | CONFIG_SYSCTL=y | ||
30 | # CONFIG_AUDIT is not set | ||
31 | CONFIG_LOG_BUF_SHIFT=14 | ||
32 | # CONFIG_HOTPLUG is not set | ||
33 | CONFIG_KOBJECT_UEVENT=y | ||
34 | # CONFIG_IKCONFIG is not set | ||
35 | CONFIG_EMBEDDED=y | ||
36 | CONFIG_KALLSYMS=y | ||
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
38 | CONFIG_FUTEX=y | ||
39 | CONFIG_EPOLL=y | ||
40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
41 | CONFIG_SHMEM=y | ||
42 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
43 | CONFIG_CC_ALIGN_LABELS=0 | ||
44 | CONFIG_CC_ALIGN_LOOPS=0 | ||
45 | CONFIG_CC_ALIGN_JUMPS=0 | ||
46 | # CONFIG_TINY_SHMEM is not set | ||
47 | |||
48 | # | ||
49 | # Loadable module support | ||
50 | # | ||
51 | CONFIG_MODULES=y | ||
52 | # CONFIG_MODULE_UNLOAD is not set | ||
53 | CONFIG_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=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 | ||
90 | CONFIG_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 | ||
98 | CONFIG_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 | ||
104 | CONFIG_MMU=y | ||
105 | CONFIG_CMDLINE_BOOL=y | ||
106 | CONFIG_CMDLINE="console=ttySC1,38400" | ||
107 | CONFIG_MEMORY_START=0x0c000000 | ||
108 | CONFIG_MEMORY_SIZE=0x04000000 | ||
109 | CONFIG_MEMORY_SET=y | ||
110 | # CONFIG_MEMORY_OVERRIDE is not set | ||
111 | CONFIG_SH_RTC=y | ||
112 | CONFIG_SH_FPU=y | ||
113 | CONFIG_ZERO_PAGE_OFFSET=0x00010000 | ||
114 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
115 | CONFIG_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 | ||
122 | CONFIG_SH_PCLK_CALC=y | ||
123 | CONFIG_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 | ||
139 | CONFIG_HEARTBEAT=y | ||
140 | |||
141 | # | ||
142 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | ||
143 | # | ||
144 | CONFIG_PCI=y | ||
145 | # CONFIG_SH_PCIDMA_NONCOHERENT is not set | ||
146 | CONFIG_PCI_AUTO=y | ||
147 | CONFIG_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 | # | ||
168 | CONFIG_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 | # | ||
184 | CONFIG_STANDALONE=y | ||
185 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
186 | # CONFIG_FW_LOADER is not set | ||
187 | |||
188 | # | ||
189 | # Memory Technology Devices (MTD) | ||
190 | # | ||
191 | CONFIG_MTD=y | ||
192 | # CONFIG_MTD_DEBUG is not set | ||
193 | CONFIG_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 | ||
202 | CONFIG_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 | # | ||
210 | CONFIG_MTD_CFI=y | ||
211 | # CONFIG_MTD_JEDECPROBE is not set | ||
212 | CONFIG_MTD_GEN_PROBE=y | ||
213 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
214 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
215 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
216 | CONFIG_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 | ||
220 | CONFIG_MTD_CFI_I1=y | ||
221 | CONFIG_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 | ||
225 | CONFIG_MTD_CFI_AMDSTD=y | ||
226 | CONFIG_MTD_CFI_AMDSTD_RETRY=0 | ||
227 | # CONFIG_MTD_CFI_STAA is not set | ||
228 | CONFIG_MTD_CFI_UTIL=y | ||
229 | CONFIG_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 | ||
285 | CONFIG_BLK_DEV_RAM=y | ||
286 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
287 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
288 | CONFIG_BLK_DEV_INITRD=y | ||
289 | CONFIG_INITRAMFS_SOURCE="" | ||
290 | # CONFIG_LBD is not set | ||
291 | # CONFIG_CDROM_PKTCDVD is not set | ||
292 | |||
293 | # | ||
294 | # IO Schedulers | ||
295 | # | ||
296 | CONFIG_IOSCHED_NOOP=y | ||
297 | CONFIG_IOSCHED_AS=y | ||
298 | CONFIG_IOSCHED_DEADLINE=y | ||
299 | CONFIG_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 | # | ||
334 | CONFIG_NET=y | ||
335 | |||
336 | # | ||
337 | # Networking options | ||
338 | # | ||
339 | CONFIG_PACKET=y | ||
340 | # CONFIG_PACKET_MMAP is not set | ||
341 | CONFIG_NETLINK_DEV=y | ||
342 | CONFIG_UNIX=y | ||
343 | # CONFIG_NET_KEY is not set | ||
344 | CONFIG_INET=y | ||
345 | CONFIG_IP_MULTICAST=y | ||
346 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
347 | CONFIG_IP_PNP=y | ||
348 | CONFIG_IP_PNP_DHCP=y | ||
349 | CONFIG_IP_PNP_BOOTP=y | ||
350 | CONFIG_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 | ||
360 | CONFIG_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 | ||
368 | CONFIG_NETFILTER=y | ||
369 | CONFIG_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 | ||
376 | CONFIG_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 | ||
412 | CONFIG_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 | # | ||
427 | CONFIG_NET_ETHERNET=y | ||
428 | CONFIG_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 | ||
440 | CONFIG_NET_PCI=y | ||
441 | CONFIG_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 | ||
524 | CONFIG_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 | ||
547 | CONFIG_UNIX98_PTYS=y | ||
548 | CONFIG_LEGACY_PTYS=y | ||
549 | CONFIG_LEGACY_PTY_COUNT=256 | ||
550 | |||
551 | # | ||
552 | # IPMI | ||
553 | # | ||
554 | # CONFIG_IPMI_HANDLER is not set | ||
555 | |||
556 | # | ||
557 | # Watchdog Cards | ||
558 | # | ||
559 | CONFIG_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 | ||
623 | CONFIG_USB_ARCH_HAS_HCD=y | ||
624 | CONFIG_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 | # | ||
648 | CONFIG_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 | ||
662 | CONFIG_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 | # | ||
682 | CONFIG_PROC_FS=y | ||
683 | CONFIG_PROC_KCORE=y | ||
684 | CONFIG_SYSFS=y | ||
685 | # CONFIG_DEVFS_FS is not set | ||
686 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
687 | CONFIG_TMPFS=y | ||
688 | # CONFIG_TMPFS_XATTR is not set | ||
689 | # CONFIG_HUGETLBFS is not set | ||
690 | # CONFIG_HUGETLB_PAGE is not set | ||
691 | CONFIG_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 | ||
704 | CONFIG_JFFS2_FS=y | ||
705 | CONFIG_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 | ||
709 | CONFIG_JFFS2_ZLIB=y | ||
710 | CONFIG_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 | ||
734 | CONFIG_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 | ||
774 | CONFIG_CRC32=y | ||
775 | # CONFIG_LIBCRC32C is not set | ||
776 | CONFIG_ZLIB_INFLATE=y | ||
777 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | # CONFIG_CLEAN_COMPILE is not set | ||
18 | CONFIG_BROKEN=y | ||
19 | CONFIG_BROKEN_ON_SMP=y | ||
20 | CONFIG_LOCK_KERNEL=y | ||
21 | |||
22 | # | ||
23 | # General setup | ||
24 | # | ||
25 | CONFIG_LOCALVERSION="" | ||
26 | CONFIG_SWAP=y | ||
27 | CONFIG_SYSVIPC=y | ||
28 | CONFIG_POSIX_MQUEUE=y | ||
29 | CONFIG_BSD_PROCESS_ACCT=y | ||
30 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
31 | CONFIG_SYSCTL=y | ||
32 | # CONFIG_AUDIT is not set | ||
33 | CONFIG_LOG_BUF_SHIFT=14 | ||
34 | CONFIG_HOTPLUG=y | ||
35 | CONFIG_KOBJECT_UEVENT=y | ||
36 | # CONFIG_IKCONFIG is not set | ||
37 | # CONFIG_EMBEDDED is not set | ||
38 | CONFIG_KALLSYMS=y | ||
39 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
40 | CONFIG_FUTEX=y | ||
41 | CONFIG_EPOLL=y | ||
42 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
43 | CONFIG_SHMEM=y | ||
44 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
45 | CONFIG_CC_ALIGN_LABELS=0 | ||
46 | CONFIG_CC_ALIGN_LOOPS=0 | ||
47 | CONFIG_CC_ALIGN_JUMPS=0 | ||
48 | # CONFIG_TINY_SHMEM is not set | ||
49 | |||
50 | # | ||
51 | # Loadable module support | ||
52 | # | ||
53 | CONFIG_MODULES=y | ||
54 | CONFIG_MODULE_UNLOAD=y | ||
55 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
56 | CONFIG_OBSOLETE_MODPARM=y | ||
57 | CONFIG_MODVERSIONS=y | ||
58 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
59 | CONFIG_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 | ||
84 | CONFIG_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 | ||
93 | CONFIG_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 | ||
101 | CONFIG_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 | ||
107 | CONFIG_MMU=y | ||
108 | CONFIG_CMDLINE_BOOL=y | ||
109 | CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs" | ||
110 | CONFIG_MEMORY_START=0x08000000 | ||
111 | CONFIG_MEMORY_SIZE=0x08000000 | ||
112 | CONFIG_MEMORY_SET=y | ||
113 | # CONFIG_MEMORY_OVERRIDE is not set | ||
114 | CONFIG_CF_ENABLER=y | ||
115 | CONFIG_CF_AREA5=y | ||
116 | # CONFIG_CF_AREA6 is not set | ||
117 | CONFIG_CF_BASE_ADDR=0xb4000000 | ||
118 | CONFIG_SH_RTC=y | ||
119 | CONFIG_SH_FPU=y | ||
120 | CONFIG_ZERO_PAGE_OFFSET=0x00004000 | ||
121 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
122 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
123 | CONFIG_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 | ||
129 | CONFIG_SH_PCLK_CALC=y | ||
130 | CONFIG_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 | ||
146 | CONFIG_HEARTBEAT=y | ||
147 | |||
148 | # | ||
149 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | ||
150 | # | ||
151 | CONFIG_PCI=y | ||
152 | CONFIG_SH_PCIDMA_NONCOHERENT=y | ||
153 | CONFIG_PCI_AUTO=y | ||
154 | CONFIG_PCI_AUTO_UPDATE_RESOURCES=y | ||
155 | CONFIG_PCI_LEGACY_PROC=y | ||
156 | CONFIG_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 | # | ||
170 | CONFIG_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 | # | ||
178 | CONFIG_BINFMT_ELF=y | ||
179 | # CONFIG_BINFMT_FLAT is not set | ||
180 | CONFIG_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 | ||
221 | CONFIG_BLK_DEV_LOOP=y | ||
222 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
223 | CONFIG_BLK_DEV_NBD=y | ||
224 | # CONFIG_BLK_DEV_SX8 is not set | ||
225 | CONFIG_BLK_DEV_RAM=y | ||
226 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
227 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
228 | CONFIG_BLK_DEV_INITRD=y | ||
229 | CONFIG_INITRAMFS_SOURCE="" | ||
230 | # CONFIG_LBD is not set | ||
231 | # CONFIG_CDROM_PKTCDVD is not set | ||
232 | |||
233 | # | ||
234 | # IO Schedulers | ||
235 | # | ||
236 | CONFIG_IOSCHED_NOOP=y | ||
237 | CONFIG_IOSCHED_AS=y | ||
238 | CONFIG_IOSCHED_DEADLINE=y | ||
239 | CONFIG_IOSCHED_CFQ=y | ||
240 | # CONFIG_ATA_OVER_ETH is not set | ||
241 | |||
242 | # | ||
243 | # ATA/ATAPI/MFM/RLL support | ||
244 | # | ||
245 | CONFIG_IDE=y | ||
246 | CONFIG_IDE_MAX_HWIFS=4 | ||
247 | CONFIG_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 | ||
253 | CONFIG_BLK_DEV_IDEDISK=y | ||
254 | CONFIG_IDEDISK_MULTI_MODE=y | ||
255 | CONFIG_BLK_DEV_IDECD=m | ||
256 | CONFIG_BLK_DEV_IDETAPE=m | ||
257 | CONFIG_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 | # | ||
264 | CONFIG_IDE_GENERIC=y | ||
265 | # CONFIG_BLK_DEV_IDEPCI is not set | ||
266 | CONFIG_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 | # | ||
275 | CONFIG_SCSI=m | ||
276 | CONFIG_SCSI_PROC_FS=y | ||
277 | |||
278 | # | ||
279 | # SCSI support type (disk, tape, CD-ROM) | ||
280 | # | ||
281 | CONFIG_BLK_DEV_SD=m | ||
282 | # CONFIG_CHR_DEV_ST is not set | ||
283 | # CONFIG_CHR_DEV_OSST is not set | ||
284 | CONFIG_BLK_DEV_SR=m | ||
285 | CONFIG_BLK_DEV_SR_VENDOR=y | ||
286 | CONFIG_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 | ||
334 | CONFIG_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 | # | ||
368 | CONFIG_NET=y | ||
369 | |||
370 | # | ||
371 | # Networking options | ||
372 | # | ||
373 | CONFIG_PACKET=y | ||
374 | # CONFIG_PACKET_MMAP is not set | ||
375 | # CONFIG_NETLINK_DEV is not set | ||
376 | CONFIG_UNIX=y | ||
377 | CONFIG_NET_KEY=y | ||
378 | CONFIG_INET=y | ||
379 | CONFIG_IP_MULTICAST=y | ||
380 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
381 | CONFIG_IP_PNP=y | ||
382 | CONFIG_IP_PNP_DHCP=y | ||
383 | CONFIG_IP_PNP_BOOTP=y | ||
384 | CONFIG_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 | ||
394 | CONFIG_IP_TCPDIAG=y | ||
395 | # CONFIG_IP_TCPDIAG_IPV6 is not set | ||
396 | # CONFIG_IPV6 is not set | ||
397 | # CONFIG_NETFILTER is not set | ||
398 | CONFIG_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 | ||
433 | CONFIG_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 | # | ||
447 | CONFIG_NET_ETHERNET=y | ||
448 | CONFIG_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 | ||
460 | CONFIG_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 | ||
472 | CONFIG_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 | # | ||
535 | CONFIG_INPUT=y | ||
536 | |||
537 | # | ||
538 | # Userland interfaces | ||
539 | # | ||
540 | CONFIG_INPUT_MOUSEDEV=y | ||
541 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
542 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
543 | CONFIG_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 | ||
553 | CONFIG_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 | # | ||
569 | CONFIG_VT=y | ||
570 | CONFIG_VT_CONSOLE=y | ||
571 | CONFIG_HW_CONSOLE=y | ||
572 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
573 | |||
574 | # | ||
575 | # Serial drivers | ||
576 | # | ||
577 | CONFIG_SERIAL_8250=m | ||
578 | CONFIG_SERIAL_8250_NR_UARTS=4 | ||
579 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
580 | |||
581 | # | ||
582 | # Non-8250 serial port support | ||
583 | # | ||
584 | CONFIG_SERIAL_SH_SCI=y | ||
585 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
586 | CONFIG_SERIAL_CORE=y | ||
587 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
588 | CONFIG_UNIX98_PTYS=y | ||
589 | CONFIG_LEGACY_PTYS=y | ||
590 | CONFIG_LEGACY_PTY_COUNT=256 | ||
591 | |||
592 | # | ||
593 | # IPMI | ||
594 | # | ||
595 | # CONFIG_IPMI_HANDLER is not set | ||
596 | |||
597 | # | ||
598 | # Watchdog Cards | ||
599 | # | ||
600 | CONFIG_WATCHDOG=y | ||
601 | # CONFIG_WATCHDOG_NOWAYOUT is not set | ||
602 | |||
603 | # | ||
604 | # Watchdog Device Drivers | ||
605 | # | ||
606 | # CONFIG_SOFT_WATCHDOG is not set | ||
607 | CONFIG_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 | ||
615 | CONFIG_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 | ||
660 | CONFIG_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 | ||
671 | CONFIG_USB_ARCH_HAS_HCD=y | ||
672 | CONFIG_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 | # | ||
696 | CONFIG_EXT2_FS=y | ||
697 | CONFIG_EXT2_FS_XATTR=y | ||
698 | # CONFIG_EXT2_FS_POSIX_ACL is not set | ||
699 | # CONFIG_EXT2_FS_SECURITY is not set | ||
700 | CONFIG_EXT3_FS=y | ||
701 | CONFIG_EXT3_FS_XATTR=y | ||
702 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
703 | # CONFIG_EXT3_FS_SECURITY is not set | ||
704 | CONFIG_JBD=y | ||
705 | # CONFIG_JBD_DEBUG is not set | ||
706 | CONFIG_FS_MBCACHE=y | ||
707 | # CONFIG_REISERFS_FS is not set | ||
708 | # CONFIG_JFS_FS is not set | ||
709 | CONFIG_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 | ||
718 | CONFIG_DNOTIFY=y | ||
719 | CONFIG_AUTOFS_FS=y | ||
720 | CONFIG_AUTOFS4_FS=y | ||
721 | |||
722 | # | ||
723 | # CD-ROM/DVD Filesystems | ||
724 | # | ||
725 | CONFIG_ISO9660_FS=m | ||
726 | CONFIG_JOLIET=y | ||
727 | CONFIG_ZISOFS=y | ||
728 | CONFIG_ZISOFS_FS=m | ||
729 | CONFIG_UDF_FS=m | ||
730 | CONFIG_UDF_NLS=y | ||
731 | |||
732 | # | ||
733 | # DOS/FAT/NT Filesystems | ||
734 | # | ||
735 | CONFIG_FAT_FS=m | ||
736 | CONFIG_MSDOS_FS=m | ||
737 | CONFIG_VFAT_FS=m | ||
738 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
739 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
740 | # CONFIG_NTFS_FS is not set | ||
741 | |||
742 | # | ||
743 | # Pseudo filesystems | ||
744 | # | ||
745 | CONFIG_PROC_FS=y | ||
746 | CONFIG_PROC_KCORE=y | ||
747 | CONFIG_SYSFS=y | ||
748 | # CONFIG_DEVFS_FS is not set | ||
749 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
750 | CONFIG_TMPFS=y | ||
751 | # CONFIG_TMPFS_XATTR is not set | ||
752 | # CONFIG_HUGETLBFS is not set | ||
753 | # CONFIG_HUGETLB_PAGE is not set | ||
754 | CONFIG_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 | # | ||
776 | CONFIG_NFS_FS=y | ||
777 | CONFIG_NFS_V3=y | ||
778 | CONFIG_NFS_V4=y | ||
779 | # CONFIG_NFS_DIRECTIO is not set | ||
780 | CONFIG_NFSD=y | ||
781 | CONFIG_NFSD_V3=y | ||
782 | # CONFIG_NFSD_V4 is not set | ||
783 | CONFIG_NFSD_TCP=y | ||
784 | CONFIG_ROOT_NFS=y | ||
785 | CONFIG_LOCKD=y | ||
786 | CONFIG_LOCKD_V4=y | ||
787 | CONFIG_EXPORTFS=y | ||
788 | CONFIG_SUNRPC=y | ||
789 | CONFIG_SUNRPC_GSS=y | ||
790 | CONFIG_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 | # | ||
801 | CONFIG_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 | ||
807 | CONFIG_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 | # | ||
821 | CONFIG_NLS=m | ||
822 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
823 | CONFIG_NLS_CODEPAGE_437=m | ||
824 | CONFIG_NLS_CODEPAGE_737=m | ||
825 | CONFIG_NLS_CODEPAGE_775=m | ||
826 | CONFIG_NLS_CODEPAGE_850=m | ||
827 | CONFIG_NLS_CODEPAGE_852=m | ||
828 | CONFIG_NLS_CODEPAGE_855=m | ||
829 | CONFIG_NLS_CODEPAGE_857=m | ||
830 | CONFIG_NLS_CODEPAGE_860=m | ||
831 | CONFIG_NLS_CODEPAGE_861=m | ||
832 | CONFIG_NLS_CODEPAGE_862=m | ||
833 | CONFIG_NLS_CODEPAGE_863=m | ||
834 | CONFIG_NLS_CODEPAGE_864=m | ||
835 | CONFIG_NLS_CODEPAGE_865=m | ||
836 | CONFIG_NLS_CODEPAGE_866=m | ||
837 | CONFIG_NLS_CODEPAGE_869=m | ||
838 | CONFIG_NLS_CODEPAGE_936=m | ||
839 | CONFIG_NLS_CODEPAGE_950=m | ||
840 | CONFIG_NLS_CODEPAGE_932=m | ||
841 | CONFIG_NLS_CODEPAGE_949=m | ||
842 | CONFIG_NLS_CODEPAGE_874=m | ||
843 | CONFIG_NLS_ISO8859_8=m | ||
844 | CONFIG_NLS_CODEPAGE_1250=m | ||
845 | CONFIG_NLS_CODEPAGE_1251=m | ||
846 | CONFIG_NLS_ASCII=m | ||
847 | CONFIG_NLS_ISO8859_1=m | ||
848 | CONFIG_NLS_ISO8859_2=m | ||
849 | CONFIG_NLS_ISO8859_3=m | ||
850 | CONFIG_NLS_ISO8859_4=m | ||
851 | CONFIG_NLS_ISO8859_5=m | ||
852 | CONFIG_NLS_ISO8859_6=m | ||
853 | CONFIG_NLS_ISO8859_7=m | ||
854 | CONFIG_NLS_ISO8859_9=m | ||
855 | CONFIG_NLS_ISO8859_13=m | ||
856 | CONFIG_NLS_ISO8859_14=m | ||
857 | CONFIG_NLS_ISO8859_15=m | ||
858 | CONFIG_NLS_KOI8_R=m | ||
859 | CONFIG_NLS_KOI8_U=m | ||
860 | CONFIG_NLS_UTF8=m | ||
861 | |||
862 | # | ||
863 | # Profiling support | ||
864 | # | ||
865 | CONFIG_PROFILING=y | ||
866 | CONFIG_OPROFILE=m | ||
867 | |||
868 | # | ||
869 | # Kernel hacking | ||
870 | # | ||
871 | # CONFIG_DEBUG_KERNEL is not set | ||
872 | CONFIG_DEBUG_PREEMPT=y | ||
873 | # CONFIG_FRAME_POINTER is not set | ||
874 | CONFIG_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 | # | ||
888 | CONFIG_CRYPTO=y | ||
889 | CONFIG_CRYPTO_HMAC=y | ||
890 | # CONFIG_CRYPTO_NULL is not set | ||
891 | # CONFIG_CRYPTO_MD4 is not set | ||
892 | CONFIG_CRYPTO_MD5=y | ||
893 | CONFIG_CRYPTO_SHA1=y | ||
894 | # CONFIG_CRYPTO_SHA256 is not set | ||
895 | # CONFIG_CRYPTO_SHA512 is not set | ||
896 | # CONFIG_CRYPTO_WP512 is not set | ||
897 | CONFIG_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 | ||
908 | CONFIG_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 | # | ||
920 | CONFIG_CRC_CCITT=y | ||
921 | CONFIG_CRC32=y | ||
922 | # CONFIG_LIBCRC32C is not set | ||
923 | CONFIG_ZLIB_INFLATE=y | ||
924 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | CONFIG_CLEAN_COMPILE=y | ||
18 | CONFIG_BROKEN_ON_SMP=y | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | CONFIG_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 | ||
30 | CONFIG_LOG_BUF_SHIFT=14 | ||
31 | # CONFIG_HOTPLUG is not set | ||
32 | CONFIG_KOBJECT_UEVENT=y | ||
33 | # CONFIG_IKCONFIG is not set | ||
34 | # CONFIG_EMBEDDED is not set | ||
35 | CONFIG_KALLSYMS=y | ||
36 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
37 | CONFIG_FUTEX=y | ||
38 | CONFIG_EPOLL=y | ||
39 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
40 | CONFIG_SHMEM=y | ||
41 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
42 | CONFIG_CC_ALIGN_LABELS=0 | ||
43 | CONFIG_CC_ALIGN_LOOPS=0 | ||
44 | CONFIG_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 | ||
76 | CONFIG_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 | ||
84 | CONFIG_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 | ||
92 | CONFIG_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 | ||
98 | CONFIG_MMU=y | ||
99 | # CONFIG_CMDLINE_BOOL is not set | ||
100 | CONFIG_MEMORY_START=0x08000000 | ||
101 | CONFIG_MEMORY_SIZE=0x01000000 | ||
102 | CONFIG_MEMORY_SET=y | ||
103 | # CONFIG_MEMORY_OVERRIDE is not set | ||
104 | CONFIG_SH_RTC=y | ||
105 | CONFIG_SH_FPU=y | ||
106 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
107 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
108 | CONFIG_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 | ||
115 | CONFIG_SH_PCLK_CALC=y | ||
116 | CONFIG_SH_PCLK_FREQ=60013568 | ||
117 | |||
118 | # | ||
119 | # CPU Frequency scaling | ||
120 | # | ||
121 | # CONFIG_CPU_FREQ is not set | ||
122 | |||
123 | # | ||
124 | # DMA support | ||
125 | # | ||
126 | CONFIG_SH_DMA=y | ||
127 | CONFIG_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 | # | ||
138 | CONFIG_PCI=y | ||
139 | # CONFIG_SH_PCIDMA_NONCOHERENT is not set | ||
140 | CONFIG_PCI_AUTO=y | ||
141 | CONFIG_PCI_AUTO_UPDATE_RESOURCES=y | ||
142 | # CONFIG_PCI_LEGACY_PROC is not set | ||
143 | CONFIG_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 | # | ||
162 | CONFIG_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 | # | ||
178 | CONFIG_STANDALONE=y | ||
179 | CONFIG_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 | ||
208 | CONFIG_BLK_DEV_RAM=y | ||
209 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
210 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
211 | CONFIG_BLK_DEV_INITRD=y | ||
212 | CONFIG_INITRAMFS_SOURCE="" | ||
213 | # CONFIG_LBD is not set | ||
214 | # CONFIG_CDROM_PKTCDVD is not set | ||
215 | |||
216 | # | ||
217 | # IO Schedulers | ||
218 | # | ||
219 | CONFIG_IOSCHED_NOOP=y | ||
220 | CONFIG_IOSCHED_AS=y | ||
221 | CONFIG_IOSCHED_DEADLINE=y | ||
222 | CONFIG_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 | # | ||
257 | CONFIG_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 | ||
266 | CONFIG_INET=y | ||
267 | # CONFIG_IP_MULTICAST is not set | ||
268 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
269 | CONFIG_IP_PNP=y | ||
270 | CONFIG_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 | ||
281 | CONFIG_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 | ||
318 | CONFIG_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 | # | ||
332 | CONFIG_NET_ETHERNET=y | ||
333 | CONFIG_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 | ||
345 | CONFIG_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 | ||
358 | CONFIG_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 | # | ||
423 | CONFIG_INPUT=y | ||
424 | |||
425 | # | ||
426 | # Userland interfaces | ||
427 | # | ||
428 | CONFIG_INPUT_MOUSEDEV=y | ||
429 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
430 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
431 | CONFIG_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 | ||
441 | CONFIG_SOUND_GAMEPORT=y | ||
442 | CONFIG_SERIO=y | ||
443 | CONFIG_SERIO_I8042=y | ||
444 | CONFIG_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 | # | ||
461 | CONFIG_VT=y | ||
462 | CONFIG_VT_CONSOLE=y | ||
463 | CONFIG_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 | ||
475 | CONFIG_UNIX98_PTYS=y | ||
476 | CONFIG_LEGACY_PTYS=y | ||
477 | CONFIG_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 | # | ||
532 | CONFIG_VGA_CONSOLE=y | ||
533 | CONFIG_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 | ||
544 | CONFIG_USB_ARCH_HAS_HCD=y | ||
545 | CONFIG_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 | # | ||
569 | CONFIG_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 | ||
581 | CONFIG_ROMFS_FS=y | ||
582 | # CONFIG_QUOTA is not set | ||
583 | CONFIG_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 | # | ||
603 | CONFIG_PROC_FS=y | ||
604 | # CONFIG_PROC_KCORE is not set | ||
605 | CONFIG_SYSFS=y | ||
606 | CONFIG_DEVFS_FS=y | ||
607 | CONFIG_DEVFS_MOUNT=y | ||
608 | # CONFIG_DEVFS_DEBUG is not set | ||
609 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
610 | CONFIG_TMPFS=y | ||
611 | # CONFIG_TMPFS_XATTR is not set | ||
612 | # CONFIG_HUGETLBFS is not set | ||
613 | # CONFIG_HUGETLB_PAGE is not set | ||
614 | CONFIG_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 | ||
626 | CONFIG_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 | # | ||
636 | CONFIG_NFS_FS=y | ||
637 | CONFIG_NFS_V3=y | ||
638 | # CONFIG_NFS_V4 is not set | ||
639 | # CONFIG_NFS_DIRECTIO is not set | ||
640 | # CONFIG_NFSD is not set | ||
641 | CONFIG_ROOT_NFS=y | ||
642 | CONFIG_LOCKD=y | ||
643 | CONFIG_LOCKD_V4=y | ||
644 | CONFIG_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 | ||
657 | CONFIG_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 | ||
697 | CONFIG_CRC32=y | ||
698 | # CONFIG_LIBCRC32C is not set | ||
699 | CONFIG_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 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_UID16=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
12 | |||
13 | # | ||
14 | # Code maturity level options | ||
15 | # | ||
16 | CONFIG_EXPERIMENTAL=y | ||
17 | # CONFIG_CLEAN_COMPILE is not set | ||
18 | CONFIG_BROKEN=y | ||
19 | CONFIG_BROKEN_ON_SMP=y | ||
20 | CONFIG_LOCK_KERNEL=y | ||
21 | |||
22 | # | ||
23 | # General setup | ||
24 | # | ||
25 | CONFIG_LOCALVERSION="" | ||
26 | CONFIG_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 | ||
31 | CONFIG_LOG_BUF_SHIFT=14 | ||
32 | # CONFIG_HOTPLUG is not set | ||
33 | # CONFIG_IKCONFIG is not set | ||
34 | CONFIG_EMBEDDED=y | ||
35 | CONFIG_KALLSYMS=y | ||
36 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
37 | CONFIG_FUTEX=y | ||
38 | CONFIG_EPOLL=y | ||
39 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
40 | CONFIG_SHMEM=y | ||
41 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
42 | CONFIG_CC_ALIGN_LABELS=0 | ||
43 | CONFIG_CC_ALIGN_LOOPS=0 | ||
44 | CONFIG_CC_ALIGN_JUMPS=0 | ||
45 | # CONFIG_TINY_SHMEM is not set | ||
46 | |||
47 | # | ||
48 | # Loadable module support | ||
49 | # | ||
50 | CONFIG_MODULES=y | ||
51 | CONFIG_MODULE_UNLOAD=y | ||
52 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
53 | CONFIG_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 | ||
65 | CONFIG_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 | ||
90 | CONFIG_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 | ||
98 | CONFIG_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 | ||
104 | CONFIG_MMU=y | ||
105 | # CONFIG_CMDLINE_BOOL is not set | ||
106 | CONFIG_MEMORY_START=0x0c000000 | ||
107 | CONFIG_MEMORY_SIZE=0x00400000 | ||
108 | # CONFIG_MEMORY_OVERRIDE is not set | ||
109 | CONFIG_SH_RTC=y | ||
110 | CONFIG_SH_FPU=y | ||
111 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
112 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
113 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
114 | CONFIG_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 | ||
120 | CONFIG_SH_PCLK_CALC=y | ||
121 | CONFIG_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 | # | ||
141 | CONFIG_PCI=y | ||
142 | # CONFIG_SH_PCIDMA_NONCOHERENT is not set | ||
143 | CONFIG_PCI_AUTO=y | ||
144 | CONFIG_PCI_AUTO_UPDATE_RESOURCES=y | ||
145 | CONFIG_PCI_LEGACY_PROC=y | ||
146 | CONFIG_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 | # | ||
165 | CONFIG_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 | ||
182 | CONFIG_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 | ||
210 | CONFIG_BLK_DEV_RAM=y | ||
211 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
212 | CONFIG_BLK_DEV_RAM_SIZE=1024 | ||
213 | CONFIG_BLK_DEV_INITRD=y | ||
214 | CONFIG_INITRAMFS_SOURCE="" | ||
215 | # CONFIG_LBD is not set | ||
216 | # CONFIG_CDROM_PKTCDVD is not set | ||
217 | |||
218 | # | ||
219 | # IO Schedulers | ||
220 | # | ||
221 | CONFIG_IOSCHED_NOOP=y | ||
222 | CONFIG_IOSCHED_AS=y | ||
223 | CONFIG_IOSCHED_DEADLINE=y | ||
224 | CONFIG_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 | ||
284 | CONFIG_SOUND_GAMEPORT=y | ||
285 | CONFIG_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 | ||
312 | CONFIG_UNIX98_PTYS=y | ||
313 | CONFIG_LEGACY_PTYS=y | ||
314 | CONFIG_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 | ||
374 | CONFIG_USB_ARCH_HAS_HCD=y | ||
375 | CONFIG_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 | ||
410 | CONFIG_ROMFS_FS=y | ||
411 | # CONFIG_QUOTA is not set | ||
412 | CONFIG_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 | # | ||
432 | CONFIG_PROC_FS=y | ||
433 | CONFIG_PROC_KCORE=y | ||
434 | CONFIG_SYSFS=y | ||
435 | CONFIG_DEVFS_FS=y | ||
436 | CONFIG_DEVFS_MOUNT=y | ||
437 | # CONFIG_DEVFS_DEBUG is not set | ||
438 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
439 | CONFIG_TMPFS=y | ||
440 | # CONFIG_TMPFS_XATTR is not set | ||
441 | # CONFIG_HUGETLBFS is not set | ||
442 | # CONFIG_HUGETLB_PAGE is not set | ||
443 | CONFIG_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 | ||
455 | CONFIG_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 | ||
466 | CONFIG_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 | ||
482 | CONFIG_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 | ||
507 | CONFIG_CRC32=y | ||
508 | # CONFIG_LIBCRC32C is not set | ||
509 | CONFIG_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 | |||
5 | obj-$(CONFIG_PCI) += pci/ | ||
6 | obj-$(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 @@ | |||
1 | menu "DMA support" | ||
2 | |||
3 | config 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 | |||
11 | config 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 | |||
20 | config 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 | |||
28 | config 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 | |||
37 | config 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 | |||
45 | config 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 | |||
54 | endmenu | ||
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 | |||
5 | obj-y += dma-api.o dma-isa.o | ||
6 | obj-$(CONFIG_SYSFS) += dma-sysfs.o | ||
7 | obj-$(CONFIG_SH_DMA) += dma-sh.o | ||
8 | obj-$(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 | |||
20 | DEFINE_SPINLOCK(dma_spin_lock); | ||
21 | static 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 | |||
56 | struct 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, ®istered_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 | |||
78 | struct 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 | |||
88 | int 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 | |||
99 | int 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 | |||
123 | void 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 | |||
134 | void 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 | |||
149 | void 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 | |||
158 | int 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 | ||
173 | static 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(®istered_dmac_list)) | ||
180 | return 0; | ||
181 | |||
182 | /* | ||
183 | * Iterate over each registered DMAC | ||
184 | */ | ||
185 | list_for_each_safe(pos, tmp, ®istered_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 | |||
208 | int __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, ®istered_dmac_list); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | void __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 | |||
266 | static 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 | |||
277 | subsys_initcall(dma_api_init); | ||
278 | |||
279 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | ||
280 | MODULE_DESCRIPTION("DMA API for SuperH"); | ||
281 | MODULE_LICENSE("GPL"); | ||
282 | |||
283 | EXPORT_SYMBOL(request_dma); | ||
284 | EXPORT_SYMBOL(free_dma); | ||
285 | EXPORT_SYMBOL(register_dmac); | ||
286 | EXPORT_SYMBOL(get_dma_residue); | ||
287 | EXPORT_SYMBOL(get_dma_info); | ||
288 | EXPORT_SYMBOL(get_dma_channel); | ||
289 | EXPORT_SYMBOL(dma_xfer); | ||
290 | EXPORT_SYMBOL(dma_wait_for_completion); | ||
291 | EXPORT_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 | |||
21 | struct 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 | |||
32 | struct 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 | |||
39 | struct 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 | |||
48 | static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800; | ||
49 | |||
50 | static 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 | |||
56 | static struct irqaction g2_dma_irq = { | ||
57 | .name = "g2 DMA handler", | ||
58 | .handler = g2_dma_interrupt, | ||
59 | .flags = SA_INTERRUPT, | ||
60 | }; | ||
61 | |||
62 | static 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 | |||
72 | static 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 | |||
82 | static 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 | |||
138 | static struct dma_ops g2_dma_ops = { | ||
139 | .xfer = g2_xfer_dma, | ||
140 | }; | ||
141 | |||
142 | static 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 | |||
149 | static 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 | |||
160 | static void __exit g2_dma_exit(void) | ||
161 | { | ||
162 | free_irq(HW_EVENT_G2_DMA, 0); | ||
163 | } | ||
164 | |||
165 | subsys_initcall(g2_dma_init); | ||
166 | module_exit(g2_dma_exit); | ||
167 | |||
168 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | ||
169 | MODULE_DESCRIPTION("G2 bus DMA driver"); | ||
170 | MODULE_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 | |||
35 | unsigned 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 | } | ||
43 | EXPORT_SYMBOL(claim_dma_lock); | ||
44 | |||
45 | void __deprecated release_dma_lock(unsigned long flags) | ||
46 | { | ||
47 | spin_unlock_irqrestore(&dma_spin_lock, flags); | ||
48 | } | ||
49 | EXPORT_SYMBOL(release_dma_lock); | ||
50 | |||
51 | void __deprecated disable_dma(unsigned int chan) | ||
52 | { | ||
53 | /* Nothing */ | ||
54 | } | ||
55 | EXPORT_SYMBOL(disable_dma); | ||
56 | |||
57 | void __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 | } | ||
64 | EXPORT_SYMBOL(enable_dma); | ||
65 | |||
66 | void clear_dma_ff(unsigned int chan) | ||
67 | { | ||
68 | /* Nothing */ | ||
69 | } | ||
70 | EXPORT_SYMBOL(clear_dma_ff); | ||
71 | |||
72 | void 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 | } | ||
79 | EXPORT_SYMBOL(set_dma_mode); | ||
80 | |||
81 | void 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 | } | ||
96 | EXPORT_SYMBOL(set_dma_addr); | ||
97 | |||
98 | void 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 | } | ||
105 | EXPORT_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 | |||
21 | static unsigned int xfer_complete = 0; | ||
22 | static int count = 0; | ||
23 | |||
24 | static 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 | |||
41 | static 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 | |||
51 | static int pvr2_get_dma_residue(struct dma_channel *chan) | ||
52 | { | ||
53 | return xfer_complete == 0; | ||
54 | } | ||
55 | |||
56 | static 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 | |||
70 | static struct irqaction pvr2_dma_irq = { | ||
71 | .name = "pvr2 DMA handler", | ||
72 | .handler = pvr2_dma_interrupt, | ||
73 | .flags = SA_INTERRUPT, | ||
74 | }; | ||
75 | |||
76 | static 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 | |||
82 | static 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 | |||
89 | static 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 | |||
97 | static void __exit pvr2_dma_exit(void) | ||
98 | { | ||
99 | free_dma(PVR2_CASCADE_CHAN); | ||
100 | free_irq(HW_EVENT_PVR2_DMA, 0); | ||
101 | } | ||
102 | |||
103 | subsys_initcall(pvr2_dma_init); | ||
104 | module_exit(pvr2_dma_exit); | ||
105 | |||
106 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | ||
107 | MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver"); | ||
108 | MODULE_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 | */ | ||
31 | enum { | ||
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 | */ | ||
42 | static 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 | |||
50 | static 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 | */ | ||
77 | static 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 | */ | ||
92 | static 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 | |||
110 | static 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 | |||
116 | static void sh_dmac_free_dma(struct dma_channel *chan) | ||
117 | { | ||
118 | free_irq(get_dmte_irq(chan->chan), chan); | ||
119 | } | ||
120 | |||
121 | static 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 | |||
131 | static 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 | |||
143 | static 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 | |||
155 | static 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 | |||
193 | static 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) | ||
202 | static 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 | |||
218 | static 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 | |||
226 | static 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 | |||
233 | static 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 | |||
256 | static void __exit sh_dmac_exit(void) | ||
257 | { | ||
258 | #ifdef CONFIG_CPU_SH4 | ||
259 | free_irq(DMAE_IRQ, 0); | ||
260 | #endif | ||
261 | } | ||
262 | |||
263 | subsys_initcall(sh_dmac_init); | ||
264 | module_exit(sh_dmac_exit); | ||
265 | |||
266 | MODULE_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 | |||
18 | static struct sysdev_class dma_sysclass = { | ||
19 | set_kset_name("dma"), | ||
20 | }; | ||
21 | |||
22 | EXPORT_SYMBOL(dma_sysclass); | ||
23 | |||
24 | static 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 | |||
41 | static SYSDEV_ATTR(devices, S_IRUGO, dma_show_devices, NULL); | ||
42 | |||
43 | static 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 | |||
54 | postcore_initcall(dma_sysclass_init); | ||
55 | |||
56 | static 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 | |||
62 | static 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 | |||
70 | static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id); | ||
71 | |||
72 | static 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 | |||
84 | static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config); | ||
85 | |||
86 | static 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 | |||
92 | static 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 | |||
100 | static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode); | ||
101 | |||
102 | #define dma_ro_attr(field, fmt) \ | ||
103 | static 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 | } \ | ||
108 | static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL); | ||
109 | |||
110 | dma_ro_attr(count, "0x%08x\n"); | ||
111 | dma_ro_attr(flags, "0x%08lx\n"); | ||
112 | |||
113 | int __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 @@ | |||
1 | config 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 | |||
13 | config 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 | ||
26 | config PCI_AUTO | ||
27 | bool | ||
28 | depends on PCI | ||
29 | default y | ||
30 | |||
31 | config 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 | |||
5 | obj-y += pci.o | ||
6 | obj-$(CONFIG_PCI_AUTO) += pci-auto.o | ||
7 | |||
8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o | ||
9 | obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o | ||
10 | |||
11 | obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ | ||
12 | dma-dreamcast.o | ||
13 | obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o | ||
14 | obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o | ||
15 | obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o | ||
16 | obj-$(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 | |||
33 | static int gapspci_dma_used = 0; | ||
34 | |||
35 | void *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 | |||
60 | int 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 | |||
31 | static 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 | |||
50 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); | ||
51 | |||
52 | void __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 | |||
61 | void __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 | |||
19 | int 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 | |||
10 | int __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 | |||
36 | static u8 __init sh03_no_swizzle(struct pci_dev *dev, u8 *pin) | ||
37 | { | ||
38 | /* no swizzling */ | ||
39 | return PCI_SLOT(dev->devfn); | ||
40 | } | ||
41 | |||
42 | static 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 | |||
58 | void __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 | |||
28 | static 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 | |||
35 | static 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 | |||
42 | extern struct pci_ops sh7751_pci_ops; | ||
43 | |||
44 | struct pci_channel board_pci_channels[] = { | ||
45 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
46 | { 0, } | ||
47 | }; | ||
48 | |||
49 | static 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 | */ | ||
67 | int __init pcibios_init_platform(void) | ||
68 | { | ||
69 | return sh7751_pcic_init(&sh7751_pci_map); | ||
70 | } | ||
71 | |||
72 | int 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 | |||
31 | static 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 | |||
38 | static 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 | |||
45 | static struct pci_ops gapspci_pci_ops; | ||
46 | |||
47 | struct 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 | */ | ||
69 | static 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 | */ | ||
79 | static 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 | |||
95 | static 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 | |||
109 | static struct pci_ops gapspci_pci_ops = { | ||
110 | .read = gapspci_read, | ||
111 | .write = gapspci_write, | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * gapspci init | ||
116 | */ | ||
117 | |||
118 | int __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 */ | ||
166 | char * __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 | |||
26 | int __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 | |||
39 | static 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 | |||
46 | static 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 | |||
53 | extern struct pci_ops sh7751_pci_ops; | ||
54 | |||
55 | struct pci_channel board_pci_channels[] = { | ||
56 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
57 | { NULL, NULL, NULL, 0, 0 }, | ||
58 | }; | ||
59 | EXPORT_SYMBOL(board_pci_channels); | ||
60 | |||
61 | static 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 | |||
75 | int __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 | */ | ||
20 | int __init pcibios_init_platform(void) | ||
21 | { | ||
22 | return 1; | ||
23 | } | ||
24 | |||
25 | static 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 | |||
32 | static 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 | |||
39 | extern struct pci_ops sh7751_pci_ops; | ||
40 | |||
41 | struct 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 | |||
33 | static 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 | |||
40 | static 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 | |||
47 | extern struct pci_ops sh7751_pci_ops; | ||
48 | |||
49 | struct pci_channel board_pci_channels[] = { | ||
50 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
51 | { 0, } | ||
52 | }; | ||
53 | |||
54 | static 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 | */ | ||
74 | int __init pcibios_init_platform(void) | ||
75 | { | ||
76 | return sh7751_pcic_init(&sh7751_pci_map); | ||
77 | } | ||
78 | |||
79 | int __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 | |||
98 | void __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 | */ | ||
59 | static 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) \ | ||
81 | int 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 | |||
89 | EARLY_PCI_OP(read, byte, u8 *) | ||
90 | EARLY_PCI_OP(read, word, u16 *) | ||
91 | EARLY_PCI_OP(read, dword, u32 *) | ||
92 | EARLY_PCI_OP(write, byte, u8) | ||
93 | EARLY_PCI_OP(write, word, u16) | ||
94 | EARLY_PCI_OP(write, dword, u32) | ||
95 | |||
96 | static struct resource *io_resource_inuse; | ||
97 | static struct resource *mem_resource_inuse; | ||
98 | |||
99 | static u32 pciauto_lower_iospc; | ||
100 | static u32 pciauto_upper_iospc; | ||
101 | |||
102 | static u32 pciauto_lower_memspc; | ||
103 | static u32 pciauto_upper_memspc; | ||
104 | |||
105 | static void __init | ||
106 | pciauto_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 | |||
168 | retry: | ||
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 | |||
250 | static void __init | ||
251 | pciauto_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 | |||
286 | static void __init | ||
287 | pciauto_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 | |||
329 | static void __init | ||
330 | pciauto_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 | |||
356 | static void __init | ||
357 | pciauto_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 | |||
425 | static int __init | ||
426 | pciauto_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 | |||
538 | int __init | ||
539 | pciauto_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 | |||
33 | static unsigned int pci_probe = PCI_PROBE_CONF1; | ||
34 | extern int pci_fixup_pcic(void); | ||
35 | |||
36 | void 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 | */ | ||
47 | static 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 | */ | ||
84 | static 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 | |||
121 | struct pci_ops sh7751_pci_ops = { | ||
122 | .read = sh7751_pci_read, | ||
123 | .write = sh7751_pci_write, | ||
124 | }; | ||
125 | |||
126 | static 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 | |||
163 | static 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 | |||
182 | DECLARE_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 | |||
189 | void __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 | |||
208 | static 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 | |||
219 | subsys_initcall(sh7751_pci_init); | ||
220 | |||
221 | static 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 | |||
246 | int __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 | |||
378 | char * __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 | */ | ||
391 | static u8 __init sh7751_no_swizzle(struct pci_dev *dev, u8 *pin) | ||
392 | { | ||
393 | /* no swizzling */ | ||
394 | return PCI_SLOT(dev->devfn); | ||
395 | } | ||
396 | |||
397 | static 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 | |||
413 | void __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... */ | ||
285 | extern int pcibios_init_platform(void); | ||
286 | extern int pcibios_map_platform_irq(u8 slot, u8 pin); | ||
287 | |||
288 | struct sh7751_pci_address_space { | ||
289 | unsigned long base; | ||
290 | unsigned long size; | ||
291 | }; | ||
292 | |||
293 | struct 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 */ | ||
300 | extern 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 | |||
71 | static 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 | */ | ||
78 | extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); | ||
79 | |||
80 | static __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 | |||
106 | struct pci_err { | ||
107 | unsigned mask; | ||
108 | const char *error_string; | ||
109 | }; | ||
110 | |||
111 | static 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 | |||
127 | static 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 | |||
139 | static 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 | |||
152 | static 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 | |||
171 | static 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 | */ | ||
217 | static 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 | |||
240 | static 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 | } | ||
258 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
259 | |||
260 | int __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 | |||
339 | char * __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 | |||
351 | static 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 */ | ||
364 | static 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 | |||
396 | static 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 | |||
417 | struct pci_ops st40pci_config_ops = { | ||
418 | .read = st40pci_read, | ||
419 | .write = st40pci_write, | ||
420 | }; | ||
421 | |||
422 | |||
423 | /* Everything hangs off this */ | ||
424 | static struct pci_bus *pci_root_bus; | ||
425 | |||
426 | |||
427 | static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) | ||
428 | { | ||
429 | return PCI_SLOT(dev->devfn); | ||
430 | } | ||
431 | |||
432 | |||
433 | static 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 | |||
474 | subsys_initcall(pcibios_init); | ||
475 | |||
476 | void __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 | */ | ||
484 | static 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 | |||
20 | static 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 | |||
47 | subsys_initcall(pcibios_init); | ||
48 | |||
49 | void | ||
50 | pcibios_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 | |||
77 | void 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 | */ | ||
87 | void 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 | |||
100 | int 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 | */ | ||
136 | unsigned int pcibios_max_latency = 255; | ||
137 | |||
138 | void 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 | |||
152 | void __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 | |||
5 | extra-y := head.o init_task.o vmlinux.lds | ||
6 | |||
7 | obj-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 | |||
11 | obj-y += cpu/ | ||
12 | |||
13 | obj-$(CONFIG_SMP) += smp.o | ||
14 | obj-$(CONFIG_CF_ENABLER) += cf-enabler.o | ||
15 | obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o | ||
16 | obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o | ||
17 | obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o | ||
18 | obj-$(CONFIG_MODULES) += module.o | ||
19 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
20 | |||
21 | USE_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 | |||
21 | int 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 */ | ||
46 | extern 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*/ | ||
49 | void *cf_io_base; | ||
50 | |||
51 | static 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 | |||
74 | static 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 | |||
101 | static 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 | |||
149 | int __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 | |||
5 | obj-y := irq_ipr.o irq_imask.o init.o bus.o | ||
6 | |||
7 | obj-$(CONFIG_CPU_SH2) += sh2/ | ||
8 | obj-$(CONFIG_CPU_SH3) += sh3/ | ||
9 | obj-$(CONFIG_CPU_SH4) += sh4/ | ||
10 | |||
11 | obj-$(CONFIG_SH_RTC) += rtc.o | ||
12 | obj-$(CONFIG_UBC_WAKEUP) += ubc.o | ||
13 | obj-$(CONFIG_SH_ADC) += adc.o | ||
14 | |||
15 | USE_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 | |||
12 | int 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 | |||
36 | EXPORT_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 | |||
26 | static 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 | |||
34 | static 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 | |||
45 | static 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 | |||
56 | static struct device sh_bus_devices[SH_NR_BUSES] = { | ||
57 | { | ||
58 | .bus_id = SH_BUS_NAME_VIRT, | ||
59 | }, | ||
60 | }; | ||
61 | |||
62 | struct 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 | |||
71 | static 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 | |||
82 | static 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 | |||
93 | int 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 | |||
120 | void sh_device_unregister(struct sh_dev *dev) | ||
121 | { | ||
122 | device_unregister(&dev->dev); | ||
123 | } | ||
124 | |||
125 | int 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 | |||
143 | void sh_driver_unregister(struct sh_driver *drv) | ||
144 | { | ||
145 | driver_unregister(&drv->drv); | ||
146 | } | ||
147 | |||
148 | static 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 | |||
173 | static 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 | |||
183 | module_init(sh_bus_init); | ||
184 | module_exit(sh_bus_exit); | ||
185 | |||
186 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | ||
187 | MODULE_DESCRIPTION("SH Virtual Bus"); | ||
188 | MODULE_LICENSE("GPL"); | ||
189 | |||
190 | EXPORT_SYMBOL(sh_bus_types); | ||
191 | EXPORT_SYMBOL(sh_device_register); | ||
192 | EXPORT_SYMBOL(sh_device_unregister); | ||
193 | EXPORT_SYMBOL(sh_driver_register); | ||
194 | EXPORT_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 | |||
21 | extern 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) \ | ||
28 | static int x##_disabled __initdata = 0; \ | ||
29 | \ | ||
30 | static int __init x##_setup(char *opts) \ | ||
31 | { \ | ||
32 | x##_disabled = 1; \ | ||
33 | return 0; \ | ||
34 | } \ | ||
35 | __setup("no" __stringify(x), x##_setup); | ||
36 | |||
37 | onchip_setup(fpu); | ||
38 | onchip_setup(dsp); | ||
39 | |||
40 | /* | ||
41 | * Generic first-level cache init | ||
42 | */ | ||
43 | static 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 | ||
122 | static 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 | |||
136 | static 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 | */ | ||
179 | asmlinkage 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 */ | ||
31 | static unsigned long imask_mask = 0x7fff; | ||
32 | static int interrupt_priority = 0; | ||
33 | |||
34 | static void enable_imask_irq(unsigned int irq); | ||
35 | static void disable_imask_irq(unsigned int irq); | ||
36 | static void shutdown_imask_irq(unsigned int irq); | ||
37 | static void mask_and_ack_imask(unsigned int); | ||
38 | static void end_imask_irq(unsigned int irq); | ||
39 | |||
40 | #define IMASK_PRIORITY 15 | ||
41 | |||
42 | static unsigned int startup_imask_irq(unsigned int irq) | ||
43 | { | ||
44 | /* Nothing to do */ | ||
45 | return 0; /* never anything pending */ | ||
46 | } | ||
47 | |||
48 | static 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 | |||
58 | void 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 | |||
78 | static 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 | |||
87 | static 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 | |||
95 | static void mask_and_ack_imask(unsigned int irq) | ||
96 | { | ||
97 | disable_imask_irq(irq); | ||
98 | } | ||
99 | |||
100 | static 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 | |||
106 | static void shutdown_imask_irq(unsigned int irq) | ||
107 | { | ||
108 | /* Nothing to do */ | ||
109 | } | ||
110 | |||
111 | void 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 | |||
28 | struct 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 | }; | ||
33 | static struct ipr_data ipr_data[NR_IRQS]; | ||
34 | |||
35 | static void enable_ipr_irq(unsigned int irq); | ||
36 | static void disable_ipr_irq(unsigned int irq); | ||
37 | |||
38 | /* shutdown is same as "disable" */ | ||
39 | #define shutdown_ipr_irq disable_ipr_irq | ||
40 | |||
41 | static void mask_and_ack_ipr(unsigned int); | ||
42 | static void end_ipr_irq(unsigned int irq); | ||
43 | |||
44 | static unsigned int startup_ipr_irq(unsigned int irq) | ||
45 | { | ||
46 | enable_ipr_irq(irq); | ||
47 | return 0; /* never anything pending */ | ||
48 | } | ||
49 | |||
50 | static 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 | |||
60 | static 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 | |||
74 | static 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 | |||
89 | static 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 | |||
106 | static 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 | |||
112 | void 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) | ||
126 | static unsigned char pint_map[256]; | ||
127 | static unsigned long portcr_mask = 0; | ||
128 | |||
129 | static void enable_pint_irq(unsigned int irq); | ||
130 | static void disable_pint_irq(unsigned int irq); | ||
131 | |||
132 | /* shutdown is same as "disable" */ | ||
133 | #define shutdown_pint_irq disable_pint_irq | ||
134 | |||
135 | static void mask_and_ack_pint(unsigned int); | ||
136 | static void end_pint_irq(unsigned int irq); | ||
137 | |||
138 | static unsigned int startup_pint_irq(unsigned int irq) | ||
139 | { | ||
140 | enable_pint_irq(irq); | ||
141 | return 0; /* never anything pending */ | ||
142 | } | ||
143 | |||
144 | static 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 | |||
154 | static 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 | |||
166 | static 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 | |||
178 | static void mask_and_ack_pint(unsigned int irq) | ||
179 | { | ||
180 | disable_pint_irq(irq); | ||
181 | } | ||
182 | |||
183 | static 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 | |||
189 | void 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 | |||
197 | void __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) | ||
296 | int 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 | |||
338 | EXPORT_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 | |||
24 | void 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 | */ | ||
96 | int 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 | |||
5 | obj-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 | |||
18 | int __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 | |||
5 | obj-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 | |||
20 | ENTRY(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*/ | ||
45 | ENTRY(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 | ||
51 | ENTRY(user_break_point_trap) | ||
52 | .long break_point_trap /* 1E0 */ | ||
53 | ENTRY(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 | |||
19 | int __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 | |||
5 | obj-y := ex.o probe.o | ||
6 | |||
7 | obj-$(CONFIG_SH_FPU) += fpu.o | ||
8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += irq_intc2.o | ||
9 | obj-$(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 | |||
20 | ENTRY(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*/ | ||
49 | ENTRY(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 | ||
55 | ENTRY(user_break_point_trap) | ||
56 | .long break_point_trap /* 1E0 */ | ||
57 | ENTRY(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 | */ | ||
33 | void | ||
34 | save_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 | |||
88 | static void | ||
89 | restore_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 | |||
143 | static void | ||
144 | fpu_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 | */ | ||
196 | static void | ||
197 | denormal_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 | */ | ||
225 | static int | ||
226 | ieee_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 | |||
298 | asmlinkage void | ||
299 | do_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 (®s)) | ||
305 | return; | ||
306 | |||
307 | regs.pc += 2; | ||
308 | save_fpu(tsk, ®s); | ||
309 | tsk->thread.trap_no = 11; | ||
310 | tsk->thread.error_code = 0; | ||
311 | force_sig(SIGFPE, tsk); | ||
312 | } | ||
313 | |||
314 | asmlinkage void | ||
315 | do_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(®s); | ||
321 | if (!user_mode(®s)) { | ||
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 | |||
24 | struct 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 | |||
33 | static struct intc2_data intc2_data[NR_INTC2_IRQS]; | ||
34 | |||
35 | static void enable_intc2_irq(unsigned int irq); | ||
36 | static void disable_intc2_irq(unsigned int irq); | ||
37 | |||
38 | /* shutdown is same as "disable" */ | ||
39 | #define shutdown_intc2_irq disable_intc2_irq | ||
40 | |||
41 | static void mask_and_ack_intc2(unsigned int); | ||
42 | static void end_intc2_irq(unsigned int irq); | ||
43 | |||
44 | static unsigned int startup_intc2_irq(unsigned int irq) | ||
45 | { | ||
46 | enable_intc2_irq(irq); | ||
47 | return 0; /* never anything pending */ | ||
48 | } | ||
49 | |||
50 | static 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 | |||
60 | static 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 | |||
76 | static 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 | |||
92 | static void mask_and_ack_intc2(unsigned int irq) | ||
93 | { | ||
94 | disable_intc2_irq(irq); | ||
95 | } | ||
96 | |||
97 | static 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 | */ | ||
118 | void 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 | |||
156 | struct intc2_init { | ||
157 | unsigned short irq; | ||
158 | unsigned char ipr_offset, ipr_shift; | ||
159 | unsigned char msk_offset, msk_shift; | ||
160 | }; | ||
161 | |||
162 | static 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 | |||
199 | void __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 */ | ||
214 | void 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 | |||
19 | int __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 | |||
34 | static LIST_HEAD(sq_mapping_list); | ||
35 | static 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 | */ | ||
44 | inline 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 | */ | ||
57 | void 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 | |||
73 | static 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 | |||
96 | static 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 | */ | ||
132 | static 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 | */ | ||
222 | struct 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 | */ | ||
259 | void 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 | */ | ||
276 | void 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 | */ | ||
299 | static 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 | */ | ||
339 | static 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 | |||
347 | static 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 | */ | ||
361 | static 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 | ||
392 | static 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 | |||
412 | static struct file_operations sq_fops = { | ||
413 | .owner = THIS_MODULE, | ||
414 | .mmap = sq_mmap, | ||
415 | }; | ||
416 | |||
417 | static struct miscdevice sq_dev = { | ||
418 | .minor = STORE_QUEUE_MINOR, | ||
419 | .name = "sq", | ||
420 | .devfs_name = "cpu/sq", | ||
421 | .fops = &sq_fops, | ||
422 | }; | ||
423 | |||
424 | static 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 | |||
435 | static void __exit sq_api_exit(void) | ||
436 | { | ||
437 | misc_deregister(&sq_dev); | ||
438 | } | ||
439 | |||
440 | module_init(sq_api_init); | ||
441 | module_exit(sq_api_exit); | ||
442 | |||
443 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>"); | ||
444 | MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues"); | ||
445 | MODULE_LICENSE("GPL"); | ||
446 | MODULE_ALIAS_MISCDEV(STORE_QUEUE_MINOR); | ||
447 | |||
448 | EXPORT_SYMBOL(sq_remap); | ||
449 | EXPORT_SYMBOL(sq_unmap); | ||
450 | EXPORT_SYMBOL(sq_clear); | ||
451 | EXPORT_SYMBOL(sq_flush); | ||
452 | EXPORT_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 | |||
18 | ENTRY(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 | |||
43 | ENTRY(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 | |||
55 | 1: .long UBC_BBRA | ||
56 | 2: .long UBC_BBRB | ||
57 | 3: .long UBC_BRCR | ||
58 | 4: .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 | */ | ||
37 | struct 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 | |||
65 | static struct cpufreq_frequency_table sh_freqs[] = { | ||
66 | { SH_FREQ_MAX, 0 }, | ||
67 | { SH_FREQ_MIN, 0 }, | ||
68 | { 0, CPUFREQ_TABLE_END }, | ||
69 | }; | ||
70 | |||
71 | static 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 | */ | ||
83 | static 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 | |||
139 | static 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 | |||
168 | static int sh_cpufreq_verify(struct cpufreq_policy *policy) | ||
169 | { | ||
170 | return cpufreq_frequency_table_verify(policy, &sh_freqs[0]); | ||
171 | } | ||
172 | |||
173 | static 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 | |||
189 | static 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 | |||
197 | static 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 | |||
207 | static void __exit sh_cpufreq_exit(void) | ||
208 | { | ||
209 | cpufreq_unregister_driver(&sh_cpufreq_driver); | ||
210 | } | ||
211 | |||
212 | module_init(sh_cpufreq_init); | ||
213 | module_exit(sh_cpufreq_exit); | ||
214 | |||
215 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | ||
216 | MODULE_DESCRIPTION("cpufreq driver for SuperH"); | ||
217 | MODULE_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 | */ | ||
23 | static 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 | */ | ||
35 | static 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 | |||
52 | static 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 | |||
64 | static 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 | |||
75 | static 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 | |||
84 | static 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 | |||
92 | static 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 | |||
99 | static 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 | |||
107 | void 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 | |||
125 | void __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 | |||
133 | void 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 | |||
75 | ENOSYS = 38 | ||
76 | EINVAL = 22 | ||
77 | |||
78 | #if defined(CONFIG_CPU_SH3) | ||
79 | TRA = 0xffffffd0 | ||
80 | EXPEVT = 0xffffffd4 | ||
81 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ | ||
82 | defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
83 | INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000) | ||
84 | #else | ||
85 | INTEVT = 0xffffffd8 | ||
86 | #endif | ||
87 | MMU_TEA = 0xfffffffc ! TLB Exception Address Register | ||
88 | #elif defined(CONFIG_CPU_SH4) | ||
89 | TRA = 0xff000020 | ||
90 | EXPEVT = 0xff000024 | ||
91 | INTEVT = 0xff000028 | ||
92 | MMU_TEA = 0xff00000c ! TLB Exception Address Register | ||
93 | #endif | ||
94 | |||
95 | #if defined(CONFIG_KGDB_NMI) | ||
96 | NMI_VEC = 0x1c0 ! Must catch early for debounce | ||
97 | #endif | ||
98 | |||
99 | /* Offsets to the stack */ | ||
100 | OFF_R0 = 0 /* Return value. New ABI also arg4 */ | ||
101 | OFF_R1 = 4 /* New ABI: arg5 */ | ||
102 | OFF_R2 = 8 /* New ABI: arg6 */ | ||
103 | OFF_R3 = 12 /* New ABI: syscall_nr */ | ||
104 | OFF_R4 = 16 /* New ABI: arg0 */ | ||
105 | OFF_R5 = 20 /* New ABI: arg1 */ | ||
106 | OFF_R6 = 24 /* New ABI: arg2 */ | ||
107 | OFF_R7 = 28 /* New ABI: arg3 */ | ||
108 | OFF_SP = (15*4) | ||
109 | OFF_PC = (16*4) | ||
110 | OFF_SR = (16*4+8) | ||
111 | OFF_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 | ||
173 | ENTRY(tlb_miss_load) | ||
174 | bra call_dpf | ||
175 | mov #0, r5 | ||
176 | |||
177 | .align 2 | ||
178 | ENTRY(tlb_miss_store) | ||
179 | bra call_dpf | ||
180 | mov #1, r5 | ||
181 | |||
182 | .align 2 | ||
183 | ENTRY(initial_page_write) | ||
184 | bra call_dpf | ||
185 | mov #1, r5 | ||
186 | |||
187 | .align 2 | ||
188 | ENTRY(tlb_protection_violation_load) | ||
189 | bra call_dpf | ||
190 | mov #0, r5 | ||
191 | |||
192 | .align 2 | ||
193 | ENTRY(tlb_protection_violation_store) | ||
194 | bra call_dpf | ||
195 | mov #1, r5 | ||
196 | |||
197 | call_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 | ||
212 | 0: 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 | ||
220 | 1: .long MMU_TEA | ||
221 | 2: .long __do_page_fault | ||
222 | 3: .long do_page_fault | ||
223 | |||
224 | .align 2 | ||
225 | ENTRY(address_error_load) | ||
226 | bra call_dae | ||
227 | mov #0,r5 ! writeaccess = 0 | ||
228 | |||
229 | .align 2 | ||
230 | ENTRY(address_error_store) | ||
231 | bra call_dae | ||
232 | mov #1,r5 ! writeaccess = 1 | ||
233 | |||
234 | .align 2 | ||
235 | call_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 | ||
243 | 1: .long MMU_TEA | ||
244 | 2: .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 | ||
253 | debug_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 | |||
262 | debug_enter: | ||
263 | #if defined(CONFIG_SH_KGDB) | ||
264 | /* Jump to kgdb, pass stacked regs as arg */ | ||
265 | debug_kernel_sw: | ||
266 | mov.l 3f, r0 | ||
267 | jmp @r0 | ||
268 | mov r15, r4 | ||
269 | .align 2 | ||
270 | 3: .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 */ | ||
275 | debug_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 | ||
309 | 1: .long 0x300000f0 | ||
310 | 2: .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 | ||
317 | debug_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 | ||
331 | ENTRY(exception_error) | ||
332 | ! | ||
333 | STI() | ||
334 | mov.l 2f, r0 | ||
335 | jmp @r0 | ||
336 | nop | ||
337 | |||
338 | ! | ||
339 | .align 2 | ||
340 | 1: .long break_point_trap_software | ||
341 | 2: .long do_exception_error | ||
342 | |||
343 | .align 2 | ||
344 | ret_from_exception: | ||
345 | preempt_stop() | ||
346 | ret_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 | ||
358 | ENTRY(resume_kernel) | ||
359 | mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count | ||
360 | tst r0, r0 | ||
361 | bf noresched | ||
362 | need_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 | ||
386 | noresched: | ||
387 | bra restore_all | ||
388 | nop | ||
389 | |||
390 | .align 2 | ||
391 | 1: .long PREEMPT_ACTIVE | ||
392 | 2: .long schedule | ||
393 | #endif | ||
394 | |||
395 | ENTRY(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 | ||
404 | work_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 | ||
410 | work_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 | ||
418 | work_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 | ! | ||
436 | 1: | ||
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 | ||
450 | 1: .long schedule | ||
451 | 2: .long do_signal | ||
452 | |||
453 | .align 2 | ||
454 | syscall_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 | ||
469 | syscall_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 | ||
521 | ret_from_fork: | ||
522 | mov.l 1f, r8 | ||
523 | jsr @r8 | ||
524 | mov r0, r4 | ||
525 | bra syscall_exit | ||
526 | nop | ||
527 | .align 2 | ||
528 | 1: .long schedule_tail | ||
529 | ! | ||
530 | ENTRY(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) | ||
550 | syscall_badsys: ! Bad syscall number | ||
551 | mov #-ENOSYS, r0 | ||
552 | bra resume_userspace | ||
553 | mov.l r0, @(OFF_R0,r15) ! Return value | ||
554 | ! | ||
555 | 0: | ||
556 | bra debug_trap | ||
557 | nop | ||
558 | ! | ||
559 | good_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 | ! | ||
565 | syscall_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 | ! | ||
574 | syscall_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 | ||
581 | restore_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 | ||
643 | skip_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 | ! | ||
659 | 6: 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 | ||
674 | 1: .long TRA | ||
675 | 2: .long NR_syscalls | ||
676 | 3: .long sys_call_table | ||
677 | 4: .long do_syscall_trace | ||
678 | 5: .long 0x00001000 ! DSP | ||
679 | 7: .long 0x30000000 | ||
680 | 9: | ||
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 | ||
689 | ENTRY(vbr_base) | ||
690 | .long 0 | ||
691 | ! | ||
692 | .balign 256,0,256 | ||
693 | general_exception: | ||
694 | mov.l 1f, k2 | ||
695 | mov.l 2f, k3 | ||
696 | bra handle_exception | ||
697 | mov.l @k2, k2 | ||
698 | .align 2 | ||
699 | 1: .long EXPEVT | ||
700 | 2: .long ret_from_exception | ||
701 | ! | ||
702 | ! | ||
703 | .balign 1024,0,1024 | ||
704 | tlb_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 | ||
711 | interrupt: | ||
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 | ||
726 | 5: .long NMI_VEC | ||
727 | 6: .long in_nmi | ||
728 | 0: | ||
729 | #endif /* defined(CONFIG_KGDB_NMI) */ | ||
730 | bra handle_exception | ||
731 | mov.l @k2, k2 | ||
732 | |||
733 | .align 2 | ||
734 | 1: .long EXPEVT | ||
735 | 2: .long INTEVT | ||
736 | 3: .long ret_from_irq | ||
737 | 4: .long ret_from_exception | ||
738 | |||
739 | ! | ||
740 | ! | ||
741 | .align 2 | ||
742 | handle_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 | ! | ||
757 | 1: 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 | ||
798 | skip_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 | ||
848 | 1: .long 0x00001000 ! DSP=1 | ||
849 | 2: .long 0x000080f0 ! FD=1, IMASK=15 | ||
850 | 3: .long 0xcfffffff ! RB=0, BL=0 | ||
851 | 4: .long exception_handling_table | ||
852 | |||
853 | .align 2 | ||
854 | ENTRY(exception_none) | ||
855 | rts | ||
856 | nop | ||
857 | |||
858 | .data | ||
859 | ENTRY(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" | ||
16 | ENTRY(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 | */ | ||
38 | ENTRY(_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 | ||
62 | 9: 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 | ||
71 | 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF | ||
72 | 2: .long stack | ||
73 | 3: .long __bss_start | ||
74 | 4: .long _end | ||
75 | 5: .long start_kernel | ||
76 | 6: .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 | |||
10 | static struct fs_struct init_fs = INIT_FS; | ||
11 | static struct files_struct init_files = INIT_FILES; | ||
12 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | ||
13 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | ||
14 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
15 | |||
16 | EXPORT_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 | */ | ||
25 | union 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 | */ | ||
34 | struct task_struct init_task = INIT_TASK(init_task); | ||
35 | |||
36 | EXPORT_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 | */ | ||
17 | void 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 | */ | ||
32 | void 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 | */ | ||
47 | void 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 | |||
56 | EXPORT_SYMBOL(memcpy_fromio); | ||
57 | EXPORT_SYMBOL(memcpy_toio); | ||
58 | EXPORT_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 | |||
28 | unsigned long generic_io_base; | ||
29 | |||
30 | static inline void delay(void) | ||
31 | { | ||
32 | ctrl_inw(0xa0000000); | ||
33 | } | ||
34 | |||
35 | unsigned char generic_inb(unsigned long port) | ||
36 | { | ||
37 | return *(volatile unsigned char*)PORT2ADDR(port); | ||
38 | } | ||
39 | |||
40 | unsigned short generic_inw(unsigned long port) | ||
41 | { | ||
42 | return *(volatile unsigned short*)PORT2ADDR(port); | ||
43 | } | ||
44 | |||
45 | unsigned int generic_inl(unsigned long port) | ||
46 | { | ||
47 | return *(volatile unsigned long*)PORT2ADDR(port); | ||
48 | } | ||
49 | |||
50 | unsigned 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 | |||
58 | unsigned 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 | |||
66 | unsigned 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 | |||
80 | void 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 | |||
91 | void 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 | |||
105 | void 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 | |||
119 | void generic_outb(unsigned char b, unsigned long port) | ||
120 | { | ||
121 | *(volatile unsigned char*)PORT2ADDR(port) = b; | ||
122 | } | ||
123 | |||
124 | void generic_outw(unsigned short b, unsigned long port) | ||
125 | { | ||
126 | *(volatile unsigned short*)PORT2ADDR(port) = b; | ||
127 | } | ||
128 | |||
129 | void generic_outl(unsigned int b, unsigned long port) | ||
130 | { | ||
131 | *(volatile unsigned long*)PORT2ADDR(port) = b; | ||
132 | } | ||
133 | |||
134 | void generic_outb_p(unsigned char b, unsigned long port) | ||
135 | { | ||
136 | *(volatile unsigned char*)PORT2ADDR(port) = b; | ||
137 | delay(); | ||
138 | } | ||
139 | |||
140 | void generic_outw_p(unsigned short b, unsigned long port) | ||
141 | { | ||
142 | *(volatile unsigned short*)PORT2ADDR(port) = b; | ||
143 | delay(); | ||
144 | } | ||
145 | |||
146 | void 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 | |||
158 | void 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 | |||
169 | void 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 | |||
184 | void 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 | |||
199 | unsigned char generic_readb(unsigned long addr) | ||
200 | { | ||
201 | return *(volatile unsigned char*)addr; | ||
202 | } | ||
203 | |||
204 | unsigned short generic_readw(unsigned long addr) | ||
205 | { | ||
206 | return *(volatile unsigned short*)addr; | ||
207 | } | ||
208 | |||
209 | unsigned int generic_readl(unsigned long addr) | ||
210 | { | ||
211 | return *(volatile unsigned long*)addr; | ||
212 | } | ||
213 | |||
214 | void generic_writeb(unsigned char b, unsigned long addr) | ||
215 | { | ||
216 | *(volatile unsigned char*)addr = b; | ||
217 | } | ||
218 | |||
219 | void generic_writew(unsigned short b, unsigned long addr) | ||
220 | { | ||
221 | *(volatile unsigned short*)addr = b; | ||
222 | } | ||
223 | |||
224 | void generic_writel(unsigned int b, unsigned long addr) | ||
225 | { | ||
226 | *(volatile unsigned long*)addr = b; | ||
227 | } | ||
228 | |||
229 | void * generic_ioremap(unsigned long offset, unsigned long size) | ||
230 | { | ||
231 | return (void *) P2SEGADDR(offset); | ||
232 | } | ||
233 | EXPORT_SYMBOL(generic_ioremap); | ||
234 | |||
235 | void generic_iounmap(void *addr) | ||
236 | { | ||
237 | } | ||
238 | EXPORT_SYMBOL(generic_iounmap); | ||
239 | |||
240 | unsigned 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 | */ | ||
49 | void 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) | ||
55 | int 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'); | ||
82 | unlock: | ||
83 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
84 | } | ||
85 | return 0; | ||
86 | } | ||
87 | #endif | ||
88 | |||
89 | asmlinkage 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, ®s); | ||
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 | |||
3 | ENTRY(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 | |||
17 | ENTRY(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 | ||
31 | 1: 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 */ | ||
116 | kgdb_debug_hook_t *kgdb_debug_hook; | ||
117 | kgdb_bus_error_hook_t *kgdb_bus_err_hook; | ||
118 | |||
119 | int (*kgdb_getchar)(void); | ||
120 | void (*kgdb_putchar)(int); | ||
121 | |||
122 | static void put_debug_char(int c) | ||
123 | { | ||
124 | if (!kgdb_putchar) | ||
125 | return; | ||
126 | (*kgdb_putchar)(c); | ||
127 | } | ||
128 | static 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 | |||
140 | enum 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 | |||
148 | static unsigned int registers[MAXREG]; | ||
149 | struct kgdb_regs trap_registers; | ||
150 | |||
151 | char kgdb_in_gdb_mode; | ||
152 | char in_nmi; /* Set during NMI to prevent reentry */ | ||
153 | int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ | ||
154 | int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ | ||
155 | int kgdb_halt; | ||
156 | |||
157 | /* Exposed for user access */ | ||
158 | struct task_struct *kgdb_current; | ||
159 | unsigned int kgdb_g_imask; | ||
160 | int kgdb_trapa_val; | ||
161 | int 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() */ | ||
187 | int kgdb_portnum = CONFIG_KGDB_DEFPORT; | ||
188 | int kgdb_baud = CONFIG_KGDB_DEFBAUD; | ||
189 | char kgdb_parity = CONFIG_KGDB_DEFPARITY; | ||
190 | char kgdb_bits = CONFIG_KGDB_DEFBITS; | ||
191 | |||
192 | /* Jump buffer for setjmp/longjmp */ | ||
193 | static 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 */ | ||
241 | static int stepped_address; | ||
242 | static short stepped_opcode; | ||
243 | static const char hexchars[] = "0123456789abcdef"; | ||
244 | static char in_buffer[BUFMAX]; | ||
245 | static char out_buffer[OUTBUFMAX]; | ||
246 | |||
247 | static void kgdb_to_gdb(const char *s); | ||
248 | |||
249 | #ifdef CONFIG_KGDB_THREAD | ||
250 | static struct task_struct *trapped_thread; | ||
251 | static struct task_struct *current_thread; | ||
252 | typedef unsigned char threadref[8]; | ||
253 | #define BUF_THREAD_ID_SIZE 16 | ||
254 | #endif | ||
255 | |||
256 | /* Return addr as a real volatile address */ | ||
257 | static inline unsigned int ctrl_inl(const unsigned long addr) | ||
258 | { | ||
259 | return *(volatile unsigned long *) addr; | ||
260 | } | ||
261 | |||
262 | /* Correctly set *addr using volatile */ | ||
263 | static 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 */ | ||
269 | static char highhex(const int x) | ||
270 | { | ||
271 | return hexchars[(x >> 4) & 0xf]; | ||
272 | } | ||
273 | |||
274 | /* Get low hex bits */ | ||
275 | static char lowhex(const int x) | ||
276 | { | ||
277 | return hexchars[x & 0xf]; | ||
278 | } | ||
279 | |||
280 | /* Convert ch to hex */ | ||
281 | static 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) */ | ||
294 | static 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 */ | ||
320 | static 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 */ | ||
334 | static 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. */ | ||
356 | static 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 */ | ||
368 | static 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 */ | ||
378 | static 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 */ | ||
392 | static 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 */ | ||
407 | static 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 */ | ||
436 | static 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 */ | ||
496 | static 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 */ | ||
540 | static 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 */ | ||
546 | static 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) */ | ||
580 | static 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 */ | ||
609 | static 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 */ | ||
639 | asmlinkage void ret_from_fork(void); | ||
640 | static 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 */ | ||
706 | static 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. */ | ||
791 | static 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 */ | ||
809 | static 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 */ | ||
821 | static 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 */ | ||
857 | static void send_ok_msg(void) | ||
858 | { | ||
859 | strcpy(out_buffer, "OK"); | ||
860 | put_packet(out_buffer); | ||
861 | } | ||
862 | |||
863 | /* Reply that an error occurred */ | ||
864 | static void send_err_msg(void) | ||
865 | { | ||
866 | strcpy(out_buffer, "E01"); | ||
867 | put_packet(out_buffer); | ||
868 | } | ||
869 | |||
870 | /* Empty message indicates unrecognised command */ | ||
871 | static void send_empty_msg(void) | ||
872 | { | ||
873 | put_packet(""); | ||
874 | } | ||
875 | |||
876 | /* Read memory due to 'm' message */ | ||
877 | static 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 */ | ||
909 | static 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 */ | ||
941 | static 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 */ | ||
952 | static 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 */ | ||
972 | static void step_msg(void) | ||
973 | { | ||
974 | continue_msg(); | ||
975 | do_single_step(); | ||
976 | } | ||
977 | |||
978 | /* Step message with signal */ | ||
979 | static void step_with_sig_msg(void) | ||
980 | { | ||
981 | continue_with_sig_msg(); | ||
982 | do_single_step(); | ||
983 | } | ||
984 | |||
985 | /* Send register contents */ | ||
986 | static 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 */ | ||
1002 | static 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 */ | ||
1021 | void 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? */ | ||
1062 | static 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 */ | ||
1077 | static 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 */ | ||
1105 | static 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 */ | ||
1138 | static 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. */ | ||
1172 | static 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 | */ | ||
1202 | static 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 */ | ||
1213 | static 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. */ | ||
1349 | void 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 */ | ||
1399 | void 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 */ | ||
1409 | int 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 | |||
1444 | char gdbmsgbuf[BUFMAX]; | ||
1445 | #define MAXOUT ((BUFMAX-2)/2) | ||
1446 | |||
1447 | static 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 | |||
1477 | static void kgdb_to_gdb(const char *s) | ||
1478 | { | ||
1479 | kgdb_msg_write(s, strlen(s)); | ||
1480 | } | ||
1481 | |||
1482 | #ifdef CONFIG_SH_KGDB_CONSOLE | ||
1483 | void 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 | |||
30 | void *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 */ | ||
39 | void 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. */ | ||
47 | int 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 | |||
78 | int 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 | |||
126 | int 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 | |||
137 | int module_finalize(const Elf_Ehdr *hdr, | ||
138 | const Elf_Shdr *sechdrs, | ||
139 | struct module *me) | ||
140 | { | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | void 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 | |||
34 | static int hlt_counter=0; | ||
35 | |||
36 | int ubc_usercnt = 0; | ||
37 | |||
38 | #define HARD_IDLE_TIMEOUT (HZ / 3) | ||
39 | |||
40 | void disable_hlt(void) | ||
41 | { | ||
42 | hlt_counter++; | ||
43 | } | ||
44 | |||
45 | EXPORT_SYMBOL(disable_hlt); | ||
46 | |||
47 | void enable_hlt(void) | ||
48 | { | ||
49 | hlt_counter--; | ||
50 | } | ||
51 | |||
52 | EXPORT_SYMBOL(enable_hlt); | ||
53 | |||
54 | void 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 | |||
71 | void cpu_idle(void) | ||
72 | { | ||
73 | default_idle(); | ||
74 | } | ||
75 | |||
76 | void 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 | |||
83 | EXPORT_SYMBOL(machine_restart); | ||
84 | |||
85 | void 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 | |||
99 | EXPORT_SYMBOL(machine_halt); | ||
100 | |||
101 | void 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 | |||
113 | EXPORT_SYMBOL(machine_power_off); | ||
114 | |||
115 | void 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 | */ | ||
163 | extern 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 | |||
174 | int 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(®s, 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, ®s, 0, NULL, NULL); | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Free current thread data structures etc.. | ||
191 | */ | ||
192 | void exit_thread(void) | ||
193 | { | ||
194 | if (current->thread.ubc_pc) { | ||
195 | current->thread.ubc_pc = 0; | ||
196 | ubc_usercnt -= 1; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | void 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 | |||
215 | void release_thread(struct task_struct *dead_task) | ||
216 | { | ||
217 | /* do nothing */ | ||
218 | } | ||
219 | |||
220 | /* Fill in the fpu structure for a core dump.. */ | ||
221 | int 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 | */ | ||
241 | int 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 | |||
257 | int | ||
258 | dump_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 | |||
277 | asmlinkage void ret_from_fork(void); | ||
278 | |||
279 | int 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 | */ | ||
321 | void 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. */ | ||
339 | static void | ||
340 | ubc_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 | */ | ||
363 | struct 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 | |||
423 | asmlinkage 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], ®s, 0, NULL, NULL); | ||
429 | #else | ||
430 | /* fork almost works, enough to trick you into looking elsewhere :-( */ | ||
431 | return -EINVAL; | ||
432 | #endif | ||
433 | } | ||
434 | |||
435 | asmlinkage 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, ®s, 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 | */ | ||
456 | asmlinkage 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], ®s, | ||
461 | 0, NULL, NULL); | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * sys_execve() executes a new program. | ||
466 | */ | ||
467 | asmlinkage 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 | ®s); | ||
483 | if (error == 0) { | ||
484 | task_lock(current); | ||
485 | current->ptrace &= ~PT_DTRACE; | ||
486 | task_unlock(current); | ||
487 | } | ||
488 | putname(filename); | ||
489 | out: | ||
490 | return error; | ||
491 | } | ||
492 | |||
493 | unsigned 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 | |||
512 | asmlinkage 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 | |||
525 | asmlinkage 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 | */ | ||
39 | static 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 | */ | ||
56 | static 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 | */ | ||
77 | void ptrace_disable(struct task_struct *child) | ||
78 | { | ||
79 | /* nothing to do.. */ | ||
80 | } | ||
81 | |||
82 | asmlinkage 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 | } | ||
291 | out_tsk: | ||
292 | put_task_struct(child); | ||
293 | out: | ||
294 | unlock_kernel(); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | asmlinkage 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 | |||
17 | spinlock_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 | */ | ||
49 | void __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 | |||
107 | void __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 | |||
117 | int __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 | |||
136 | int __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> | ||
32 | static int kgdb_parse_options(char *options); | ||
33 | #endif | ||
34 | extern 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 | */ | ||
44 | struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 10000000, }; | ||
45 | struct screen_info screen_info; | ||
46 | |||
47 | #if defined(CONFIG_SH_UNKNOWN) | ||
48 | struct sh_machine_vector sh_mv; | ||
49 | #endif | ||
50 | |||
51 | /* We need this to satisfy some external references. */ | ||
52 | struct 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 | |||
64 | extern void platform_setup(void); | ||
65 | extern char *get_system_type(void); | ||
66 | extern int root_mountflags; | ||
67 | |||
68 | #define MV_NAME_SIZE 32 | ||
69 | |||
70 | static 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 | |||
90 | static char command_line[COMMAND_LINE_SIZE] = { 0, }; | ||
91 | |||
92 | struct 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]) | ||
108 | static 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 | |||
116 | unsigned long memory_start, memory_end; | ||
117 | |||
118 | static 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 | |||
187 | static 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 | |||
247 | void __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 | |||
396 | struct 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 | |||
418 | static struct cpu cpu[NR_CPUS]; | ||
419 | |||
420 | static 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 | |||
431 | subsys_initcall(topology_init); | ||
432 | |||
433 | static 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 | |||
453 | const char *get_cpu_subtype(void) | ||
454 | { | ||
455 | return cpu_name[boot_cpu_data.type]; | ||
456 | } | ||
457 | |||
458 | #ifdef CONFIG_PROC_FS | ||
459 | static const char *cpu_flags[] = { | ||
460 | "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", | ||
461 | }; | ||
462 | |||
463 | static 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 | |||
481 | static 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 | */ | ||
493 | static 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 | |||
541 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
542 | { | ||
543 | return *pos < NR_CPUS ? cpu_data + *pos : NULL; | ||
544 | } | ||
545 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
546 | { | ||
547 | ++*pos; | ||
548 | return c_start(m, pos); | ||
549 | } | ||
550 | static void c_stop(struct seq_file *m, void *v) | ||
551 | { | ||
552 | } | ||
553 | struct 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 | */ | ||
568 | struct kgdb_sermap kgdb_sci_sermap = | ||
569 | { "ttySC", 5, kgdb_sci_setup, NULL }; | ||
570 | |||
571 | struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap; | ||
572 | struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap; | ||
573 | |||
574 | void 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 | |||
586 | static 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 | |||
19 | static __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 | |||
34 | void 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 | |||
40 | void sh_bios_char_out(char ch) | ||
41 | { | ||
42 | sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0); | ||
43 | } | ||
44 | |||
45 | |||
46 | int 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 | |||
62 | void sh_bios_gdb_detach(void) | ||
63 | { | ||
64 | sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); | ||
65 | } | ||
66 | |||
67 | void 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 | |||
72 | void 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 | |||
24 | extern void dump_thread(struct pt_regs *, struct user *); | ||
25 | extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); | ||
26 | extern struct hw_interrupt_type no_irq_type; | ||
27 | |||
28 | EXPORT_SYMBOL(sh_mv); | ||
29 | |||
30 | /* platform dependent support */ | ||
31 | EXPORT_SYMBOL(dump_thread); | ||
32 | EXPORT_SYMBOL(dump_fpu); | ||
33 | EXPORT_SYMBOL(iounmap); | ||
34 | EXPORT_SYMBOL(enable_irq); | ||
35 | EXPORT_SYMBOL(disable_irq); | ||
36 | EXPORT_SYMBOL(probe_irq_mask); | ||
37 | EXPORT_SYMBOL(kernel_thread); | ||
38 | EXPORT_SYMBOL(disable_irq_nosync); | ||
39 | EXPORT_SYMBOL(irq_desc); | ||
40 | EXPORT_SYMBOL(no_irq_type); | ||
41 | |||
42 | EXPORT_SYMBOL(strpbrk); | ||
43 | EXPORT_SYMBOL(strstr); | ||
44 | EXPORT_SYMBOL(strlen); | ||
45 | EXPORT_SYMBOL(strnlen); | ||
46 | EXPORT_SYMBOL(strchr); | ||
47 | EXPORT_SYMBOL(strcat); | ||
48 | EXPORT_SYMBOL(strncat); | ||
49 | |||
50 | /* PCI exports */ | ||
51 | #ifdef CONFIG_PCI | ||
52 | EXPORT_SYMBOL(pci_alloc_consistent); | ||
53 | EXPORT_SYMBOL(pci_free_consistent); | ||
54 | #endif | ||
55 | |||
56 | /* mem exports */ | ||
57 | EXPORT_SYMBOL(memchr); | ||
58 | EXPORT_SYMBOL(memcpy); | ||
59 | EXPORT_SYMBOL(memcpy_fromio); | ||
60 | EXPORT_SYMBOL(memcpy_toio); | ||
61 | EXPORT_SYMBOL(memset); | ||
62 | EXPORT_SYMBOL(memset_io); | ||
63 | EXPORT_SYMBOL(memmove); | ||
64 | EXPORT_SYMBOL(memcmp); | ||
65 | EXPORT_SYMBOL(memscan); | ||
66 | EXPORT_SYMBOL(__copy_user); | ||
67 | EXPORT_SYMBOL(boot_cpu_data); | ||
68 | |||
69 | #ifdef CONFIG_MMU | ||
70 | EXPORT_SYMBOL(get_vm_area); | ||
71 | #endif | ||
72 | |||
73 | /* semaphore exports */ | ||
74 | EXPORT_SYMBOL(__up); | ||
75 | EXPORT_SYMBOL(__down); | ||
76 | EXPORT_SYMBOL(__down_interruptible); | ||
77 | |||
78 | EXPORT_SYMBOL(__udelay); | ||
79 | EXPORT_SYMBOL(__ndelay); | ||
80 | EXPORT_SYMBOL(__const_udelay); | ||
81 | |||
82 | EXPORT_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 */ | ||
87 | DECLARE_EXPORT(__udivsi3); | ||
88 | DECLARE_EXPORT(__udivdi3); | ||
89 | DECLARE_EXPORT(__sdivsi3); | ||
90 | DECLARE_EXPORT(__ashrdi3); | ||
91 | DECLARE_EXPORT(__ashldi3); | ||
92 | DECLARE_EXPORT(__lshrdi3); | ||
93 | DECLARE_EXPORT(__movstr); | ||
94 | |||
95 | EXPORT_SYMBOL(strcpy); | ||
96 | |||
97 | #ifdef CONFIG_CPU_SH4 | ||
98 | DECLARE_EXPORT(__movstr_i4_even); | ||
99 | DECLARE_EXPORT(__movstr_i4_odd); | ||
100 | DECLARE_EXPORT(__movstrSI12_i4); | ||
101 | |||
102 | /* needed by some modules */ | ||
103 | EXPORT_SYMBOL(flush_cache_all); | ||
104 | EXPORT_SYMBOL(flush_cache_range); | ||
105 | EXPORT_SYMBOL(flush_dcache_page); | ||
106 | EXPORT_SYMBOL(__flush_purge_region); | ||
107 | #endif | ||
108 | |||
109 | #if defined(CONFIG_SH7705_CACHE_32KB) | ||
110 | EXPORT_SYMBOL(flush_cache_all); | ||
111 | EXPORT_SYMBOL(flush_cache_range); | ||
112 | EXPORT_SYMBOL(flush_dcache_page); | ||
113 | EXPORT_SYMBOL(__flush_purge_region); | ||
114 | #endif | ||
115 | |||
116 | EXPORT_SYMBOL(flush_tlb_page); | ||
117 | EXPORT_SYMBOL(__down_trylock); | ||
118 | |||
119 | #ifdef CONFIG_SMP | ||
120 | EXPORT_SYMBOL(synchronize_irq); | ||
121 | #endif | ||
122 | |||
123 | EXPORT_SYMBOL(csum_partial); | ||
124 | EXPORT_SYMBOL(csum_ipv6_magic); | ||
125 | EXPORT_SYMBOL(consistent_sync); | ||
126 | EXPORT_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 | |||
36 | asmlinkage 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 | */ | ||
41 | asmlinkage int | ||
42 | sys_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(¤t->sighand->siglock); | ||
50 | saveset = current->blocked; | ||
51 | siginitset(¤t->blocked, mask); | ||
52 | recalc_sigpending(); | ||
53 | spin_unlock_irq(¤t->sighand->siglock); | ||
54 | |||
55 | regs.regs[0] = -EINTR; | ||
56 | while (1) { | ||
57 | current->state = TASK_INTERRUPTIBLE; | ||
58 | schedule(); | ||
59 | if (do_signal(®s, &saveset)) | ||
60 | return -EINTR; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | asmlinkage int | ||
65 | sys_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(¤t->sighand->siglock); | ||
79 | saveset = current->blocked; | ||
80 | current->blocked = newset; | ||
81 | recalc_sigpending(); | ||
82 | spin_unlock_irq(¤t->sighand->siglock); | ||
83 | |||
84 | regs.regs[0] = -EINTR; | ||
85 | while (1) { | ||
86 | current->state = TASK_INTERRUPTIBLE; | ||
87 | schedule(); | ||
88 | if (do_signal(®s, &saveset)) | ||
89 | return -EINTR; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | asmlinkage int | ||
94 | sys_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 | |||
125 | asmlinkage int | ||
126 | sys_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 | |||
142 | struct sigframe | ||
143 | { | ||
144 | struct sigcontext sc; | ||
145 | unsigned long extramask[_NSIG_WORDS-1]; | ||
146 | u16 retcode[8]; | ||
147 | }; | ||
148 | |||
149 | struct rt_sigframe | ||
150 | { | ||
151 | struct siginfo info; | ||
152 | struct ucontext uc; | ||
153 | u16 retcode[8]; | ||
154 | }; | ||
155 | |||
156 | #ifdef CONFIG_SH_FPU | ||
157 | static 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 | |||
169 | static 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 | |||
195 | static int | ||
196 | restore_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 | |||
233 | asmlinkage 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(¤t->sighand->siglock); | ||
253 | current->blocked = set; | ||
254 | recalc_sigpending(); | ||
255 | spin_unlock_irq(¤t->sighand->siglock); | ||
256 | |||
257 | if (restore_sigcontext(®s, &frame->sc, &r0)) | ||
258 | goto badframe; | ||
259 | return r0; | ||
260 | |||
261 | badframe: | ||
262 | force_sig(SIGSEGV, current); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | asmlinkage 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(¤t->sighand->siglock); | ||
283 | current->blocked = set; | ||
284 | recalc_sigpending(); | ||
285 | spin_unlock_irq(¤t->sighand->siglock); | ||
286 | |||
287 | if (restore_sigcontext(®s, &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 | |||
298 | badframe: | ||
299 | force_sig(SIGSEGV, current); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | /* | ||
304 | * Set up a signal frame. | ||
305 | */ | ||
306 | |||
307 | static int | ||
308 | setup_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 | */ | ||
340 | static inline void __user * | ||
341 | get_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 | |||
351 | static 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 | |||
415 | give_sigsegv: | ||
416 | force_sigsegv(sig, current); | ||
417 | } | ||
418 | |||
419 | static 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 | |||
490 | give_sigsegv: | ||
491 | force_sigsegv(sig, current); | ||
492 | } | ||
493 | |||
494 | /* | ||
495 | * OK, we're invoking a handler | ||
496 | */ | ||
497 | |||
498 | static void | ||
499 | handle_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(¤t->sighand->siglock); | ||
551 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
552 | sigaddset(¤t->blocked,sig); | ||
553 | recalc_sigpending(); | ||
554 | spin_unlock_irq(¤t->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 | */ | ||
567 | int 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 = ¤t->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 | */ | ||
37 | struct sh_cpuinfo cpu_data[NR_CPUS]; | ||
38 | |||
39 | extern void per_cpu_trap_init(void); | ||
40 | |||
41 | cpumask_t cpu_possible_map; | ||
42 | cpumask_t cpu_online_map; | ||
43 | static 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 | */ | ||
52 | void __smp_send_ipi(unsigned int cpu, unsigned int action); | ||
53 | |||
54 | /* | ||
55 | * Find the number of available processors | ||
56 | */ | ||
57 | unsigned int __smp_probe_cpus(void); | ||
58 | |||
59 | /* | ||
60 | * Start a particular processor | ||
61 | */ | ||
62 | void __smp_slave_init(unsigned int cpu); | ||
63 | |||
64 | /* | ||
65 | * Run specified function on a particular processor. | ||
66 | */ | ||
67 | void __smp_call_function(unsigned int cpu); | ||
68 | |||
69 | static inline void __init smp_store_cpu_info(unsigned int cpu) | ||
70 | { | ||
71 | cpu_data[cpu].loops_per_jiffy = loops_per_jiffy; | ||
72 | } | ||
73 | |||
74 | void __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 | |||
86 | void __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 | |||
94 | int __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 | |||
110 | int 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 | |||
128 | void __init smp_cpus_done(unsigned int max_cpus) | ||
129 | { | ||
130 | smp_mb(); | ||
131 | } | ||
132 | |||
133 | void smp_send_reschedule(int cpu) | ||
134 | { | ||
135 | __smp_send_ipi(cpu, SMP_MSG_RESCHEDULE); | ||
136 | } | ||
137 | |||
138 | static 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 | |||
147 | void smp_send_stop(void) | ||
148 | { | ||
149 | smp_call_function(stop_this_cpu, 0, 1, 0); | ||
150 | } | ||
151 | |||
152 | |||
153 | struct 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 | */ | ||
165 | int 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 ... */ | ||
195 | int 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 | */ | ||
32 | asmlinkage 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 | |||
53 | unsigned 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 | |||
88 | full_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 | |||
116 | static inline long | ||
117 | do_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(¤t->mm->mmap_sem); | ||
131 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
132 | up_write(¤t->mm->mmap_sem); | ||
133 | |||
134 | if (file) | ||
135 | fput(file); | ||
136 | out: | ||
137 | return error; | ||
138 | } | ||
139 | |||
140 | asmlinkage 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 | |||
149 | asmlinkage 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 | */ | ||
161 | asmlinkage 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 | |||
256 | asmlinkage 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 | |||
267 | asmlinkage 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 | |||
273 | asmlinkage 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 | |||
279 | asmlinkage 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 | |||
55 | extern unsigned long wall_jiffies; | ||
56 | #define TICK_SIZE (tick_nsec / 1000) | ||
57 | DEFINE_SPINLOCK(tmu0_lock); | ||
58 | |||
59 | u64 jiffies_64 = INITIAL_JIFFIES; | ||
60 | |||
61 | EXPORT_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 | ||
66 | void (*rtc_get_time)(struct timespec *) = sh_rtc_gettimeofday; | ||
67 | int (*rtc_set_time)(const time_t) = sh_rtc_settimeofday; | ||
68 | #else | ||
69 | void (*rtc_get_time)(struct timespec *); | ||
70 | int (*rtc_set_time)(const time_t); | ||
71 | #endif | ||
72 | |||
73 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
74 | static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; | ||
75 | #endif | ||
76 | #if defined(CONFIG_CPU_SH3) | ||
77 | static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
78 | static int stc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; | ||
79 | #define bfc_divisors stc_multipliers | ||
80 | #define bfc_values stc_values | ||
81 | static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; | ||
82 | static int ifc_values[] = { 0, 1, 4, 2, 0, 0, 0, 0 }; | ||
83 | static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
84 | static int pfc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; | ||
85 | #elif defined(CONFIG_CPU_SH4) | ||
86 | #if defined(CONFIG_CPU_SUBTYPE_SH73180) | ||
87 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; | ||
88 | static 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 | ||
94 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; | ||
95 | static int ifc_values[] = { 0, 1, 2, 3, 0, 4, 0, 5 }; | ||
96 | #define bfc_divisors ifc_divisors /* Same */ | ||
97 | #define bfc_values ifc_values | ||
98 | static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; | ||
99 | static 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 | */ | ||
108 | unsigned long long sched_clock(void) | ||
109 | { | ||
110 | return (unsigned long long)jiffies * (1000000000 / HZ); | ||
111 | } | ||
112 | |||
113 | static 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 | |||
165 | void 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 | |||
192 | EXPORT_SYMBOL(do_gettimeofday); | ||
193 | |||
194 | int 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 | |||
228 | EXPORT_SYMBOL(do_settimeofday); | ||
229 | |||
230 | /* last time the RTC clock got updated */ | ||
231 | static 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 | */ | ||
237 | static 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 | */ | ||
271 | static 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 | */ | ||
297 | static 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 | |||
348 | void (*board_time_init)(void); | ||
349 | void (*board_timer_setup)(struct irqaction *irq); | ||
350 | |||
351 | static unsigned int sh_pclk_freq __initdata = CONFIG_SH_PCLK_FREQ; | ||
352 | |||
353 | static 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 | |||
364 | static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; | ||
365 | |||
366 | void 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 | |||
434 | struct frqcr_data { | ||
435 | unsigned short frqcr; | ||
436 | |||
437 | struct { | ||
438 | unsigned char multiplier; | ||
439 | unsigned char divisor; | ||
440 | } factor[3]; | ||
441 | }; | ||
442 | |||
443 | static 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 | |||
473 | struct memclk_data { | ||
474 | unsigned char multiplier; | ||
475 | unsigned char divisor; | ||
476 | }; | ||
477 | |||
478 | static 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 | |||
489 | static 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 | |||
538 | void __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) \ | ||
52 | asmlinkage 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(®s)) { \ | ||
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(®s); \ | ||
70 | force_sig(signr, tsk); \ | ||
71 | die_if_no_fixup(str,®s,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 | |||
90 | spinlock_t die_lock; | ||
91 | |||
92 | void 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 | |||
105 | static 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 | |||
111 | static 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 | */ | ||
120 | static 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 | */ | ||
142 | static 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 = ®s->regs[index]; | ||
150 | |||
151 | index = (instruction>>4)&15; /* 0x00F0 */ | ||
152 | rm = ®s->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*) ®s->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*) ®s->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 | */ | ||
320 | static 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 | |||
352 | static 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 | */ | ||
492 | asmlinkage 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 | */ | ||
554 | int 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 | |||
579 | DO_ERROR(TRAP_RESERVED_INST, SIGILL, "reserved instruction", reserved_inst, current) | ||
580 | DO_ERROR(TRAP_ILLEGAL_SLOT_INST, SIGILL, "illegal slot instruction", illegal_slot_inst, current) | ||
581 | |||
582 | asmlinkage 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", ®s, ex); | ||
589 | } | ||
590 | |||
591 | #if defined(CONFIG_SH_STANDARD_BIOS) | ||
592 | void *gdb_vbr_vector; | ||
593 | |||
594 | static 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 | |||
611 | void __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 | |||
629 | void __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 | |||
652 | void 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 | |||
703 | void show_task(unsigned long *sp) | ||
704 | { | ||
705 | show_stack(NULL, sp); | ||
706 | } | ||
707 | |||
708 | void dump_stack(void) | ||
709 | { | ||
710 | show_stack(NULL, NULL); | ||
711 | } | ||
712 | EXPORT_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 | ||
9 | OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") | ||
10 | #else | ||
11 | OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") | ||
12 | #endif | ||
13 | OUTPUT_ARCH(sh) | ||
14 | ENTRY(_start) | ||
15 | SECTIONS | ||
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 | |||
5 | lib-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 | |||
9 | memcpy-y := memcpy.o | ||
10 | memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o | ||
11 | |||
12 | lib-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 | ||
44 | ENTRY(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. | ||
63 | 1: | ||
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 | ||
70 | 2: | ||
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 | ||
77 | 3: | ||
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 | ||
100 | 4: | ||
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 | ||
108 | 5: | ||
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 | ||
117 | 6: | ||
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 | ||
133 | 7: | ||
134 | mov.b @r4+, r0 | ||
135 | extu.b r0, r0 | ||
136 | #ifndef __LITTLE_ENDIAN__ | ||
137 | shll8 r0 | ||
138 | #endif | ||
139 | 8: | ||
140 | addc r0, r6 | ||
141 | mov #0, r0 | ||
142 | addc r0, r6 | ||
143 | 9: | ||
144 | rts | ||
145 | mov r6, r0 | ||
146 | |||
147 | /* | ||
148 | unsigned 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 | ! | ||
185 | ENTRY(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 | |||
208 | 3: ! 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 | ||
216 | 5: | ||
217 | SRC( mov.b @r4+,r1 ) | ||
218 | SRC( mov.b @r4+,r0 ) | ||
219 | extu.b r1,r1 | ||
220 | DST( mov.b r1,@r5 ) | ||
221 | DST( 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 | ||
249 | 1: | ||
250 | SRC( mov.w @r4+,r0 ) | ||
251 | DST( 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 | ||
257 | 2: | ||
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 | ||
265 | 1: | ||
266 | SRC( mov.l @r4+,r0 ) | ||
267 | SRC( mov.l @r4+,r1 ) | ||
268 | addc r0,r7 | ||
269 | DST( mov.l r0,@r5 ) | ||
270 | DST( mov.l r1,@(4,r5) ) | ||
271 | addc r1,r7 | ||
272 | |||
273 | SRC( mov.l @r4+,r0 ) | ||
274 | SRC( mov.l @r4+,r1 ) | ||
275 | addc r0,r7 | ||
276 | DST( mov.l r0,@(8,r5) ) | ||
277 | DST( mov.l r1,@(12,r5) ) | ||
278 | addc r1,r7 | ||
279 | |||
280 | SRC( mov.l @r4+,r0 ) | ||
281 | SRC( mov.l @r4+,r1 ) | ||
282 | addc r0,r7 | ||
283 | DST( mov.l r0,@(16,r5) ) | ||
284 | DST( mov.l r1,@(20,r5) ) | ||
285 | addc r1,r7 | ||
286 | |||
287 | SRC( mov.l @r4+,r0 ) | ||
288 | SRC( mov.l @r4+,r1 ) | ||
289 | addc r0,r7 | ||
290 | DST( mov.l r0,@(24,r5) ) | ||
291 | DST( 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 | |||
301 | 2: mov r2,r6 | ||
302 | mov #0x1c,r0 | ||
303 | and r0,r6 | ||
304 | cmp/pl r6 | ||
305 | bf/s 4f | ||
306 | clrt | ||
307 | shlr2 r6 | ||
308 | 3: | ||
309 | SRC( mov.l @r4+,r0 ) | ||
310 | addc r0,r7 | ||
311 | DST( 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 | ||
319 | 4: 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 | ||
327 | SRC( mov.w @r4+,r0 ) | ||
328 | DST( 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 | ||
336 | 5: | ||
337 | SRC( mov.b @r4+,r0 ) | ||
338 | DST( mov.b r0,@r5 ) | ||
339 | extu.b r0,r0 | ||
340 | #ifndef __LITTLE_ENDIAN__ | ||
341 | shll8 r0 | ||
342 | #endif | ||
343 | 6: addc r0,r7 | ||
344 | mov #0,r0 | ||
345 | addc r0,r7 | ||
346 | 7: | ||
347 | 5000: | ||
348 | |||
349 | # Exception handler: | ||
350 | .section .fixup, "ax" | ||
351 | |||
352 | 6001: | ||
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 | ||
362 | 1: 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 | ||
370 | 8000: .long 5000b | ||
371 | |||
372 | 6002: | ||
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 | ||
380 | 8001: .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 | |||
10 | void __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 | |||
22 | inline 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 | |||
32 | void __udelay(unsigned long usecs) | ||
33 | { | ||
34 | __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ | ||
35 | } | ||
36 | |||
37 | void __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 | |||
7 | extern u64 __xdiv64_32(u64 n, u32 d); | ||
8 | |||
9 | u64 __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 | ||
8 | ENTRY(__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 | ||
31 | 1: | ||
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> | ||
14 | ENTRY(memchr) | ||
15 | tst r6,r6 | ||
16 | bt/s 2f | ||
17 | exts.b r5,r5 | ||
18 | 1: mov.b @r4,r1 | ||
19 | cmp/eq r1,r5 | ||
20 | bt/s 3f | ||
21 | dt r6 | ||
22 | bf/s 1b | ||
23 | add #1,r4 | ||
24 | 2: mov #0,r4 | ||
25 | 3: 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 | ||
40 | 3: 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 | ||
57 | 3: 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 | |||
82 | 8: 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 | |||
89 | 9: 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 | ||
113 | 3: 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 | ||
130 | 3: 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 | |||
150 | 8: 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 | |||
157 | 9: rts | ||
158 | nop | ||
159 | |||
160 | ENTRY(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 | ||
223 | 3: mov.b @(r0,r5),r1 ! 20 LS (latency=2) | ||
224 | |||
225 | 4: 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 | ||
232 | 98: | ||
233 | rts | ||
234 | nop | ||
235 | |||
236 | 99: 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 | |||
244 | 6: 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 | ||
251 | 1: 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 | |||
259 | 2: 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 | ||
287 | 2: bt/s .Lcase0b | ||
288 | mov r3, r0 | ||
289 | |||
290 | bra .Lcase2b | ||
291 | nop | ||
292 | |||
293 | ! bit 0 set | ||
294 | 1: 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 | ||
333 | 3: mov.l @(r0, r5), r1 ! 21 LS (latency=2) | ||
334 | |||
335 | 4: 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 | |||
343 | 5: 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 | ||
367 | 3: mov.l @(r0, r5), r1 ! 21 LS (latency=2) | ||
368 | |||
369 | 4: 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 | ||
387 | 1: 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 | |||
393 | 9: 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 | ||
435 | 3: mov.l @(r0, r5), r1 ! 21 LS (latency=2) | ||
436 | |||
437 | 4: 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 | ! | ||
460 | 1: 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 | ||
472 | 2: 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 | ||
509 | 1: 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 | ||
539 | 3: mov.l @(r0, r5), r6 ! 21 LS (latency=2) | ||
540 | |||
541 | 4: 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 | |||
551 | 5: 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 | ||
558 | 1: 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 | |||
564 | 9: 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 | |||
575 | 2: 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 | ||
582 | 3: 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 | |||
623 | 2: 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 | ! | ||
645 | 1: 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 | ||
660 | 2: 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 | ||
707 | 2: 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 | ||
770 | 1: 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 | ||
776 | 10: 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 | |||
784 | 3: 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 | ||
790 | 1: | ||
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> | ||
15 | ENTRY(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 | ||
45 | jmptable: | ||
46 | .long case0 | ||
47 | .long case1 | ||
48 | .long case2 | ||
49 | .long case3 | ||
50 | |||
51 | ! copy a byte at once | ||
52 | 7: mov r4,r2 | ||
53 | add #1,r2 | ||
54 | 8: | ||
55 | cmp/hi r2,r0 | ||
56 | mov.b @(r0,r5),r1 | ||
57 | bt/s 8b ! while (r0>r2) | ||
58 | mov.b r1,@-r0 | ||
59 | 9: | ||
60 | rts | ||
61 | nop | ||
62 | |||
63 | case0: | ||
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 | ||
74 | 1: dt r3 | ||
75 | mov.b @(r0,r5),r1 | ||
76 | bf/s 1b | ||
77 | mov.b r1,@-r0 | ||
78 | ! | ||
79 | add #-3,r5 | ||
80 | 2: ! Second, copy a long word at once | ||
81 | mov r4,r2 | ||
82 | add #7,r2 | ||
83 | 3: 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 | |||
95 | case1: | ||
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 | ||
105 | 1: dt r3 | ||
106 | mov.b @(r0,r5),r1 | ||
107 | bf/s 1b | ||
108 | mov.b r1,@-r0 | ||
109 | ! | ||
110 | 2: ! 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__ | ||
117 | 3: 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 | ||
128 | 3: 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 | |||
147 | case2: | ||
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 | ! | ||
158 | 2: ! Second, read a word and write a word at once | ||
159 | add #-1,r5 | ||
160 | mov r4,r2 | ||
161 | add #3,r2 | ||
162 | ! | ||
163 | 3: 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 | |||
176 | case3: | ||
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 | ||
186 | 1: dt r3 | ||
187 | mov.b @(r0,r5),r1 | ||
188 | bf/s 1b | ||
189 | mov.b r1,@-r0 | ||
190 | ! | ||
191 | 2: ! 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__ | ||
199 | 3: 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 | ||
210 | 3: 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> | ||
15 | ENTRY(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 | ||
23 | 2: .long memcpy | ||
24 | 1: | ||
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 | ||
55 | jmptable: | ||
56 | .long case0 | ||
57 | .long case1 | ||
58 | .long case2 | ||
59 | .long case3 | ||
60 | |||
61 | ! copy a byte at once | ||
62 | 8: 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 | ||
67 | 9: | ||
68 | add r4,r0 | ||
69 | rts | ||
70 | sub r6,r0 | ||
71 | |||
72 | case_none: | ||
73 | bra 8b | ||
74 | add #-1,r4 | ||
75 | |||
76 | case0: | ||
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 | ||
88 | 1: dt r2 | ||
89 | mov.b @r0+,r1 | ||
90 | bf/s 1b | ||
91 | mov.b r1,@(r0,r4) | ||
92 | ! | ||
93 | 2: ! Second, copy a long word at once | ||
94 | add #-3,r4 | ||
95 | add #-3,r5 | ||
96 | 3: 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 | |||
109 | case3: | ||
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 | ||
121 | 1: dt r2 | ||
122 | mov.b @r0+,r1 | ||
123 | bf/s 1b | ||
124 | mov.b r1,@(r0,r4) | ||
125 | ! | ||
126 | 2: ! 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 | ||
134 | 3: 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 | ||
146 | 3: 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 | |||
167 | case2: | ||
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 | ! | ||
178 | 2: ! Second, read a word and write a word at once | ||
179 | add #-1,r4 | ||
180 | add #-1,r5 | ||
181 | ! | ||
182 | 3: 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 | |||
197 | case1: | ||
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 | ||
209 | 1: dt r2 | ||
210 | mov.b @r0+,r1 | ||
211 | bf/s 1b | ||
212 | mov.b r1,@(r0,r4) | ||
213 | ! | ||
214 | 2: ! 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 | ||
222 | 3: 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 | ||
235 | 3: 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 | |||
15 | ENTRY(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 | ||
27 | 1: | ||
28 | dt r0 | ||
29 | bf/s 1b | ||
30 | mov.b r5,@-r4 | ||
31 | 2: ! 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 | ||
40 | 3: | ||
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 | ||
51 | 4: | ||
52 | dt r6 | ||
53 | bf/s 4b | ||
54 | mov.b r5,@-r4 | ||
55 | 5: | ||
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 | |||
12 | int 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> | ||
12 | ENTRY(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 | |||
40 | 1: | ||
41 | mov #0,r3 | ||
42 | 2: | ||
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 | ||
68 | 8: | ||
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 | |||
7 | extern u64 __xdiv64_32(u64 n, u32 d); | ||
8 | extern void panic(const char * fmt, ...); | ||
9 | |||
10 | u64 __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 | |||
5 | obj-y := init.o extable.o consistent.o | ||
6 | |||
7 | obj-$(CONFIG_CPU_SH2) += cache-sh2.o | ||
8 | obj-$(CONFIG_CPU_SH3) += cache-sh3.o | ||
9 | obj-$(CONFIG_CPU_SH4) += cache-sh4.o pg-sh4.o | ||
10 | |||
11 | obj-$(CONFIG_DMA_PAGE_OPS) += pg-dma.o | ||
12 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | ||
13 | |||
14 | mmu-y := fault-nommu.o tlb-nommu.o pg-nommu.o | ||
15 | mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o | ||
16 | |||
17 | obj-y += $(mmu-y) | ||
18 | |||
19 | ifdef CONFIG_MMU | ||
20 | obj-$(CONFIG_CPU_SH3) += tlb-sh3.o | ||
21 | obj-$(CONFIG_CPU_SH4) += tlb-sh4.o ioremap.o | ||
22 | obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o | ||
23 | endif | ||
24 | |||
25 | obj-$(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 | */ | ||
24 | unsigned 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 | |||
35 | void __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 | */ | ||
74 | void __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 | */ | ||
99 | void __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 | |||
29 | extern void __flush_cache_4096_all(unsigned long start); | ||
30 | static void __flush_cache_4096_all_ex(unsigned long start); | ||
31 | extern void __flush_dcache_all(void); | ||
32 | static void __flush_dcache_all_ex(void); | ||
33 | |||
34 | /* | ||
35 | * SH-4 has virtually indexed and physically tagged cache. | ||
36 | */ | ||
37 | |||
38 | struct semaphore p3map_sem[4]; | ||
39 | |||
40 | void __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 | */ | ||
57 | void __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 | */ | ||
78 | void __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 | */ | ||
97 | void __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 | |||
112 | static 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 | |||
123 | static 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 | |||
138 | void 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 | */ | ||
151 | void 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 | */ | ||
161 | void 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 | |||
182 | static 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 | */ | ||
206 | void 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 | |||
219 | static 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 | |||
235 | void 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 | |||
244 | void 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 | */ | ||
267 | void 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 | */ | ||
299 | void 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 | */ | ||
357 | void 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 | |||
36 | static 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 | */ | ||
71 | void 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 | */ | ||
80 | static 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 | */ | ||
136 | void 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 | |||
142 | void 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 | |||
154 | void 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 | */ | ||
170 | void 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 | */ | ||
189 | void 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 | */ | ||
202 | void 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 | */ | ||
24 | ENTRY(clear_page_slow) | ||
25 | mov r4,r5 | ||
26 | mov.w .Llimit,r0 | ||
27 | add r0,r5 | ||
28 | mov #0,r0 | ||
29 | ! | ||
30 | 1: | ||
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 | |||
56 | ENTRY(__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 | ||
81 | 0: 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) | ||
96 | 1: movca.l r0, @r2 | ||
97 | #else | ||
98 | 1: mov.l r0, @r2 | ||
99 | #endif | ||
100 | add #4, r2 | ||
101 | 2: mov.l r0, @r2 | ||
102 | add #4, r2 | ||
103 | 3: mov.l r0, @r2 | ||
104 | add #4, r2 | ||
105 | 4: mov.l r0, @r2 | ||
106 | add #4, r2 | ||
107 | 5: mov.l r0, @r2 | ||
108 | add #4, r2 | ||
109 | 6: mov.l r0, @r2 | ||
110 | add #4, r2 | ||
111 | 7: mov.l r0, @r2 | ||
112 | add #4, r2 | ||
113 | 8: 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 | ||
127 | 9: 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 | */ | ||
170 | ENTRY(__clear_user_page) | ||
171 | mov.w .L4096,r0 | ||
172 | mov r4,r6 | ||
173 | add r0,r6 | ||
174 | mov #0,r0 | ||
175 | ! | ||
176 | 1: 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 | |||
197 | ENTRY(__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 | ||
207 | 1: .long 2f | ||
208 | 2: | ||
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 | |||
227 | ENTRY(__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 | ||
236 | 1: | ||
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 | ||
257 | 2: .long 0xffffc000 | ||
258 | 3: .long empty_zero_page | ||
259 | 4: .long 0x10000000 ! BL bit | ||
260 | |||
261 | /* __flush_cache_4096_all(unsigned long addr) */ | ||
262 | ENTRY(__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 | ||
271 | 1: | ||
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 | ||
292 | 2: .long 0xffffc000 | ||
293 | 3: .long empty_zero_page | ||
294 | 4: .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 | |||
14 | void *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 | |||
51 | void 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 | |||
63 | void 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 | |||
82 | EXPORT_SYMBOL(consistent_alloc); | ||
83 | EXPORT_SYMBOL(consistent_free); | ||
84 | EXPORT_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 | */ | ||
26 | ENTRY(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 | ! | ||
36 | 1: 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 | */ | ||
88 | ENTRY(__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 | ! | ||
100 | 1: 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 | ||
142 | ENTRY(__copy_user) | ||
143 | tst r6,r6 ! Check explicitly for zero | ||
144 | bf 1f | ||
145 | rts | ||
146 | mov #0,r0 ! normal return | ||
147 | 1: | ||
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 | ||
158 | 2: | ||
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 | ||
168 | EX( mov.b @r5+,r0 ) | ||
169 | dt r1 | ||
170 | EX( 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 | ||
208 | 2: | ||
209 | EX( mov.l @r5+,r0 ) | ||
210 | EX( mov.l @r5+,r8 ) | ||
211 | EX( mov.l @r5+,r9 ) | ||
212 | EX( mov.l @r5+,r10 ) | ||
213 | EX( mov.l r0,@r4 ) | ||
214 | EX( mov.l r8,@(4,r4) ) | ||
215 | EX( mov.l r9,@(8,r4) ) | ||
216 | EX( mov.l r10,@(12,r4) ) | ||
217 | EX( mov.l @r5+,r0 ) | ||
218 | EX( mov.l @r5+,r8 ) | ||
219 | EX( mov.l @r5+,r9 ) | ||
220 | EX( mov.l @r5+,r10 ) | ||
221 | dt r7 | ||
222 | EX( mov.l r0,@(16,r4) ) | ||
223 | EX( mov.l r8,@(20,r4) ) | ||
224 | EX( mov.l r9,@(24,r4) ) | ||
225 | EX( mov.l r10,@(28,r4) ) | ||
226 | bf/s 2b | ||
227 | add #32,r4 | ||
228 | tst r2,r2 | ||
229 | bt .L_cleanup | ||
230 | 1: | ||
231 | EX( mov.l @r5+,r0 ) | ||
232 | dt r2 | ||
233 | EX( 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 | ||
250 | 2: | ||
251 | dt r7 | ||
252 | #ifdef __LITTLE_ENDIAN__ | ||
253 | EX( mov.l @r5+,r0 ) | ||
254 | EX( mov.l @r5+,r1 ) | ||
255 | EX( mov.l @r5+,r8 ) | ||
256 | EX( mov.l @r5+,r9 ) | ||
257 | EX( mov.l @r5+,r10 ) | ||
258 | EX( 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 | |||
265 | EX( mov.l r0,@r4 ) | ||
266 | EX( mov.l r1,@(4,r4) ) | ||
267 | EX( mov.l r8,@(8,r4) ) | ||
268 | EX( mov.l r9,@(12,r4) ) | ||
269 | |||
270 | EX( mov.l @r5+,r1 ) | ||
271 | EX( mov.l @r5+,r8 ) | ||
272 | EX( mov.l @r5+,r0 ) | ||
273 | xtrct r1,r10 | ||
274 | xtrct r8,r1 | ||
275 | xtrct r0,r8 | ||
276 | shlr16 r0 | ||
277 | EX( mov.l r10,@(16,r4) ) | ||
278 | EX( mov.l r1,@(20,r4) ) | ||
279 | EX( mov.l r8,@(24,r4) ) | ||
280 | EX( mov.w r0,@(28,r4) ) | ||
281 | bf/s 2b | ||
282 | add #30,r4 | ||
283 | #else | ||
284 | EX( mov.l @(28,r5),r0 ) | ||
285 | EX( mov.l @(24,r5),r8 ) | ||
286 | EX( mov.l @(20,r5),r9 ) | ||
287 | EX( mov.l @(16,r5),r10 ) | ||
288 | EX( mov.w r0,@(30,r4) ) | ||
289 | add #-2,r4 | ||
290 | xtrct r8,r0 | ||
291 | xtrct r9,r8 | ||
292 | xtrct r10,r9 | ||
293 | EX( mov.l r0,@(28,r4) ) | ||
294 | EX( mov.l r8,@(24,r4) ) | ||
295 | EX( mov.l r9,@(20,r4) ) | ||
296 | |||
297 | EX( mov.l @(12,r5),r0 ) | ||
298 | EX( mov.l @(8,r5),r8 ) | ||
299 | xtrct r0,r10 | ||
300 | EX( mov.l @(4,r5),r9 ) | ||
301 | mov.l r10,@(16,r4) | ||
302 | EX( mov.l @r5,r10 ) | ||
303 | xtrct r8,r0 | ||
304 | xtrct r9,r8 | ||
305 | xtrct r10,r9 | ||
306 | EX( mov.l r0,@(12,r4) ) | ||
307 | EX( mov.l r8,@(8,r4) ) | ||
308 | swap.w r10,r0 | ||
309 | EX( mov.l r9,@(4,r4) ) | ||
310 | EX( 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 | |||
319 | 1: ! Read longword, write two words per iteration | ||
320 | EX( mov.l @r5+,r0 ) | ||
321 | dt r2 | ||
322 | #ifdef __LITTLE_ENDIAN__ | ||
323 | EX( mov.w r0,@r4 ) | ||
324 | shlr16 r0 | ||
325 | EX( mov.w r0,@(2,r4) ) | ||
326 | #else | ||
327 | EX( mov.w r0,@(2,r4) ) | ||
328 | shlr16 r0 | ||
329 | EX( 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 | ||
342 | EX( mov.l @r5+,r0 ) | ||
343 | dt r2 | ||
344 | #ifdef __LITTLE_ENDIAN__ | ||
345 | EX( mov.b r0,@r4 ) | ||
346 | shlr8 r0 | ||
347 | add #1,r4 | ||
348 | EX( mov.w r0,@r4 ) | ||
349 | shlr16 r0 | ||
350 | EX( mov.b r0,@(2,r4) ) | ||
351 | bf/s .L_dest01 | ||
352 | add #3,r4 | ||
353 | #else | ||
354 | EX( mov.b r0,@(3,r4) ) | ||
355 | shlr8 r0 | ||
356 | swap.w r0,r7 | ||
357 | EX( mov.b r7,@r4 ) | ||
358 | add #1,r4 | ||
359 | EX( 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: | ||
373 | EX( mov.b @r5+,r0 ) | ||
374 | dt r6 | ||
375 | EX( mov.b r0,@r4 ) | ||
376 | bf/s .L_cleanup_loop | ||
377 | add #1,r4 | ||
378 | |||
379 | .L_exit: | ||
380 | mov #0,r0 ! normal return | ||
381 | 5000: | ||
382 | |||
383 | # Exception handler: | ||
384 | .section .fixup, "ax" | ||
385 | 6000: | ||
386 | mov.l 8000f,r1 | ||
387 | mov r3,r0 | ||
388 | jmp @r1 | ||
389 | sub r4,r0 | ||
390 | .align 2 | ||
391 | 8000: .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 | |||
11 | int 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 | |||
36 | extern 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 | */ | ||
43 | asmlinkage 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 | |||
69 | asmlinkage 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 | |||
33 | extern 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 | */ | ||
40 | asmlinkage 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 | */ | ||
78 | good_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 | */ | ||
92 | survive: | ||
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 | */ | ||
115 | bad_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 | |||
125 | no_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 | */ | ||
161 | out_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 | |||
173 | do_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 | */ | ||
193 | asmlinkage 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 | |||
258 | void 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 | |||
280 | void 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 | |||
317 | void 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 | |||
343 | void 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 | |||
358 | void 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 | |||
27 | static 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 | |||
42 | static 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 | |||
59 | static 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 | */ | ||
86 | int 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 | |||
95 | int 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 | |||
123 | nomem: | ||
124 | return -ENOMEM; | ||
125 | } | ||
126 | |||
127 | int 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 | |||
168 | struct page *follow_huge_addr(struct mm_struct *mm, | ||
169 | unsigned long address, int write) | ||
170 | { | ||
171 | return ERR_PTR(-EINVAL); | ||
172 | } | ||
173 | |||
174 | int pmd_huge(pmd_t pmd) | ||
175 | { | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, | ||
180 | pmd_t *pmd, int write) | ||
181 | { | ||
182 | return NULL; | ||
183 | } | ||
184 | |||
185 | void 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 | |||
213 | int 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 | } | ||
261 | out: | ||
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 | |||
40 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
41 | pgd_t swapper_pg_dir[PTRS_PER_PGD]; | ||
42 | |||
43 | /* | ||
44 | * Cache of MMU context last used. | ||
45 | */ | ||
46 | unsigned 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 | ||
55 | pg_data_t discontig_page_data[MAX_NUMNODES]; | ||
56 | bootmem_data_t discontig_node_bdata[MAX_NUMNODES]; | ||
57 | #endif | ||
58 | |||
59 | void (*copy_page)(void *from, void *to); | ||
60 | void (*clear_page)(void *to); | ||
61 | |||
62 | void 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 | |||
86 | static 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 | */ | ||
134 | void __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 | |||
148 | extern char _text, _etext, _edata, __bss_start, _end; | ||
149 | extern 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 | */ | ||
157 | void __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 | |||
230 | void __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 | |||
286 | void 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 | ||
301 | void 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 | |||
19 | static 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 | |||
47 | static 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 | |||
70 | int 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 | */ | ||
114 | void * 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 | |||
159 | void 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. */ | ||
24 | static int dma_channel = CONFIG_DMA_PAGE_OPS_CHANNEL; | ||
25 | |||
26 | static 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 | |||
40 | static 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 | |||
72 | static 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 | |||
86 | static void __exit pg_dma_exit(void) | ||
87 | { | ||
88 | free_dma(dma_channel); | ||
89 | } | ||
90 | |||
91 | module_init(pg_dma_init); | ||
92 | module_exit(pg_dma_exit); | ||
93 | |||
94 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); | ||
95 | MODULE_DESCRIPTION("Optimized page copy/clear routines using a dual-address mode capable DMAC channel"); | ||
96 | MODULE_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 | |||
17 | static void copy_page_nommu(void *to, void *from) | ||
18 | { | ||
19 | memcpy(to, from, PAGE_SIZE); | ||
20 | } | ||
21 | |||
22 | static void clear_page_nommu(void *to) | ||
23 | { | ||
24 | memset(to, 0, PAGE_SIZE); | ||
25 | } | ||
26 | |||
27 | static 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 | |||
35 | subsys_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 | |||
25 | extern 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 | */ | ||
33 | void 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 | */ | ||
71 | void 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 | */ | ||
106 | inline 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 | |||
28 | static 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 | */ | ||
75 | void 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 | */ | ||
98 | void 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 | */ | ||
120 | inline 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 | |||
17 | void flush_tlb(void) | ||
18 | { | ||
19 | BUG(); | ||
20 | } | ||
21 | |||
22 | void flush_tlb_all(void) | ||
23 | { | ||
24 | BUG(); | ||
25 | } | ||
26 | |||
27 | void flush_tlb_mm(struct mm_struct *mm) | ||
28 | { | ||
29 | BUG(); | ||
30 | } | ||
31 | |||
32 | void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | ||
33 | unsigned long end) | ||
34 | { | ||
35 | BUG(); | ||
36 | } | ||
37 | |||
38 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | ||
39 | { | ||
40 | BUG(); | ||
41 | } | ||
42 | |||
43 | void __flush_tlb_page(unsigned long asid, unsigned long page) | ||
44 | { | ||
45 | BUG(); | ||
46 | } | ||
47 | |||
48 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
49 | { | ||
50 | BUG(); | ||
51 | } | ||
52 | |||
53 | void 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 | |||
31 | void 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 | |||
70 | void __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 | |||
31 | void 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 | |||
80 | void __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 | |||
2 | menu "Profiling support" | ||
3 | depends on EXPERIMENTAL | ||
4 | |||
5 | config 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 | |||
12 | config 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 | |||
22 | endmenu | ||
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 @@ | |||
1 | obj-$(CONFIG_OPROFILE) += oprofile.o | ||
2 | |||
3 | DRIVER_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 | |||
9 | profdrvr-y := op_model_null.o | ||
10 | profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750) := op_model_sh7750.o | ||
11 | |||
12 | oprofile-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 | |||
15 | int __init oprofile_arch_init(struct oprofile_operations *ops) | ||
16 | { | ||
17 | return -ENODEV; | ||
18 | } | ||
19 | |||
20 | void 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 | |||
47 | extern const char *get_cpu_subtype(void); | ||
48 | |||
49 | struct 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 | |||
60 | static 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 | |||
114 | static 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 | |||
121 | static struct notifier_block sh7750_timer_notifier = { | ||
122 | .notifier_call = sh7750_timer_notify, | ||
123 | }; | ||
124 | |||
125 | static 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 | */ | ||
143 | static 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 | */ | ||
156 | static 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 | |||
165 | static 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 | |||
190 | static struct file_operations count_fops = { | ||
191 | .read = sh7750_read_count, | ||
192 | .write = sh7750_write_count, | ||
193 | }; | ||
194 | |||
195 | static 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 | |||
219 | static 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 | |||
246 | static 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 | |||
254 | static 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 | |||
260 | int __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 | |||
278 | void 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 | |||
5 | obj-y += ramdisk.o | ||
6 | |||
7 | |||
8 | O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32) | ||
9 | img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE)) | ||
10 | # add $(src) when $(img) is relative | ||
11 | img := $(subst $(src)//,/,$(src)/$(img)) | ||
12 | |||
13 | quiet_cmd_ramdisk = LD $@ | ||
14 | define cmd_ramdisk | ||
15 | $(LD) -T $(srctree)/$(src)/ld.script -b binary --oformat $(O_FORMAT) \ | ||
16 | -o $@ $(img) | ||
17 | endef | ||
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 @@ | |||
1 | OUTPUT_ARCH(sh) | ||
2 | SECTIONS | ||
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 | |||
13 | include/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 | # | ||
6 | BEGIN { nr = 0 } | ||
7 | /^#/ { next } | ||
8 | /^[ ]*$/ { next } | ||
9 | |||
10 | NF == 2 { | ||
11 | mach[nr] = $1; | ||
12 | config[nr] = "CONFIG_"$2; | ||
13 | nr++; | ||
14 | } | ||
15 | |||
16 | END { | ||
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 | # | ||
8 | SE SH_SOLUTION_ENGINE | ||
9 | 7751SE SH_7751_SOLUTION_ENGINE | ||
10 | 7300SE SH_7300_SOLUTION_ENGINE | ||
11 | 73180SE SH_73180_SOLUTION_ENGINE | ||
12 | 7751SYSTEMH SH_7751_SYSTEMH | ||
13 | HP600 SH_HP600 | ||
14 | HP620 SH_HP620 | ||
15 | HP680 SH_HP680 | ||
16 | HP690 SH_HP690 | ||
17 | HD64461 HD64461 | ||
18 | HD64465 HD64465 | ||
19 | SH2000 SH_SH2000 | ||
20 | SATURN SH_SATURN | ||
21 | DREAMCAST SH_DREAMCAST | ||
22 | BIGSUR SH_BIGSUR | ||
23 | ADX SH_ADX | ||
24 | MPC1211 SH_MPC1211 | ||
25 | SNAPGEAR SH_SECUREEDGE5410 | ||
26 | HS7751RVOIP SH_HS7751RVOIP | ||
27 | RTS7751R2D SH_RTS7751R2D | ||
28 | EDOSK7705 SH_EDOSK7705 | ||
29 | SH4202_MICRODEV SH_SH4202_MICRODEV | ||
30 | SH03 SH_SH03 | ||
31 | |||