diff options
Diffstat (limited to 'arch/sh')
57 files changed, 3449 insertions, 1916 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8cf6d437a630..01bc7d589afe 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -33,9 +33,11 @@ config GENERIC_CALIBRATE_DELAY | |||
33 | bool | 33 | bool |
34 | default y | 34 | default y |
35 | 35 | ||
36 | config GENERIC_IOMAP | ||
37 | bool | ||
38 | |||
36 | config ARCH_MAY_HAVE_PC_FDC | 39 | config ARCH_MAY_HAVE_PC_FDC |
37 | bool | 40 | bool |
38 | default y | ||
39 | 41 | ||
40 | source "init/Kconfig" | 42 | source "init/Kconfig" |
41 | 43 | ||
@@ -53,24 +55,28 @@ config SH_SOLUTION_ENGINE | |||
53 | 55 | ||
54 | config SH_7751_SOLUTION_ENGINE | 56 | config SH_7751_SOLUTION_ENGINE |
55 | bool "SolutionEngine7751" | 57 | bool "SolutionEngine7751" |
58 | select CPU_SUBTYPE_SH7751 | ||
56 | help | 59 | help |
57 | Select 7751 SolutionEngine if configuring for a Hitachi SH7751 | 60 | Select 7751 SolutionEngine if configuring for a Hitachi SH7751 |
58 | evaluation board. | 61 | evaluation board. |
59 | 62 | ||
60 | config SH_7300_SOLUTION_ENGINE | 63 | config SH_7300_SOLUTION_ENGINE |
61 | bool "SolutionEngine7300" | 64 | bool "SolutionEngine7300" |
65 | select CPU_SUBTYPE_SH7300 | ||
62 | help | 66 | help |
63 | Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) | 67 | Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) |
64 | evaluation board. | 68 | evaluation board. |
65 | 69 | ||
66 | config SH_73180_SOLUTION_ENGINE | 70 | config SH_73180_SOLUTION_ENGINE |
67 | bool "SolutionEngine73180" | 71 | bool "SolutionEngine73180" |
72 | select CPU_SUBTYPE_SH73180 | ||
68 | help | 73 | help |
69 | Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) | 74 | Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) |
70 | evaluation board. | 75 | evaluation board. |
71 | 76 | ||
72 | config SH_7751_SYSTEMH | 77 | config SH_7751_SYSTEMH |
73 | bool "SystemH7751R" | 78 | bool "SystemH7751R" |
79 | select CPU_SUBTYPE_SH7751R | ||
74 | help | 80 | help |
75 | Select SystemH if you are configuring for a Renesas SystemH | 81 | Select SystemH if you are configuring for a Renesas SystemH |
76 | 7751R evaluation board. | 82 | 7751R evaluation board. |
@@ -81,27 +87,13 @@ config SH_STB1_HARP | |||
81 | config SH_STB1_OVERDRIVE | 87 | config SH_STB1_OVERDRIVE |
82 | bool "STB1_Overdrive" | 88 | bool "STB1_Overdrive" |
83 | 89 | ||
84 | config SH_HP620 | 90 | config SH_HP6XX |
85 | bool "HP620" | 91 | bool "HP6XX" |
86 | help | 92 | help |
87 | Select HP620 if configuring for a HP jornada HP620. | 93 | Select HP6XX if configuring for a HP jornada HP6xx. |
88 | More information (hardware only) at | 94 | More information (hardware only) at |
89 | <http://www.hp.com/jornada/>. | 95 | <http://www.hp.com/jornada/>. |
90 | 96 | ||
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 | 97 | config SH_CQREEK |
106 | bool "CqREEK" | 98 | bool "CqREEK" |
107 | help | 99 | help |
@@ -123,11 +115,13 @@ config SH_EC3104 | |||
123 | 115 | ||
124 | config SH_SATURN | 116 | config SH_SATURN |
125 | bool "Saturn" | 117 | bool "Saturn" |
118 | select CPU_SUBTYPE_SH7604 | ||
126 | help | 119 | help |
127 | Select Saturn if configuring for a SEGA Saturn. | 120 | Select Saturn if configuring for a SEGA Saturn. |
128 | 121 | ||
129 | config SH_DREAMCAST | 122 | config SH_DREAMCAST |
130 | bool "Dreamcast" | 123 | bool "Dreamcast" |
124 | select CPU_SUBTYPE_SH7091 | ||
131 | help | 125 | help |
132 | Select Dreamcast if configuring for a SEGA Dreamcast. | 126 | Select Dreamcast if configuring for a SEGA Dreamcast. |
133 | More information at | 127 | More information at |
@@ -142,6 +136,7 @@ config SH_BIGSUR | |||
142 | 136 | ||
143 | config SH_SH2000 | 137 | config SH_SH2000 |
144 | bool "SH2000" | 138 | bool "SH2000" |
139 | select CPU_SUBTYPE_SH7709 | ||
145 | help | 140 | help |
146 | SH-2000 is a single-board computer based around SH7709A chip | 141 | SH-2000 is a single-board computer based around SH7709A chip |
147 | intended for embedded applications. | 142 | intended for embedded applications. |
@@ -153,20 +148,22 @@ config SH_ADX | |||
153 | bool "ADX" | 148 | bool "ADX" |
154 | 149 | ||
155 | config SH_MPC1211 | 150 | config SH_MPC1211 |
156 | bool "MPC1211" | 151 | bool "Interface MPC1211" |
152 | help | ||
153 | CTP/PCI-SH02 is a CPU module computer that is produced | ||
154 | by Interface Corporation. | ||
155 | More information at <http://www.interface.co.jp> | ||
157 | 156 | ||
158 | config SH_SH03 | 157 | config SH_SH03 |
159 | bool "SH03" | 158 | bool "Interface CTP/PCI-SH03" |
160 | help | 159 | help |
161 | CTP/PCI-SH03 is a CPU module computer that produced | 160 | CTP/PCI-SH03 is a CPU module computer that is produced |
162 | by Interface Corporation. | 161 | 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> | 162 | More information at <http://www.interface.co.jp> |
167 | 163 | ||
168 | config SH_SECUREEDGE5410 | 164 | config SH_SECUREEDGE5410 |
169 | bool "SecureEdge5410" | 165 | bool "SecureEdge5410" |
166 | select CPU_SUBTYPE_SH7751R | ||
170 | help | 167 | help |
171 | Select SecureEdge5410 if configuring for a SnapGear SH board. | 168 | Select SecureEdge5410 if configuring for a SnapGear SH board. |
172 | This includes both the OEM SecureEdge products as well as the | 169 | This includes both the OEM SecureEdge products as well as the |
@@ -174,25 +171,49 @@ config SH_SECUREEDGE5410 | |||
174 | 171 | ||
175 | config SH_HS7751RVOIP | 172 | config SH_HS7751RVOIP |
176 | bool "HS7751RVOIP" | 173 | bool "HS7751RVOIP" |
174 | select CPU_SUBTYPE_SH7751R | ||
177 | help | 175 | help |
178 | Select HS7751RVOIP if configuring for a Renesas Technology | 176 | Select HS7751RVOIP if configuring for a Renesas Technology |
179 | Sales VoIP board. | 177 | Sales VoIP board. |
180 | 178 | ||
181 | config SH_RTS7751R2D | 179 | config SH_RTS7751R2D |
182 | bool "RTS7751R2D" | 180 | bool "RTS7751R2D" |
181 | select CPU_SUBTYPE_SH7751R | ||
183 | help | 182 | help |
184 | Select RTS7751R2D if configuring for a Renesas Technology | 183 | Select RTS7751R2D if configuring for a Renesas Technology |
185 | Sales SH-Graphics board. | 184 | Sales SH-Graphics board. |
186 | 185 | ||
186 | config SH_R7780RP | ||
187 | bool "R7780RP-1" | ||
188 | select CPU_SUBTYPE_SH7780 | ||
189 | help | ||
190 | Select R7780RP-1 if configuring for a Renesas Solutions | ||
191 | HIGHLANDER board. | ||
192 | |||
187 | config SH_EDOSK7705 | 193 | config SH_EDOSK7705 |
188 | bool "EDOSK7705" | 194 | bool "EDOSK7705" |
195 | select CPU_SUBTYPE_SH7705 | ||
189 | 196 | ||
190 | config SH_SH4202_MICRODEV | 197 | config SH_SH4202_MICRODEV |
191 | bool "SH4-202 MicroDev" | 198 | bool "SH4-202 MicroDev" |
199 | select CPU_SUBTYPE_SH4_202 | ||
192 | help | 200 | help |
193 | Select SH4-202 MicroDev if configuring for a SuperH MicroDev board | 201 | Select SH4-202 MicroDev if configuring for a SuperH MicroDev board |
194 | with an SH4-202 CPU. | 202 | with an SH4-202 CPU. |
195 | 203 | ||
204 | config SH_LANDISK | ||
205 | bool "LANDISK" | ||
206 | select CPU_SUBTYPE_SH7751R | ||
207 | help | ||
208 | I-O DATA DEVICE, INC. "LANDISK Series" support. | ||
209 | |||
210 | config SH_TITAN | ||
211 | bool "TITAN" | ||
212 | select CPU_SUBTYPE_SH7751R | ||
213 | help | ||
214 | Select Titan if you are configuring for a Nimble Microsystems | ||
215 | NetEngine NP51R. | ||
216 | |||
196 | config SH_UNKNOWN | 217 | config SH_UNKNOWN |
197 | bool "BareCPU" | 218 | bool "BareCPU" |
198 | help | 219 | help |
@@ -207,168 +228,27 @@ config SH_UNKNOWN | |||
207 | 228 | ||
208 | endchoice | 229 | endchoice |
209 | 230 | ||
210 | choice | 231 | source "arch/sh/mm/Kconfig" |
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 | 232 | ||
346 | # Platform-specific memory start and size definitions | ||
347 | config MEMORY_START | 233 | config MEMORY_START |
348 | hex "Physical memory start address" if !MEMORY_SET || MEMORY_OVERRIDE | 234 | hex "Physical memory start address" |
349 | default "0x08000000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || SH_MPC1211 || SH_SH03 || SH_SECUREEDGE5410 || SH_SH4202_MICRODEV | 235 | default "0x08000000" |
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--- | 236 | ---help--- |
352 | Computers built with Hitachi SuperH processors always | 237 | Computers built with Hitachi SuperH processors always |
353 | map the ROM starting at address zero. But the processor | 238 | map the ROM starting at address zero. But the processor |
354 | does not specify the range that RAM takes. | 239 | does not specify the range that RAM takes. |
355 | 240 | ||
356 | The physical memory (RAM) start address will be automatically | 241 | The physical memory (RAM) start address will be automatically |
357 | set to 08000000, unless you selected one of the following | 242 | set to 08000000. Other platforms, such as the Solution Engine |
358 | processor types: SolutionEngine, Overdrive, HP620, HP680, HP690, | 243 | boards typically map RAM at 0C000000. |
359 | in which case the start address will be set to 0c000000. | ||
360 | 244 | ||
361 | Tweak this only when porting to a new machine which is not already | 245 | Tweak this only when porting to a new machine which does not |
362 | known by the config system. Changing it from the known correct | 246 | already have a defconfig. Changing it from the known correct |
363 | value on any of the known systems will only lead to disaster. | 247 | value on any of the known systems will only lead to disaster. |
364 | 248 | ||
365 | config MEMORY_SIZE | 249 | config MEMORY_SIZE |
366 | hex "Physical memory size" if !MEMORY_SET || MEMORY_OVERRIDE | 250 | hex "Physical memory size" |
367 | default "0x00400000" if !MEMORY_SET || MEMORY_OVERRIDE || !MEMORY_OVERRIDE && SH_ADX || !MEMORY_OVERRIDE && (SH_HP600 || SH_BIGSUR || SH_SH2000) | 251 | default "0x00400000" |
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 | 252 | help |
373 | This sets the default memory size assumed by your SH kernel. It can | 253 | 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 | 254 | be overridden as normal by the 'mem=' argument on the kernel command |
@@ -376,21 +256,6 @@ config MEMORY_SIZE | |||
376 | as 0x00400000 which was the default value before this became | 256 | as 0x00400000 which was the default value before this became |
377 | configurable. | 257 | configurable. |
378 | 258 | ||
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 | 259 | config CF_ENABLER |
395 | bool "Compact Flash Enabler support" | 260 | bool "Compact Flash Enabler support" |
396 | depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03 | 261 | depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03 |
@@ -434,10 +299,21 @@ config CF_BASE_ADDR | |||
434 | default "0xb8000000" if CF_AREA6 | 299 | default "0xb8000000" if CF_AREA6 |
435 | default "0xb4000000" if CF_AREA5 | 300 | default "0xb4000000" if CF_AREA5 |
436 | 301 | ||
302 | menu "Processor features" | ||
303 | |||
304 | config CPU_LITTLE_ENDIAN | ||
305 | bool "Little Endian" | ||
306 | help | ||
307 | Some SuperH machines can be configured for either little or big | ||
308 | endian byte order. These modes require different kernels. Say Y if | ||
309 | your machine is little endian, N if it's a big endian machine. | ||
310 | |||
437 | # The SH7750 RTC module is disabled in the Dreamcast | 311 | # The SH7750 RTC module is disabled in the Dreamcast |
438 | config SH_RTC | 312 | config SH_RTC |
439 | bool | 313 | bool |
440 | depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && !SH_73180_SOLUTION_ENGINE | 314 | depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && \ |
315 | !SH_73180_SOLUTION_ENGINE && !SH_LANDISK && \ | ||
316 | !SH_R7780RP | ||
441 | default y | 317 | default y |
442 | help | 318 | help |
443 | Selecting this option will allow the Linux kernel to emulate | 319 | Selecting this option will allow the Linux kernel to emulate |
@@ -476,104 +352,131 @@ config SH_ADC | |||
476 | 352 | ||
477 | If unsure, say N. | 353 | If unsure, say N. |
478 | 354 | ||
479 | config SH_HP600 | 355 | config SH_STORE_QUEUES |
356 | bool "Support for Store Queues" | ||
357 | depends on CPU_SH4 | ||
358 | help | ||
359 | Selecting this option will enable an in-kernel API for manipulating | ||
360 | the store queues integrated in the SH-4 processors. | ||
361 | |||
362 | config CPU_HAS_INTEVT | ||
480 | bool | 363 | bool |
481 | depends on SH_HP620 || SH_HP680 || SH_HP690 | ||
482 | default y | ||
483 | 364 | ||
484 | config CPU_SUBTYPE_ST40 | 365 | config CPU_HAS_PINT_IRQ |
485 | bool | 366 | bool |
486 | depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1 | ||
487 | default y | ||
488 | 367 | ||
489 | source "mm/Kconfig" | 368 | config CPU_HAS_INTC2_IRQ |
369 | bool | ||
490 | 370 | ||
491 | config ZERO_PAGE_OFFSET | 371 | config CPU_HAS_SR_RB |
492 | hex "Zero page offset" | 372 | bool "CPU has SR.RB" |
493 | default "0x00001000" if !(SH_MPC1211 || SH_SH03) | 373 | depends on CPU_SH3 || CPU_SH4 |
494 | default "0x00004000" if SH_MPC1211 || SH_SH03 | 374 | default y |
495 | help | 375 | help |
496 | This sets the default offset of zero page. | 376 | This will enable the use of SR.RB register bank usage. Processors |
377 | that are lacking this bit must have another method in place for | ||
378 | accomplishing what is taken care of by the banked registers. | ||
497 | 379 | ||
498 | # XXX: needs to lose subtype for system type | 380 | See <file:Documentation/sh/register-banks.txt> for further |
499 | config ST40_LMI_MEMORY | 381 | information on SR.RB and register banking in the kernel in general. |
500 | bool "Memory on LMI" | ||
501 | depends on CPU_SUBTYPE_ST40STB1 | ||
502 | 382 | ||
503 | config MEMORY_START | 383 | endmenu |
504 | hex | ||
505 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
506 | default "0x08000000" | ||
507 | 384 | ||
508 | config MEMORY_SIZE | 385 | menu "Timer support" |
509 | hex | ||
510 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
511 | default "0x00400000" | ||
512 | 386 | ||
513 | config MEMORY_SET | 387 | config SH_TMU |
514 | bool | 388 | bool "TMU timer support" |
515 | depends on CPU_SUBTYPE_ST40STB1 && ST40_LMI_MEMORY | ||
516 | default y | 389 | default y |
517 | |||
518 | config BOOT_LINK_OFFSET | ||
519 | hex "Link address offset for booting" | ||
520 | default "0x00800000" | ||
521 | help | 390 | help |
522 | This option allows you to set the link address offset of the zImage. | 391 | This enables the use of the TMU as the system timer. |
523 | This can be useful if you are on a board which has a small amount of | ||
524 | memory. | ||
525 | 392 | ||
526 | config CPU_LITTLE_ENDIAN | 393 | endmenu |
527 | bool "Little Endian" | ||
528 | help | ||
529 | Some SuperH machines can be configured for either little or big | ||
530 | endian byte order. These modes require different kernels. Say Y if | ||
531 | your machine is little endian, N if it's a big endian machine. | ||
532 | 394 | ||
533 | config PREEMPT | 395 | source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" |
534 | bool "Preemptible Kernel (EXPERIMENTAL)" | ||
535 | depends on EXPERIMENTAL | ||
536 | 396 | ||
537 | config UBC_WAKEUP | 397 | source "arch/sh/boards/renesas/rts7751r2d/Kconfig" |
538 | bool "Wakeup UBC on startup" | 398 | |
399 | config SH_PCLK_FREQ_BOOL | ||
400 | bool "Set default pclk frequency" | ||
401 | default y if !SH_RTC | ||
402 | default n | ||
403 | |||
404 | config SH_PCLK_FREQ | ||
405 | int "Peripheral clock frequency (in Hz)" | ||
406 | depends on SH_PCLK_FREQ_BOOL | ||
407 | default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 | ||
408 | default "60000000" if CPU_SUBTYPE_SH7751 | ||
409 | default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7760 | ||
410 | default "27000000" if CPU_SUBTYPE_SH73180 | ||
411 | default "66000000" if CPU_SUBTYPE_SH4_202 | ||
539 | help | 412 | help |
540 | Selecting this option will wakeup the User Break Controller (UBC) on | 413 | This option is used to specify the peripheral clock frequency. |
541 | startup. Although the UBC is left in an awake state when the processor | 414 | This is necessary for determining the reference clock value on |
542 | comes up, some boot loaders misbehave by putting the UBC to sleep in a | 415 | platforms lacking an RTC. |
543 | power saving state, which causes issues with things like ptrace(). | ||
544 | 416 | ||
545 | If unsure, say N. | 417 | menu "CPU Frequency scaling" |
418 | |||
419 | source "drivers/cpufreq/Kconfig" | ||
546 | 420 | ||
547 | config SH_WRITETHROUGH | 421 | config SH_CPU_FREQ |
548 | bool "Use write-through caching" | 422 | tristate "SuperH CPU Frequency driver" |
549 | default y if CPU_SH2 | 423 | depends on CPU_FREQ |
424 | select CPU_FREQ_TABLE | ||
550 | help | 425 | help |
551 | Selecting this option will configure the caches in write-through | 426 | This adds the cpufreq driver for SuperH. At present, only |
552 | mode, as opposed to the default write-back configuration. | 427 | the SH-4 is supported. |
553 | 428 | ||
554 | Since there's sill some aliasing issues on SH-4, this option will | 429 | For details, take a look at <file:Documentation/cpu-freq>. |
555 | unfortunately still require the majority of flushing functions to | ||
556 | be implemented to deal with aliasing. | ||
557 | 430 | ||
558 | If unsure, say N. | 431 | If unsure, say N. |
559 | 432 | ||
560 | config SH_OCRAM | 433 | endmenu |
561 | bool "Operand Cache RAM (OCRAM) support" | 434 | |
435 | source "arch/sh/drivers/dma/Kconfig" | ||
436 | |||
437 | source "arch/sh/cchips/Kconfig" | ||
438 | |||
439 | config HEARTBEAT | ||
440 | bool "Heartbeat LED" | ||
441 | depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || \ | ||
442 | SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || \ | ||
443 | SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || \ | ||
444 | SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || \ | ||
445 | SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK | ||
562 | help | 446 | help |
563 | Selecting this option will automatically tear down the number of | 447 | Use the power-on LED on your machine as a load meter. The exact |
564 | sets in the dcache by half, which in turn exposes a memory range. | 448 | behavior is platform-dependent, but normally the flash frequency is |
449 | a hyperbolic function of the 5-minute load average. | ||
565 | 450 | ||
566 | The addresses for the OC RAM base will vary according to the | 451 | endmenu |
567 | processor version. Consult vendor documentation for specifics. | ||
568 | 452 | ||
569 | If unsure, say N. | 453 | config ISA_DMA_API |
454 | bool | ||
455 | depends on MPC1211 | ||
456 | default y | ||
570 | 457 | ||
571 | config SH_STORE_QUEUES | 458 | menu "Kernel features" |
572 | bool "Support for Store Queues" | 459 | |
573 | depends on CPU_SH4 | 460 | config KEXEC |
461 | bool "kexec system call (EXPERIMENTAL)" | ||
462 | depends on EXPERIMENTAL | ||
574 | help | 463 | help |
575 | Selecting this option will enable an in-kernel API for manipulating | 464 | kexec is a system call that implements the ability to shutdown your |
576 | the store queues integrated in the SH-4 processors. | 465 | current kernel, and to start another kernel. It is like a reboot |
466 | but it is indepedent of the system firmware. And like a reboot | ||
467 | you can start any kernel with it, not just Linux. | ||
468 | |||
469 | The name comes from the similiarity to the exec system call. | ||
470 | |||
471 | It is an ongoing process to be certain the hardware in a machine | ||
472 | is properly shutdown, so do not be surprised if this code does not | ||
473 | initially work for you. It may help to enable device hotplugging | ||
474 | support. As of this writing the exact hardware interface is | ||
475 | strongly in flux, so no good recommendation can be made. | ||
476 | |||
477 | config PREEMPT | ||
478 | bool "Preemptible Kernel (EXPERIMENTAL)" | ||
479 | depends on EXPERIMENTAL | ||
577 | 480 | ||
578 | config SMP | 481 | config SMP |
579 | bool "Symmetric multi-processing support" | 482 | bool "Symmetric multi-processing support" |
@@ -610,87 +513,58 @@ config NR_CPUS | |||
610 | This is purely to save memory - each supported CPU adds | 513 | This is purely to save memory - each supported CPU adds |
611 | approximately eight kilobytes to the kernel image. | 514 | approximately eight kilobytes to the kernel image. |
612 | 515 | ||
613 | config HS7751RVOIP_CODEC | 516 | config CPU_HAS_SR_RB |
614 | bool "Support VoIP Codec section" | 517 | bool "CPU has SR.RB" |
615 | depends on SH_HS7751RVOIP | 518 | depends on CPU_SH3 || CPU_SH4 |
616 | help | ||
617 | Selecting this option will support CODEC section. | ||
618 | |||
619 | config RTS7751R2D_REV11 | ||
620 | bool "RTS7751R2D Rev. 1.1 board support" | ||
621 | depends on SH_RTS7751R2D | ||
622 | help | ||
623 | Selecting this option will support version rev. 1.1. | ||
624 | |||
625 | config SH_PCLK_CALC | ||
626 | bool | ||
627 | default n if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH73180 | ||
628 | default y | 519 | default y |
629 | help | 520 | help |
630 | This option will cause the PCLK value to be probed at run-time. It | 521 | This will enable the use of SR.RB register bank usage. Processors |
631 | will display a notification if the probed value has greater than a | 522 | that are lacking this bit must have another method in place for |
632 | 1% variance of the hardcoded CONFIG_SH_PCLK_FREQ. | 523 | accomplishing what is taken care of by the banked registers. |
633 | 524 | ||
634 | config SH_PCLK_FREQ | 525 | See <file:Documentation/sh/register-banks.txt> for further |
635 | int "Peripheral clock frequency (in Hz)" | 526 | information on SR.RB and register banking in the kernel in general. |
636 | default "50000000" if CPU_SUBTYPE_SH7750 | ||
637 | default "60000000" if CPU_SUBTYPE_SH7751 | ||
638 | default "33333333" if CPU_SUBTYPE_SH7300 | ||
639 | default "27000000" if CPU_SUBTYPE_SH73180 | ||
640 | default "66000000" if CPU_SUBTYPE_SH4_202 | ||
641 | default "1193182" | ||
642 | help | ||
643 | This option is used to specify the peripheral clock frequency. This | ||
644 | option must be set for each processor in order for the kernel to | ||
645 | function reliably. If no sane default exists, we use a default from | ||
646 | the legacy i8254. Any discrepancies will be reported on boot time | ||
647 | with an auto-probed frequency which should be considered the proper | ||
648 | value for your hardware. | ||
649 | 527 | ||
650 | menu "CPU Frequency scaling" | 528 | endmenu |
651 | 529 | ||
652 | source "drivers/cpufreq/Kconfig" | 530 | menu "Boot options" |
653 | 531 | ||
654 | config SH_CPU_FREQ | 532 | config ZERO_PAGE_OFFSET |
655 | tristate "SuperH CPU Frequency driver" | 533 | hex "Zero page offset" |
656 | depends on CPU_FREQ | 534 | default "0x00004000" if SH_MPC1211 || SH_SH03 |
657 | select CPU_FREQ_TABLE | 535 | default "0x00001000" |
658 | help | 536 | help |
659 | This adds the cpufreq driver for SuperH. At present, only | 537 | This sets the default offset of zero page. |
660 | the SH-4 is supported. | ||
661 | |||
662 | For details, take a look at <file:Documentation/cpu-freq>. | ||
663 | |||
664 | If unsure, say N. | ||
665 | 538 | ||
666 | endmenu | 539 | config BOOT_LINK_OFFSET |
540 | hex "Link address offset for booting" | ||
541 | default "0x00800000" | ||
542 | help | ||
543 | This option allows you to set the link address offset of the zImage. | ||
544 | This can be useful if you are on a board which has a small amount of | ||
545 | memory. | ||
667 | 546 | ||
668 | source "arch/sh/drivers/dma/Kconfig" | 547 | config UBC_WAKEUP |
548 | bool "Wakeup UBC on startup" | ||
549 | help | ||
550 | Selecting this option will wakeup the User Break Controller (UBC) on | ||
551 | startup. Although the UBC is left in an awake state when the processor | ||
552 | comes up, some boot loaders misbehave by putting the UBC to sleep in a | ||
553 | power saving state, which causes issues with things like ptrace(). | ||
669 | 554 | ||
670 | source "arch/sh/cchips/Kconfig" | 555 | If unsure, say N. |
671 | 556 | ||
672 | config HEARTBEAT | 557 | config CMDLINE_BOOL |
673 | bool "Heartbeat LED" | 558 | bool "Default bootloader kernel arguments" |
674 | 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 | ||
675 | help | ||
676 | Use the power-on LED on your machine as a load meter. The exact | ||
677 | behavior is platform-dependent, but normally the flash frequency is | ||
678 | a hyperbolic function of the 5-minute load average. | ||
679 | 559 | ||
680 | config RTC_9701JE | 560 | config CMDLINE |
681 | tristate "EPSON RTC-9701JE support" | 561 | string "Initial kernel command string" |
682 | depends on SH_RTS7751R2D | 562 | depends on CMDLINE_BOOL |
683 | help | 563 | default "console=ttySC1,115200" |
684 | Selecting this option will support EPSON RTC-9701JE. | ||
685 | 564 | ||
686 | endmenu | 565 | endmenu |
687 | 566 | ||
688 | config ISA_DMA_API | 567 | menu "Bus options" |
689 | bool | ||
690 | depends on MPC1211 | ||
691 | default y | ||
692 | |||
693 | menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" | ||
694 | 568 | ||
695 | # Even on SuperH devices which don't have an ISA bus, | 569 | # Even on SuperH devices which don't have an ISA bus, |
696 | # this variable helps the PCMCIA modules handle | 570 | # this variable helps the PCMCIA modules handle |
@@ -701,7 +575,7 @@ menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" | |||
701 | # PCMCIA outright. -- PFM. | 575 | # PCMCIA outright. -- PFM. |
702 | config ISA | 576 | config ISA |
703 | bool | 577 | bool |
704 | default y if PCMCIA || SMC91X | 578 | default y if PCMCIA |
705 | help | 579 | help |
706 | Find out whether you have ISA slots on your motherboard. ISA is the | 580 | Find out whether you have ISA slots on your motherboard. ISA is the |
707 | name of a bus system, i.e. the way the CPU talks to the other stuff | 581 | name of a bus system, i.e. the way the CPU talks to the other stuff |
@@ -735,10 +609,9 @@ config MCA | |||
735 | config SBUS | 609 | config SBUS |
736 | bool | 610 | bool |
737 | 611 | ||
738 | config MAPLE | 612 | config SUPERHYWAY |
739 | tristate "Maple Bus support" | 613 | tristate "SuperHyway Bus support" |
740 | depends on SH_DREAMCAST | 614 | depends on CPU_SUBTYPE_SH4_202 |
741 | default y | ||
742 | 615 | ||
743 | source "arch/sh/drivers/pci/Kconfig" | 616 | source "arch/sh/drivers/pci/Kconfig" |
744 | 617 | ||
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 3fab181da364..8fb31ab2c02c 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug | |||
@@ -17,7 +17,7 @@ config SH_STANDARD_BIOS | |||
17 | 17 | ||
18 | config EARLY_SCIF_CONSOLE | 18 | config EARLY_SCIF_CONSOLE |
19 | bool "Use early SCIF console" | 19 | bool "Use early SCIF console" |
20 | depends on CPU_SH4 | 20 | depends on CPU_SH4 || CPU_SH2A && !SH_STANDARD_BIOS |
21 | 21 | ||
22 | config EARLY_PRINTK | 22 | config EARLY_PRINTK |
23 | bool "Early printk support" | 23 | bool "Early printk support" |
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 67192d6b00d8..08c9515c4806 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -17,10 +17,30 @@ | |||
17 | cflags-y := -mb | 17 | cflags-y := -mb |
18 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml | 18 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml |
19 | 19 | ||
20 | isa-y := any | ||
21 | isa-$(CONFIG_CPU_SH2) := sh2 | ||
22 | isa-$(CONFIG_CPU_SH3) := sh3 | ||
23 | isa-$(CONFIG_CPU_SH4) := sh4 | ||
24 | isa-$(CONFIG_CPU_SH4A) := sh4a | ||
25 | isa-$(CONFIG_CPU_SH2A) := sh2a | ||
26 | |||
27 | isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp | ||
28 | |||
29 | ifndef CONFIG_MMU | ||
30 | isa-y := $(isa-y)-nommu | ||
31 | endif | ||
32 | |||
33 | ifndef CONFIG_SH_FPU | ||
34 | isa-y := $(isa-y)-nofpu | ||
35 | endif | ||
36 | |||
37 | cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) | ||
38 | |||
20 | cflags-$(CONFIG_CPU_SH2) += -m2 | 39 | cflags-$(CONFIG_CPU_SH2) += -m2 |
21 | cflags-$(CONFIG_CPU_SH3) += -m3 | 40 | cflags-$(CONFIG_CPU_SH3) += -m3 |
22 | cflags-$(CONFIG_CPU_SH4) += -m4 \ | 41 | cflags-$(CONFIG_CPU_SH4) += -m4 \ |
23 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) | 42 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) |
43 | cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a-nofpu,) | ||
24 | 44 | ||
25 | cflags-$(CONFIG_SH_DSP) += -Wa,-dsp | 45 | cflags-$(CONFIG_SH_DSP) += -Wa,-dsp |
26 | cflags-$(CONFIG_SH_KGDB) += -g | 46 | cflags-$(CONFIG_SH_KGDB) += -g |
@@ -67,9 +87,7 @@ machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 | |||
67 | machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 | 87 | machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 |
68 | machdir-$(CONFIG_SH_STB1_HARP) := harp | 88 | machdir-$(CONFIG_SH_STB1_HARP) := harp |
69 | machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive | 89 | machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive |
70 | machdir-$(CONFIG_SH_HP620) := hp6xx/hp620 | 90 | machdir-$(CONFIG_SH_HP6XX) := hp6xx |
71 | machdir-$(CONFIG_SH_HP680) := hp6xx/hp680 | ||
72 | machdir-$(CONFIG_SH_HP690) := hp6xx/hp690 | ||
73 | machdir-$(CONFIG_SH_CQREEK) := cqreek | 91 | machdir-$(CONFIG_SH_CQREEK) := cqreek |
74 | machdir-$(CONFIG_SH_DMIDA) := dmida | 92 | machdir-$(CONFIG_SH_DMIDA) := dmida |
75 | machdir-$(CONFIG_SH_EC3104) := ec3104 | 93 | machdir-$(CONFIG_SH_EC3104) := ec3104 |
@@ -119,31 +137,39 @@ boot := arch/sh/boot | |||
119 | 137 | ||
120 | CPPFLAGS_vmlinux.lds := -traditional | 138 | CPPFLAGS_vmlinux.lds := -traditional |
121 | 139 | ||
140 | ifneq ($(KBUILD_SRC),) | ||
141 | incdir-prefix := $(srctree)/include/asm-sh/ | ||
142 | else | ||
143 | incdir-prefix := | ||
144 | endif | ||
145 | |||
122 | # Update machine arch and proc symlinks if something which affects | 146 | # Update machine arch and proc symlinks if something which affects |
123 | # them changed. We use .arch and .mach to indicate when they were | 147 | # them changed. We use .arch and .mach to indicate when they were |
124 | # updated last, otherwise make uses the target directory mtime. | 148 | # updated last, otherwise make uses the target directory mtime. |
125 | 149 | ||
126 | include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER | 150 | include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER |
127 | @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' | 151 | @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' |
128 | ifneq ($(KBUILD_SRC),) | 152 | $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi |
129 | $(Q)mkdir -p include/asm-sh | 153 | $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu |
130 | $(Q)ln -fsn $(srctree)/include/asm-sh/$(cpuincdir-y) include/asm-sh/cpu | ||
131 | else | ||
132 | $(Q)ln -fsn $(cpuincdir-y) include/asm-sh/cpu | ||
133 | endif | ||
134 | @touch $@ | 154 | @touch $@ |
135 | 155 | ||
156 | # Most boards have their own mach directories. For the ones that | ||
157 | # don't, just reference the parent directory so the semantics are | ||
158 | # kept roughly the same. | ||
159 | |||
136 | include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER | 160 | include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER |
137 | @echo ' SYMLINK include/asm-sh/mach -> include/asm-sh/$(incdir-y)' | 161 | @echo -n ' SYMLINK include/asm-sh/mach -> ' |
138 | ifneq ($(KBUILD_SRC),) | 162 | $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi |
139 | $(Q)mkdir -p include/asm-sh | 163 | $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ |
140 | $(Q)ln -fsn $(srctree)/include/asm-sh/$(incdir-y) include/asm-sh/mach | 164 | echo -e 'include/asm-sh/$(incdir-y)'; \ |
141 | else | 165 | ln -fsn $(incdir-prefix)$(incdir-y) \ |
142 | $(Q)ln -fsn $(incdir-y) include/asm-sh/mach | 166 | include/asm-sh/mach; \ |
143 | endif | 167 | else \ |
168 | echo -e 'include/asm-sh'; \ | ||
169 | ln -fsn $(incdir-prefix) include/asm-sh/mach; \ | ||
170 | fi | ||
144 | @touch $@ | 171 | @touch $@ |
145 | 172 | ||
146 | |||
147 | archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach | 173 | archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach |
148 | 174 | ||
149 | .PHONY: maketools FORCE | 175 | .PHONY: maketools FORCE |
diff --git a/arch/sh/boards/hp6xx/Makefile b/arch/sh/boards/hp6xx/Makefile new file mode 100644 index 000000000000..927fe0aa5dfa --- /dev/null +++ b/arch/sh/boards/hp6xx/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile for the HP6xx specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := mach.o setup.o | ||
6 | |||
diff --git a/arch/sh/boards/hp6xx/hp620/Makefile b/arch/sh/boards/hp6xx/hp620/Makefile deleted file mode 100644 index 20691dbce347..000000000000 --- a/arch/sh/boards/hp6xx/hp620/Makefile +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
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 deleted file mode 100644 index 0392d82b4a7b..000000000000 --- a/arch/sh/boards/hp6xx/hp620/mach.c +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
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 deleted file mode 100644 index 045fc5da7274..000000000000 --- a/arch/sh/boards/hp6xx/hp620/setup.c +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
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 deleted file mode 100644 index 0beef11d9b11..000000000000 --- a/arch/sh/boards/hp6xx/hp680/Makefile +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
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/hp690/Makefile b/arch/sh/boards/hp6xx/hp690/Makefile deleted file mode 100644 index fbbe95e75f83..000000000000 --- a/arch/sh/boards/hp6xx/hp690/Makefile +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
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 deleted file mode 100644 index 2a4c68783cd6..000000000000 --- a/arch/sh/boards/hp6xx/hp690/mach.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
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/hp6xx/hp680/mach.c b/arch/sh/boards/hp6xx/mach.c index d73486136045..08dbba910f74 100644 --- a/arch/sh/boards/hp6xx/hp680/mach.c +++ b/arch/sh/boards/hp6xx/mach.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/sh/boards/hp6xx/hp680/mach.c | 2 | * linux/arch/sh/boards/hp6xx/mach.c |
3 | * | 3 | * |
4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) | 4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) |
5 | * | 5 | * |
@@ -8,19 +8,12 @@ | |||
8 | * | 8 | * |
9 | * Machine vector for the HP680 | 9 | * Machine vector for the HP680 |
10 | */ | 10 | */ |
11 | |||
12 | #include <linux/init.h> | ||
13 | |||
14 | #include <asm/machvec.h> | 11 | #include <asm/machvec.h> |
15 | #include <asm/rtc.h> | 12 | #include <asm/hd64461.h> |
16 | #include <asm/machvec_init.h> | ||
17 | |||
18 | #include <asm/io.h> | 13 | #include <asm/io.h> |
19 | #include <asm/hd64461/hd64461.h> | ||
20 | #include <asm/hp6xx/io.h> | ||
21 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
22 | 15 | ||
23 | struct sh_machine_vector mv_hp680 __initmv = { | 16 | struct sh_machine_vector mv_hp6xx __initmv = { |
24 | .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, | 17 | .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, |
25 | 18 | ||
26 | .mv_inb = hd64461_inb, | 19 | .mv_inb = hd64461_inb, |
@@ -50,4 +43,4 @@ struct sh_machine_vector mv_hp680 __initmv = { | |||
50 | .mv_irq_demux = hd64461_irq_demux, | 43 | .mv_irq_demux = hd64461_irq_demux, |
51 | }; | 44 | }; |
52 | 45 | ||
53 | ALIAS_MV(hp680) | 46 | ALIAS_MV(hp6xx) |
diff --git a/arch/sh/boards/hp6xx/hp680/setup.c b/arch/sh/boards/hp6xx/setup.c index 4170190f2644..6d94a8e2e67a 100644 --- a/arch/sh/boards/hp6xx/hp680/setup.c +++ b/arch/sh/boards/hp6xx/setup.c | |||
@@ -11,18 +11,19 @@ | |||
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <asm/hd64461/hd64461.h> | ||
15 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | #include <asm/hd64461.h> | ||
16 | #include <asm/hp6xx/hp6xx.h> | 16 | #include <asm/hp6xx/hp6xx.h> |
17 | #include <asm/cpu/dac.h> | 17 | #include <asm/cpu/dac.h> |
18 | 18 | ||
19 | const char *get_system_type(void) | 19 | const char *get_system_type(void) |
20 | { | 20 | { |
21 | return "HP680"; | 21 | return "HP6xx"; |
22 | } | 22 | } |
23 | 23 | ||
24 | int __init platform_setup(void) | 24 | int __init platform_setup(void) |
25 | { | 25 | { |
26 | u8 v8; | ||
26 | u16 v; | 27 | u16 v; |
27 | v = inw(HD64461_STBCR); | 28 | v = inw(HD64461_STBCR); |
28 | v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | | 29 | v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | |
@@ -30,12 +31,25 @@ int __init platform_setup(void) | |||
30 | HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | | 31 | HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | |
31 | HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST | | 32 | HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST | |
32 | HD64461_STBCR_SAFECKE_IST; | 33 | HD64461_STBCR_SAFECKE_IST; |
34 | #ifndef CONFIG_HD64461_ENABLER | ||
35 | v |= HD64461_STBCR_SPC1ST; | ||
36 | #endif | ||
33 | outw(v, HD64461_STBCR); | 37 | outw(v, HD64461_STBCR); |
34 | v = inw(HD64461_GPADR); | 38 | v = inw(HD64461_GPADR); |
35 | v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; | 39 | v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; |
36 | outw(v, HD64461_GPADR); | 40 | outw(v, HD64461_GPADR); |
37 | 41 | ||
42 | outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR); | ||
43 | |||
44 | #ifndef CONFIG_HD64461_ENABLER | ||
45 | outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR); | ||
46 | #endif | ||
47 | |||
48 | sh_dac_output(0, DAC_SPEAKER_VOLUME); | ||
38 | sh_dac_disable(DAC_SPEAKER_VOLUME); | 49 | sh_dac_disable(DAC_SPEAKER_VOLUME); |
50 | v8 = ctrl_inb(DACR); | ||
51 | v8 &= ~DACR_DAE; | ||
52 | ctrl_outb(v8,DACR); | ||
39 | 53 | ||
40 | return 0; | 54 | return 0; |
41 | } | 55 | } |
diff --git a/arch/sh/boards/overdrive/Makefile b/arch/sh/boards/overdrive/Makefile index 1762b59e9279..245f03baf762 100644 --- a/arch/sh/boards/overdrive/Makefile +++ b/arch/sh/boards/overdrive/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the STMicroelectronics Overdrive specific parts of the kernel | 2 | # Makefile for the STMicroelectronics Overdrive specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := mach.o setup.o io.o irq.o led.o time.o | 5 | obj-y := mach.o setup.o io.o irq.o led.o |
6 | 6 | ||
7 | obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o | 7 | obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o |
8 | 8 | ||
diff --git a/arch/sh/boards/overdrive/setup.c b/arch/sh/boards/overdrive/setup.c index a36ce0284ed3..94f6165d33b8 100644 --- a/arch/sh/boards/overdrive/setup.c +++ b/arch/sh/boards/overdrive/setup.c | |||
@@ -17,8 +17,6 @@ | |||
17 | #include <asm/overdrive/overdrive.h> | 17 | #include <asm/overdrive/overdrive.h> |
18 | #include <asm/overdrive/fpga.h> | 18 | #include <asm/overdrive/fpga.h> |
19 | 19 | ||
20 | extern void od_time_init(void); | ||
21 | |||
22 | const char *get_system_type(void) | 20 | const char *get_system_type(void) |
23 | { | 21 | { |
24 | return "SH7750 Overdrive"; | 22 | return "SH7750 Overdrive"; |
@@ -31,11 +29,9 @@ int __init platform_setup(void) | |||
31 | { | 29 | { |
32 | #ifdef CONFIG_PCI | 30 | #ifdef CONFIG_PCI |
33 | init_overdrive_fpga(); | 31 | init_overdrive_fpga(); |
34 | galileo_init(); | 32 | galileo_init(); |
35 | #endif | 33 | #endif |
36 | 34 | ||
37 | board_time_init = od_time_init; | ||
38 | |||
39 | /* Enable RS232 receive buffers */ | 35 | /* Enable RS232 receive buffers */ |
40 | writel(0x1e, OVERDRIVE_CTRL); | 36 | writel(0x1e, OVERDRIVE_CTRL); |
41 | } | 37 | } |
diff --git a/arch/sh/boards/overdrive/time.c b/arch/sh/boards/overdrive/time.c deleted file mode 100644 index 68533690e097..000000000000 --- a/arch/sh/boards/overdrive/time.c +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
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/configs/hp680_defconfig b/arch/sh/configs/hp6xx_defconfig index c85d3655b53c..b36f102cec81 100644 --- a/arch/sh/configs/hp680_defconfig +++ b/arch/sh/configs/hp6xx_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-sh | 3 | # Linux kernel version: 2.6.15-sh |
4 | # Wed Mar 2 15:09:41 2005 | 4 | # Wed Jan 4 15:32:56 2006 |
5 | # | 5 | # |
6 | CONFIG_SUPERH=y | 6 | CONFIG_SUPERH=y |
7 | CONFIG_UID16=y | 7 | CONFIG_UID16=y |
@@ -17,31 +17,36 @@ CONFIG_EXPERIMENTAL=y | |||
17 | # CONFIG_CLEAN_COMPILE is not set | 17 | # CONFIG_CLEAN_COMPILE is not set |
18 | CONFIG_BROKEN=y | 18 | CONFIG_BROKEN=y |
19 | CONFIG_BROKEN_ON_SMP=y | 19 | CONFIG_BROKEN_ON_SMP=y |
20 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
20 | 21 | ||
21 | # | 22 | # |
22 | # General setup | 23 | # General setup |
23 | # | 24 | # |
24 | CONFIG_LOCALVERSION="" | 25 | CONFIG_LOCALVERSION="" |
26 | CONFIG_LOCALVERSION_AUTO=y | ||
25 | CONFIG_SWAP=y | 27 | CONFIG_SWAP=y |
26 | # CONFIG_SYSVIPC is not set | 28 | # CONFIG_SYSVIPC is not set |
27 | # CONFIG_BSD_PROCESS_ACCT is not set | 29 | # CONFIG_BSD_PROCESS_ACCT is not set |
28 | # CONFIG_SYSCTL is not set | 30 | # CONFIG_SYSCTL is not set |
29 | # CONFIG_AUDIT is not set | 31 | CONFIG_HOTPLUG=y |
30 | CONFIG_LOG_BUF_SHIFT=14 | ||
31 | # CONFIG_HOTPLUG is not set | ||
32 | # CONFIG_IKCONFIG is not set | 32 | # CONFIG_IKCONFIG is not set |
33 | CONFIG_INITRAMFS_SOURCE="" | ||
34 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
33 | # CONFIG_EMBEDDED is not set | 35 | # CONFIG_EMBEDDED is not set |
34 | CONFIG_KALLSYMS=y | 36 | CONFIG_KALLSYMS=y |
35 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
40 | CONFIG_BASE_FULL=y | ||
36 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
37 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
38 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
39 | CONFIG_SHMEM=y | 43 | CONFIG_SHMEM=y |
40 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 44 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
41 | CONFIG_CC_ALIGN_LABELS=0 | 45 | CONFIG_CC_ALIGN_LABELS=0 |
42 | CONFIG_CC_ALIGN_LOOPS=0 | 46 | CONFIG_CC_ALIGN_LOOPS=0 |
43 | CONFIG_CC_ALIGN_JUMPS=0 | 47 | CONFIG_CC_ALIGN_JUMPS=0 |
44 | # CONFIG_TINY_SHMEM is not set | 48 | # CONFIG_TINY_SHMEM is not set |
49 | CONFIG_BASE_SMALL=0 | ||
45 | 50 | ||
46 | # | 51 | # |
47 | # Loadable module support | 52 | # Loadable module support |
@@ -49,6 +54,24 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
49 | # CONFIG_MODULES is not set | 54 | # CONFIG_MODULES is not set |
50 | 55 | ||
51 | # | 56 | # |
57 | # Block layer | ||
58 | # | ||
59 | # CONFIG_LBD is not set | ||
60 | |||
61 | # | ||
62 | # IO Schedulers | ||
63 | # | ||
64 | CONFIG_IOSCHED_NOOP=y | ||
65 | CONFIG_IOSCHED_AS=y | ||
66 | CONFIG_IOSCHED_DEADLINE=y | ||
67 | CONFIG_IOSCHED_CFQ=y | ||
68 | CONFIG_DEFAULT_AS=y | ||
69 | # CONFIG_DEFAULT_DEADLINE is not set | ||
70 | # CONFIG_DEFAULT_CFQ is not set | ||
71 | # CONFIG_DEFAULT_NOOP is not set | ||
72 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
73 | |||
74 | # | ||
52 | # System type | 75 | # System type |
53 | # | 76 | # |
54 | # CONFIG_SH_SOLUTION_ENGINE is not set | 77 | # CONFIG_SH_SOLUTION_ENGINE is not set |
@@ -58,9 +81,7 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
58 | # CONFIG_SH_7751_SYSTEMH is not set | 81 | # CONFIG_SH_7751_SYSTEMH is not set |
59 | # CONFIG_SH_STB1_HARP is not set | 82 | # CONFIG_SH_STB1_HARP is not set |
60 | # CONFIG_SH_STB1_OVERDRIVE is not set | 83 | # CONFIG_SH_STB1_OVERDRIVE is not set |
61 | # CONFIG_SH_HP620 is not set | 84 | CONFIG_SH_HP6XX=y |
62 | CONFIG_SH_HP680=y | ||
63 | # CONFIG_SH_HP690 is not set | ||
64 | # CONFIG_SH_CQREEK is not set | 85 | # CONFIG_SH_CQREEK is not set |
65 | # CONFIG_SH_DMIDA is not set | 86 | # CONFIG_SH_DMIDA is not set |
66 | # CONFIG_SH_EC3104 is not set | 87 | # CONFIG_SH_EC3104 is not set |
@@ -77,43 +98,90 @@ CONFIG_SH_HP680=y | |||
77 | # CONFIG_SH_RTS7751R2D is not set | 98 | # CONFIG_SH_RTS7751R2D is not set |
78 | # CONFIG_SH_EDOSK7705 is not set | 99 | # CONFIG_SH_EDOSK7705 is not set |
79 | # CONFIG_SH_SH4202_MICRODEV is not set | 100 | # CONFIG_SH_SH4202_MICRODEV is not set |
101 | # CONFIG_SH_LANDISK is not set | ||
102 | # CONFIG_SH_TITAN is not set | ||
80 | # CONFIG_SH_UNKNOWN is not set | 103 | # CONFIG_SH_UNKNOWN is not set |
81 | # CONFIG_CPU_SH2 is not set | 104 | |
105 | # | ||
106 | # Processor selection | ||
107 | # | ||
82 | CONFIG_CPU_SH3=y | 108 | CONFIG_CPU_SH3=y |
83 | # CONFIG_CPU_SH4 is not set | 109 | |
110 | # | ||
111 | # SH-2 Processor Support | ||
112 | # | ||
84 | # CONFIG_CPU_SUBTYPE_SH7604 is not set | 113 | # CONFIG_CPU_SUBTYPE_SH7604 is not set |
114 | |||
115 | # | ||
116 | # SH-3 Processor Support | ||
117 | # | ||
85 | # CONFIG_CPU_SUBTYPE_SH7300 is not set | 118 | # CONFIG_CPU_SUBTYPE_SH7300 is not set |
86 | # CONFIG_CPU_SUBTYPE_SH7705 is not set | 119 | # CONFIG_CPU_SUBTYPE_SH7705 is not set |
87 | # CONFIG_CPU_SUBTYPE_SH7707 is not set | 120 | # CONFIG_CPU_SUBTYPE_SH7707 is not set |
88 | # CONFIG_CPU_SUBTYPE_SH7708 is not set | 121 | # CONFIG_CPU_SUBTYPE_SH7708 is not set |
89 | CONFIG_CPU_SUBTYPE_SH7709=y | 122 | CONFIG_CPU_SUBTYPE_SH7709=y |
123 | |||
124 | # | ||
125 | # SH-4 Processor Support | ||
126 | # | ||
90 | # CONFIG_CPU_SUBTYPE_SH7750 is not set | 127 | # CONFIG_CPU_SUBTYPE_SH7750 is not set |
128 | # CONFIG_CPU_SUBTYPE_SH7091 is not set | ||
129 | # CONFIG_CPU_SUBTYPE_SH7750R is not set | ||
130 | # CONFIG_CPU_SUBTYPE_SH7750S is not set | ||
91 | # CONFIG_CPU_SUBTYPE_SH7751 is not set | 131 | # CONFIG_CPU_SUBTYPE_SH7751 is not set |
132 | # CONFIG_CPU_SUBTYPE_SH7751R is not set | ||
92 | # CONFIG_CPU_SUBTYPE_SH7760 is not set | 133 | # CONFIG_CPU_SUBTYPE_SH7760 is not set |
93 | # CONFIG_CPU_SUBTYPE_SH73180 is not set | 134 | # CONFIG_CPU_SUBTYPE_SH4_202 is not set |
135 | |||
136 | # | ||
137 | # ST40 Processor Support | ||
138 | # | ||
94 | # CONFIG_CPU_SUBTYPE_ST40STB1 is not set | 139 | # CONFIG_CPU_SUBTYPE_ST40STB1 is not set |
95 | # CONFIG_CPU_SUBTYPE_ST40GX1 is not set | 140 | # CONFIG_CPU_SUBTYPE_ST40GX1 is not set |
96 | # CONFIG_CPU_SUBTYPE_SH4_202 is not set | 141 | |
142 | # | ||
143 | # SH-4A Processor Support | ||
144 | # | ||
145 | # CONFIG_CPU_SUBTYPE_SH73180 is not set | ||
146 | # CONFIG_CPU_SUBTYPE_SH7770 is not set | ||
147 | # CONFIG_CPU_SUBTYPE_SH7780 is not set | ||
148 | |||
149 | # | ||
150 | # Memory management options | ||
151 | # | ||
97 | CONFIG_MMU=y | 152 | CONFIG_MMU=y |
98 | # CONFIG_CMDLINE_BOOL is not set | 153 | CONFIG_SELECT_MEMORY_MODEL=y |
154 | CONFIG_FLATMEM_MANUAL=y | ||
155 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
156 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
157 | CONFIG_FLATMEM=y | ||
158 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
159 | # CONFIG_SPARSEMEM_STATIC is not set | ||
160 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
161 | |||
162 | # | ||
163 | # Cache configuration | ||
164 | # | ||
165 | # CONFIG_SH_DIRECT_MAPPED is not set | ||
166 | # CONFIG_SH_WRITETHROUGH is not set | ||
167 | # CONFIG_SH_OCRAM is not set | ||
99 | CONFIG_MEMORY_START=0x0c000000 | 168 | CONFIG_MEMORY_START=0x0c000000 |
100 | CONFIG_MEMORY_SIZE=0x00400000 | 169 | CONFIG_MEMORY_SIZE=0x00400000 |
101 | CONFIG_MEMORY_SET=y | 170 | |
102 | # CONFIG_MEMORY_OVERRIDE is not set | 171 | # |
172 | # Processor features | ||
173 | # | ||
174 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
103 | CONFIG_SH_RTC=y | 175 | CONFIG_SH_RTC=y |
104 | # CONFIG_SH_DSP is not set | 176 | # CONFIG_SH_DSP is not set |
105 | CONFIG_SH_ADC=y | 177 | CONFIG_SH_ADC=y |
106 | CONFIG_SH_HP600=y | 178 | |
107 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | 179 | # |
108 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | 180 | # Timer support |
109 | CONFIG_CPU_LITTLE_ENDIAN=y | 181 | # |
110 | # CONFIG_PREEMPT is not set | 182 | CONFIG_SH_TMU=y |
111 | # CONFIG_UBC_WAKEUP is not set | 183 | CONFIG_SH_PCLK_FREQ_BOOL=y |
112 | # CONFIG_SH_WRITETHROUGH is not set | 184 | CONFIG_SH_PCLK_FREQ=22110000 |
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 | 185 | ||
118 | # | 186 | # |
119 | # CPU Frequency scaling | 187 | # CPU Frequency scaling |
@@ -123,7 +191,10 @@ CONFIG_SH_PCLK_FREQ=1193182 | |||
123 | # | 191 | # |
124 | # DMA support | 192 | # DMA support |
125 | # | 193 | # |
126 | # CONFIG_SH_DMA is not set | 194 | CONFIG_SH_DMA=y |
195 | CONFIG_NR_ONCHIP_DMA_CHANNELS=4 | ||
196 | # CONFIG_NR_DMA_CHANNELS_BOOL is not set | ||
197 | # CONFIG_DMA_PAGE_OPS is not set | ||
127 | 198 | ||
128 | # | 199 | # |
129 | # Companion Chips | 200 | # Companion Chips |
@@ -132,21 +203,47 @@ CONFIG_HD6446X_SERIES=y | |||
132 | CONFIG_HD64461=y | 203 | CONFIG_HD64461=y |
133 | # CONFIG_HD64465 is not set | 204 | # CONFIG_HD64465 is not set |
134 | CONFIG_HD64461_IRQ=36 | 205 | CONFIG_HD64461_IRQ=36 |
135 | # CONFIG_HD64461_ENABLER is not set | 206 | CONFIG_HD64461_IOBASE=0xb0000000 |
207 | CONFIG_HD64461_ENABLER=y | ||
208 | |||
209 | # | ||
210 | # Kernel features | ||
211 | # | ||
212 | # CONFIG_KEXEC is not set | ||
213 | # CONFIG_PREEMPT is not set | ||
214 | # CONFIG_SMP is not set | ||
136 | 215 | ||
137 | # | 216 | # |
138 | # Bus options (PCI, PCMCIA, EISA, MCA, ISA) | 217 | # Boot options |
139 | # | 218 | # |
219 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
220 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
221 | # CONFIG_UBC_WAKEUP is not set | ||
222 | # CONFIG_CMDLINE_BOOL is not set | ||
223 | |||
224 | # | ||
225 | # Bus options | ||
226 | # | ||
227 | CONFIG_ISA=y | ||
140 | # CONFIG_PCI is not set | 228 | # CONFIG_PCI is not set |
141 | 229 | ||
142 | # | 230 | # |
143 | # PCCARD (PCMCIA/CardBus) support | 231 | # PCCARD (PCMCIA/CardBus) support |
144 | # | 232 | # |
145 | # CONFIG_PCCARD is not set | 233 | CONFIG_PCCARD=y |
234 | # CONFIG_PCMCIA_DEBUG is not set | ||
235 | CONFIG_PCMCIA=y | ||
236 | CONFIG_PCMCIA_LOAD_CIS=y | ||
237 | CONFIG_PCMCIA_IOCTL=y | ||
146 | 238 | ||
147 | # | 239 | # |
148 | # PC-card bridges | 240 | # PC-card bridges |
149 | # | 241 | # |
242 | # CONFIG_I82365 is not set | ||
243 | # CONFIG_TCIC is not set | ||
244 | CONFIG_HD64461_PCMCIA=y | ||
245 | CONFIG_HD64461_PCMCIA_SOCKETS=1 | ||
246 | CONFIG_PCMCIA_PROBE=y | ||
150 | 247 | ||
151 | # | 248 | # |
152 | # PCI Hotplug Support | 249 | # PCI Hotplug Support |
@@ -160,9 +257,9 @@ CONFIG_BINFMT_ELF=y | |||
160 | # CONFIG_BINFMT_MISC is not set | 257 | # CONFIG_BINFMT_MISC is not set |
161 | 258 | ||
162 | # | 259 | # |
163 | # SH initrd options | 260 | # Networking |
164 | # | 261 | # |
165 | # CONFIG_EMBEDDED_RAMDISK is not set | 262 | # CONFIG_NET is not set |
166 | 263 | ||
167 | # | 264 | # |
168 | # Device Drivers | 265 | # Device Drivers |
@@ -173,7 +270,11 @@ CONFIG_BINFMT_ELF=y | |||
173 | # | 270 | # |
174 | # CONFIG_STANDALONE is not set | 271 | # CONFIG_STANDALONE is not set |
175 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 272 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
176 | # CONFIG_FW_LOADER is not set | 273 | CONFIG_FW_LOADER=y |
274 | |||
275 | # | ||
276 | # Connector - unified userspace <-> kernelspace linker | ||
277 | # | ||
177 | 278 | ||
178 | # | 279 | # |
179 | # Memory Technology Devices (MTD) | 280 | # Memory Technology Devices (MTD) |
@@ -188,30 +289,20 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y | |||
188 | # | 289 | # |
189 | # Plug and Play support | 290 | # Plug and Play support |
190 | # | 291 | # |
292 | # CONFIG_PNP is not set | ||
191 | 293 | ||
192 | # | 294 | # |
193 | # Block devices | 295 | # Block devices |
194 | # | 296 | # |
195 | # CONFIG_BLK_DEV_FD is not set | ||
196 | # CONFIG_BLK_DEV_COW_COMMON is not set | 297 | # CONFIG_BLK_DEV_COW_COMMON is not set |
197 | # CONFIG_BLK_DEV_LOOP is not set | 298 | # CONFIG_BLK_DEV_LOOP is not set |
198 | CONFIG_BLK_DEV_RAM=y | 299 | CONFIG_BLK_DEV_RAM=y |
199 | CONFIG_BLK_DEV_RAM_COUNT=16 | 300 | CONFIG_BLK_DEV_RAM_COUNT=16 |
200 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 301 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
201 | CONFIG_BLK_DEV_INITRD=y | 302 | CONFIG_BLK_DEV_INITRD=y |
202 | CONFIG_INITRAMFS_SOURCE="" | ||
203 | # CONFIG_LBD is not set | ||
204 | # CONFIG_CDROM_PKTCDVD is not set | 303 | # CONFIG_CDROM_PKTCDVD is not set |
205 | 304 | ||
206 | # | 305 | # |
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 | 306 | # ATA/ATAPI/MFM/RLL support |
216 | # | 307 | # |
217 | CONFIG_IDE=y | 308 | CONFIG_IDE=y |
@@ -224,6 +315,7 @@ CONFIG_BLK_DEV_IDE=y | |||
224 | # CONFIG_BLK_DEV_IDE_SATA is not set | 315 | # CONFIG_BLK_DEV_IDE_SATA is not set |
225 | CONFIG_BLK_DEV_IDEDISK=y | 316 | CONFIG_BLK_DEV_IDEDISK=y |
226 | # CONFIG_IDEDISK_MULTI_MODE is not set | 317 | # CONFIG_IDEDISK_MULTI_MODE is not set |
318 | # CONFIG_BLK_DEV_IDECS is not set | ||
227 | # CONFIG_BLK_DEV_IDECD is not set | 319 | # CONFIG_BLK_DEV_IDECD is not set |
228 | # CONFIG_BLK_DEV_IDETAPE is not set | 320 | # CONFIG_BLK_DEV_IDETAPE is not set |
229 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | 321 | # CONFIG_BLK_DEV_IDEFLOPPY is not set |
@@ -235,6 +327,7 @@ CONFIG_BLK_DEV_IDEDISK=y | |||
235 | CONFIG_IDE_GENERIC=y | 327 | CONFIG_IDE_GENERIC=y |
236 | CONFIG_IDE_SH=y | 328 | CONFIG_IDE_SH=y |
237 | # CONFIG_IDE_ARM is not set | 329 | # CONFIG_IDE_ARM is not set |
330 | # CONFIG_IDE_CHIPSETS is not set | ||
238 | # CONFIG_BLK_DEV_IDEDMA is not set | 331 | # CONFIG_BLK_DEV_IDEDMA is not set |
239 | # CONFIG_IDEDMA_AUTO is not set | 332 | # CONFIG_IDEDMA_AUTO is not set |
240 | # CONFIG_BLK_DEV_HD is not set | 333 | # CONFIG_BLK_DEV_HD is not set |
@@ -242,9 +335,15 @@ CONFIG_IDE_SH=y | |||
242 | # | 335 | # |
243 | # SCSI device support | 336 | # SCSI device support |
244 | # | 337 | # |
338 | # CONFIG_RAID_ATTRS is not set | ||
245 | # CONFIG_SCSI is not set | 339 | # CONFIG_SCSI is not set |
246 | 340 | ||
247 | # | 341 | # |
342 | # Old CD-ROM drivers (not SCSI, not IDE) | ||
343 | # | ||
344 | # CONFIG_CD_NO_IDESCSI is not set | ||
345 | |||
346 | # | ||
248 | # Multi-device support (RAID and LVM) | 347 | # Multi-device support (RAID and LVM) |
249 | # | 348 | # |
250 | # CONFIG_MD is not set | 349 | # CONFIG_MD is not set |
@@ -252,6 +351,7 @@ CONFIG_IDE_SH=y | |||
252 | # | 351 | # |
253 | # Fusion MPT device support | 352 | # Fusion MPT device support |
254 | # | 353 | # |
354 | # CONFIG_FUSION is not set | ||
255 | 355 | ||
256 | # | 356 | # |
257 | # IEEE 1394 (FireWire) support | 357 | # IEEE 1394 (FireWire) support |
@@ -263,9 +363,8 @@ CONFIG_IDE_SH=y | |||
263 | # | 363 | # |
264 | 364 | ||
265 | # | 365 | # |
266 | # Networking support | 366 | # Network device support |
267 | # | 367 | # |
268 | # CONFIG_NET is not set | ||
269 | # CONFIG_NETPOLL is not set | 368 | # CONFIG_NETPOLL is not set |
270 | # CONFIG_NET_POLL_CONTROLLER is not set | 369 | # CONFIG_NET_POLL_CONTROLLER is not set |
271 | 370 | ||
@@ -296,17 +395,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
296 | # CONFIG_INPUT_EVBUG is not set | 395 | # CONFIG_INPUT_EVBUG is not set |
297 | 396 | ||
298 | # | 397 | # |
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 | 398 | # Input Device Drivers |
311 | # | 399 | # |
312 | # CONFIG_INPUT_KEYBOARD is not set | 400 | # CONFIG_INPUT_KEYBOARD is not set |
@@ -316,6 +404,15 @@ CONFIG_SERIO=y | |||
316 | # CONFIG_INPUT_MISC is not set | 404 | # CONFIG_INPUT_MISC is not set |
317 | 405 | ||
318 | # | 406 | # |
407 | # Hardware I/O ports | ||
408 | # | ||
409 | CONFIG_SERIO=y | ||
410 | # CONFIG_SERIO_I8042 is not set | ||
411 | # CONFIG_SERIO_SERPORT is not set | ||
412 | # CONFIG_SERIO_RAW is not set | ||
413 | # CONFIG_GAMEPORT is not set | ||
414 | |||
415 | # | ||
319 | # Character devices | 416 | # Character devices |
320 | # | 417 | # |
321 | CONFIG_VT=y | 418 | CONFIG_VT=y |
@@ -353,10 +450,22 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
353 | # | 450 | # |
354 | # Ftape, the floppy tape device driver | 451 | # Ftape, the floppy tape device driver |
355 | # | 452 | # |
356 | # CONFIG_DRM is not set | 453 | |
454 | # | ||
455 | # PCMCIA character devices | ||
456 | # | ||
457 | # CONFIG_SYNCLINK_CS is not set | ||
458 | # CONFIG_CARDMAN_4000 is not set | ||
459 | # CONFIG_CARDMAN_4040 is not set | ||
357 | # CONFIG_RAW_DRIVER is not set | 460 | # CONFIG_RAW_DRIVER is not set |
358 | 461 | ||
359 | # | 462 | # |
463 | # TPM devices | ||
464 | # | ||
465 | # CONFIG_TCG_TPM is not set | ||
466 | # CONFIG_TELCLOCK is not set | ||
467 | |||
468 | # | ||
360 | # I2C support | 469 | # I2C support |
361 | # | 470 | # |
362 | # CONFIG_I2C is not set | 471 | # CONFIG_I2C is not set |
@@ -367,10 +476,21 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
367 | # CONFIG_W1 is not set | 476 | # CONFIG_W1 is not set |
368 | 477 | ||
369 | # | 478 | # |
479 | # Hardware Monitoring support | ||
480 | # | ||
481 | CONFIG_HWMON=y | ||
482 | # CONFIG_HWMON_VID is not set | ||
483 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
484 | |||
485 | # | ||
370 | # Misc devices | 486 | # Misc devices |
371 | # | 487 | # |
372 | 488 | ||
373 | # | 489 | # |
490 | # Multimedia Capabilities Port drivers | ||
491 | # | ||
492 | |||
493 | # | ||
374 | # Multimedia devices | 494 | # Multimedia devices |
375 | # | 495 | # |
376 | # CONFIG_VIDEO_DEV is not set | 496 | # CONFIG_VIDEO_DEV is not set |
@@ -383,27 +503,35 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
383 | # Graphics support | 503 | # Graphics support |
384 | # | 504 | # |
385 | CONFIG_FB=y | 505 | CONFIG_FB=y |
506 | CONFIG_FB_CFB_FILLRECT=y | ||
507 | CONFIG_FB_CFB_COPYAREA=y | ||
508 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
509 | # CONFIG_FB_MACMODES is not set | ||
386 | # CONFIG_FB_MODE_HELPERS is not set | 510 | # CONFIG_FB_MODE_HELPERS is not set |
387 | # CONFIG_FB_TILEBLITTING is not set | 511 | # CONFIG_FB_TILEBLITTING is not set |
388 | # CONFIG_FB_EPSON1355 is not set | 512 | # CONFIG_FB_EPSON1355 is not set |
513 | # CONFIG_FB_S1D13XXX is not set | ||
389 | CONFIG_FB_HIT=y | 514 | CONFIG_FB_HIT=y |
390 | # CONFIG_FB_VIRTUAL is not set | 515 | # CONFIG_FB_VIRTUAL is not set |
391 | 516 | ||
392 | # | 517 | # |
393 | # Console display driver support | 518 | # Console display driver support |
394 | # | 519 | # |
395 | # CONFIG_VGA_CONSOLE is not set | 520 | # CONFIG_MDA_CONSOLE is not set |
396 | CONFIG_DUMMY_CONSOLE=y | 521 | CONFIG_DUMMY_CONSOLE=y |
397 | CONFIG_FRAMEBUFFER_CONSOLE=y | 522 | CONFIG_FRAMEBUFFER_CONSOLE=y |
523 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
398 | CONFIG_FONTS=y | 524 | CONFIG_FONTS=y |
399 | # CONFIG_FONT_8x8 is not set | 525 | # CONFIG_FONT_8x8 is not set |
400 | # CONFIG_FONT_8x16 is not set | 526 | # CONFIG_FONT_8x16 is not set |
401 | # CONFIG_FONT_6x11 is not set | 527 | # CONFIG_FONT_6x11 is not set |
528 | # CONFIG_FONT_7x14 is not set | ||
402 | CONFIG_FONT_PEARL_8x8=y | 529 | CONFIG_FONT_PEARL_8x8=y |
403 | # CONFIG_FONT_ACORN_8x8 is not set | 530 | # CONFIG_FONT_ACORN_8x8 is not set |
404 | # CONFIG_FONT_MINI_4x6 is not set | 531 | # CONFIG_FONT_MINI_4x6 is not set |
405 | # CONFIG_FONT_SUN8x16 is not set | 532 | # CONFIG_FONT_SUN8x16 is not set |
406 | # CONFIG_FONT_SUN12x22 is not set | 533 | # CONFIG_FONT_SUN12x22 is not set |
534 | # CONFIG_FONT_10x18 is not set | ||
407 | 535 | ||
408 | # | 536 | # |
409 | # Logo configuration | 537 | # Logo configuration |
@@ -414,7 +542,22 @@ CONFIG_FONT_PEARL_8x8=y | |||
414 | # | 542 | # |
415 | # Sound | 543 | # Sound |
416 | # | 544 | # |
417 | # CONFIG_SOUND is not set | 545 | CONFIG_SOUND=y |
546 | |||
547 | # | ||
548 | # Advanced Linux Sound Architecture | ||
549 | # | ||
550 | # CONFIG_SND is not set | ||
551 | |||
552 | # | ||
553 | # Open Sound System | ||
554 | # | ||
555 | CONFIG_SOUND_PRIME=y | ||
556 | # CONFIG_OBSOLETE_OSS_DRIVER is not set | ||
557 | # CONFIG_SOUND_MSNDCLAS is not set | ||
558 | # CONFIG_SOUND_MSNDPIN is not set | ||
559 | CONFIG_SOUND_SH_DAC_AUDIO=y | ||
560 | CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL=1 | ||
418 | 561 | ||
419 | # | 562 | # |
420 | # USB support | 563 | # USB support |
@@ -423,7 +566,7 @@ CONFIG_FONT_PEARL_8x8=y | |||
423 | # CONFIG_USB_ARCH_HAS_OHCI is not set | 566 | # CONFIG_USB_ARCH_HAS_OHCI is not set |
424 | 567 | ||
425 | # | 568 | # |
426 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | 569 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' |
427 | # | 570 | # |
428 | 571 | ||
429 | # | 572 | # |
@@ -442,25 +585,29 @@ CONFIG_FONT_PEARL_8x8=y | |||
442 | # CONFIG_INFINIBAND is not set | 585 | # CONFIG_INFINIBAND is not set |
443 | 586 | ||
444 | # | 587 | # |
588 | # SN Devices | ||
589 | # | ||
590 | |||
591 | # | ||
445 | # File systems | 592 | # File systems |
446 | # | 593 | # |
447 | CONFIG_EXT2_FS=y | 594 | CONFIG_EXT2_FS=y |
448 | # CONFIG_EXT2_FS_XATTR is not set | 595 | # CONFIG_EXT2_FS_XATTR is not set |
596 | # CONFIG_EXT2_FS_XIP is not set | ||
449 | # CONFIG_EXT3_FS is not set | 597 | # CONFIG_EXT3_FS is not set |
450 | # CONFIG_JBD is not set | 598 | # CONFIG_JBD is not set |
451 | # CONFIG_REISERFS_FS is not set | 599 | # CONFIG_REISERFS_FS is not set |
452 | # CONFIG_JFS_FS is not set | 600 | # CONFIG_JFS_FS is not set |
453 | 601 | # CONFIG_FS_POSIX_ACL is not set | |
454 | # | ||
455 | # XFS support | ||
456 | # | ||
457 | # CONFIG_XFS_FS is not set | 602 | # CONFIG_XFS_FS is not set |
458 | # CONFIG_MINIX_FS is not set | 603 | # CONFIG_MINIX_FS is not set |
459 | # CONFIG_ROMFS_FS is not set | 604 | # CONFIG_ROMFS_FS is not set |
605 | CONFIG_INOTIFY=y | ||
460 | # CONFIG_QUOTA is not set | 606 | # CONFIG_QUOTA is not set |
461 | CONFIG_DNOTIFY=y | 607 | CONFIG_DNOTIFY=y |
462 | # CONFIG_AUTOFS_FS is not set | 608 | # CONFIG_AUTOFS_FS is not set |
463 | # CONFIG_AUTOFS4_FS is not set | 609 | # CONFIG_AUTOFS4_FS is not set |
610 | # CONFIG_FUSE_FS is not set | ||
464 | 611 | ||
465 | # | 612 | # |
466 | # CD-ROM/DVD Filesystems | 613 | # CD-ROM/DVD Filesystems |
@@ -471,8 +618,11 @@ CONFIG_DNOTIFY=y | |||
471 | # | 618 | # |
472 | # DOS/FAT/NT Filesystems | 619 | # DOS/FAT/NT Filesystems |
473 | # | 620 | # |
621 | CONFIG_FAT_FS=y | ||
474 | # CONFIG_MSDOS_FS is not set | 622 | # CONFIG_MSDOS_FS is not set |
475 | # CONFIG_VFAT_FS is not set | 623 | CONFIG_VFAT_FS=y |
624 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
625 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
476 | # CONFIG_NTFS_FS is not set | 626 | # CONFIG_NTFS_FS is not set |
477 | 627 | ||
478 | # | 628 | # |
@@ -481,14 +631,11 @@ CONFIG_DNOTIFY=y | |||
481 | CONFIG_PROC_FS=y | 631 | CONFIG_PROC_FS=y |
482 | CONFIG_PROC_KCORE=y | 632 | CONFIG_PROC_KCORE=y |
483 | CONFIG_SYSFS=y | 633 | 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 | 634 | # CONFIG_TMPFS is not set |
489 | # CONFIG_HUGETLBFS is not set | 635 | # CONFIG_HUGETLBFS is not set |
490 | # CONFIG_HUGETLB_PAGE is not set | 636 | # CONFIG_HUGETLB_PAGE is not set |
491 | CONFIG_RAMFS=y | 637 | CONFIG_RAMFS=y |
638 | # CONFIG_RELAYFS_FS is not set | ||
492 | 639 | ||
493 | # | 640 | # |
494 | # Miscellaneous filesystems | 641 | # Miscellaneous filesystems |
@@ -516,7 +663,46 @@ CONFIG_MSDOS_PARTITION=y | |||
516 | # | 663 | # |
517 | # Native Language Support | 664 | # Native Language Support |
518 | # | 665 | # |
519 | # CONFIG_NLS is not set | 666 | CONFIG_NLS=y |
667 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
668 | # CONFIG_NLS_CODEPAGE_437 is not set | ||
669 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
670 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
671 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
672 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
673 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
674 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
675 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
676 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
677 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
678 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
679 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
680 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
681 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
682 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
683 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
684 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
685 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
686 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
687 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
688 | # CONFIG_NLS_ISO8859_8 is not set | ||
689 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
690 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
691 | # CONFIG_NLS_ASCII is not set | ||
692 | # CONFIG_NLS_ISO8859_1 is not set | ||
693 | # CONFIG_NLS_ISO8859_2 is not set | ||
694 | # CONFIG_NLS_ISO8859_3 is not set | ||
695 | # CONFIG_NLS_ISO8859_4 is not set | ||
696 | # CONFIG_NLS_ISO8859_5 is not set | ||
697 | # CONFIG_NLS_ISO8859_6 is not set | ||
698 | # CONFIG_NLS_ISO8859_7 is not set | ||
699 | # CONFIG_NLS_ISO8859_9 is not set | ||
700 | # CONFIG_NLS_ISO8859_13 is not set | ||
701 | # CONFIG_NLS_ISO8859_14 is not set | ||
702 | # CONFIG_NLS_ISO8859_15 is not set | ||
703 | # CONFIG_NLS_KOI8_R is not set | ||
704 | # CONFIG_NLS_KOI8_U is not set | ||
705 | # CONFIG_NLS_UTF8 is not set | ||
520 | 706 | ||
521 | # | 707 | # |
522 | # Profiling support | 708 | # Profiling support |
@@ -526,7 +712,9 @@ CONFIG_MSDOS_PARTITION=y | |||
526 | # | 712 | # |
527 | # Kernel hacking | 713 | # Kernel hacking |
528 | # | 714 | # |
715 | # CONFIG_PRINTK_TIME is not set | ||
529 | # CONFIG_DEBUG_KERNEL is not set | 716 | # CONFIG_DEBUG_KERNEL is not set |
717 | CONFIG_LOG_BUF_SHIFT=14 | ||
530 | # CONFIG_FRAME_POINTER is not set | 718 | # CONFIG_FRAME_POINTER is not set |
531 | # CONFIG_SH_STANDARD_BIOS is not set | 719 | # CONFIG_SH_STANDARD_BIOS is not set |
532 | # CONFIG_KGDB is not set | 720 | # CONFIG_KGDB is not set |
@@ -550,5 +738,6 @@ CONFIG_MSDOS_PARTITION=y | |||
550 | # Library routines | 738 | # Library routines |
551 | # | 739 | # |
552 | # CONFIG_CRC_CCITT is not set | 740 | # CONFIG_CRC_CCITT is not set |
741 | # CONFIG_CRC16 is not set | ||
553 | CONFIG_CRC32=y | 742 | CONFIG_CRC32=y |
554 | # CONFIG_LIBCRC32C is not set | 743 | # CONFIG_LIBCRC32C is not set |
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index 96e3036ec2bb..47c3e837599b 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SuperH-specific DMA management API | 4 | * SuperH-specific DMA management API |
5 | * | 5 | * |
6 | * Copyright (C) 2003, 2004 Paul Mundt | 6 | * Copyright (C) 2003, 2004, 2005 Paul Mundt |
7 | * | 7 | * |
8 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * This file is subject to the terms and conditions of the GNU General Public |
9 | * License. See the file "COPYING" in the main directory of this archive | 9 | * License. See the file "COPYING" in the main directory of this archive |
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
16 | #include <linux/proc_fs.h> | 16 | #include <linux/proc_fs.h> |
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/platform_device.h> | ||
18 | #include <asm/dma.h> | 19 | #include <asm/dma.h> |
19 | 20 | ||
20 | DEFINE_SPINLOCK(dma_spin_lock); | 21 | DEFINE_SPINLOCK(dma_spin_lock); |
@@ -55,16 +56,14 @@ static LIST_HEAD(registered_dmac_list); | |||
55 | 56 | ||
56 | struct dma_info *get_dma_info(unsigned int chan) | 57 | struct dma_info *get_dma_info(unsigned int chan) |
57 | { | 58 | { |
58 | struct list_head *pos, *tmp; | 59 | struct dma_info *info; |
59 | unsigned int total = 0; | 60 | unsigned int total = 0; |
60 | 61 | ||
61 | /* | 62 | /* |
62 | * Look for each DMAC's range to determine who the owner of | 63 | * Look for each DMAC's range to determine who the owner of |
63 | * the channel is. | 64 | * the channel is. |
64 | */ | 65 | */ |
65 | list_for_each_safe(pos, tmp, ®istered_dmac_list) { | 66 | list_for_each_entry(info, ®istered_dmac_list, list) { |
66 | struct dma_info *info = list_entry(pos, struct dma_info, list); | ||
67 | |||
68 | total += info->nr_channels; | 67 | total += info->nr_channels; |
69 | if (chan > total) | 68 | if (chan > total) |
70 | continue; | 69 | continue; |
@@ -75,6 +74,20 @@ struct dma_info *get_dma_info(unsigned int chan) | |||
75 | return NULL; | 74 | return NULL; |
76 | } | 75 | } |
77 | 76 | ||
77 | static unsigned int get_nr_channels(void) | ||
78 | { | ||
79 | struct dma_info *info; | ||
80 | unsigned int nr = 0; | ||
81 | |||
82 | if (unlikely(list_empty(®istered_dmac_list))) | ||
83 | return nr; | ||
84 | |||
85 | list_for_each_entry(info, ®istered_dmac_list, list) | ||
86 | nr += info->nr_channels; | ||
87 | |||
88 | return nr; | ||
89 | } | ||
90 | |||
78 | struct dma_channel *get_dma_channel(unsigned int chan) | 91 | struct dma_channel *get_dma_channel(unsigned int chan) |
79 | { | 92 | { |
80 | struct dma_info *info = get_dma_info(chan); | 93 | struct dma_info *info = get_dma_info(chan); |
@@ -173,7 +186,7 @@ int dma_xfer(unsigned int chan, unsigned long from, | |||
173 | static int dma_read_proc(char *buf, char **start, off_t off, | 186 | static int dma_read_proc(char *buf, char **start, off_t off, |
174 | int len, int *eof, void *data) | 187 | int len, int *eof, void *data) |
175 | { | 188 | { |
176 | struct list_head *pos, *tmp; | 189 | struct dma_info *info; |
177 | char *p = buf; | 190 | char *p = buf; |
178 | 191 | ||
179 | if (list_empty(®istered_dmac_list)) | 192 | if (list_empty(®istered_dmac_list)) |
@@ -182,8 +195,7 @@ static int dma_read_proc(char *buf, char **start, off_t off, | |||
182 | /* | 195 | /* |
183 | * Iterate over each registered DMAC | 196 | * Iterate over each registered DMAC |
184 | */ | 197 | */ |
185 | list_for_each_safe(pos, tmp, ®istered_dmac_list) { | 198 | list_for_each_entry(info, ®istered_dmac_list, list) { |
186 | struct dma_info *info = list_entry(pos, struct dma_info, list); | ||
187 | int i; | 199 | int i; |
188 | 200 | ||
189 | /* | 201 | /* |
@@ -205,9 +217,9 @@ static int dma_read_proc(char *buf, char **start, off_t off, | |||
205 | #endif | 217 | #endif |
206 | 218 | ||
207 | 219 | ||
208 | int __init register_dmac(struct dma_info *info) | 220 | int register_dmac(struct dma_info *info) |
209 | { | 221 | { |
210 | int i; | 222 | unsigned int total_channels, i; |
211 | 223 | ||
212 | INIT_LIST_HEAD(&info->list); | 224 | INIT_LIST_HEAD(&info->list); |
213 | 225 | ||
@@ -217,6 +229,11 @@ int __init register_dmac(struct dma_info *info) | |||
217 | 229 | ||
218 | BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); | 230 | BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); |
219 | 231 | ||
232 | info->pdev = platform_device_register_simple((char *)info->name, -1, | ||
233 | NULL, 0); | ||
234 | if (IS_ERR(info->pdev)) | ||
235 | return PTR_ERR(info->pdev); | ||
236 | |||
220 | /* | 237 | /* |
221 | * Don't touch pre-configured channels | 238 | * Don't touch pre-configured channels |
222 | */ | 239 | */ |
@@ -232,10 +249,12 @@ int __init register_dmac(struct dma_info *info) | |||
232 | memset(info->channels, 0, size); | 249 | memset(info->channels, 0, size); |
233 | } | 250 | } |
234 | 251 | ||
252 | total_channels = get_nr_channels(); | ||
235 | for (i = 0; i < info->nr_channels; i++) { | 253 | for (i = 0; i < info->nr_channels; i++) { |
236 | struct dma_channel *chan = info->channels + i; | 254 | struct dma_channel *chan = info->channels + i; |
237 | 255 | ||
238 | chan->chan = i; | 256 | chan->chan = i; |
257 | chan->vchan = i + total_channels; | ||
239 | 258 | ||
240 | memcpy(chan->dev_id, "Unused", 7); | 259 | memcpy(chan->dev_id, "Unused", 7); |
241 | 260 | ||
@@ -245,9 +264,7 @@ int __init register_dmac(struct dma_info *info) | |||
245 | init_MUTEX(&chan->sem); | 264 | init_MUTEX(&chan->sem); |
246 | init_waitqueue_head(&chan->wait_queue); | 265 | init_waitqueue_head(&chan->wait_queue); |
247 | 266 | ||
248 | #ifdef CONFIG_SYSFS | 267 | dma_create_sysfs_files(chan, info); |
249 | dma_create_sysfs_files(chan); | ||
250 | #endif | ||
251 | } | 268 | } |
252 | 269 | ||
253 | list_add(&info->list, ®istered_dmac_list); | 270 | list_add(&info->list, ®istered_dmac_list); |
@@ -255,12 +272,18 @@ int __init register_dmac(struct dma_info *info) | |||
255 | return 0; | 272 | return 0; |
256 | } | 273 | } |
257 | 274 | ||
258 | void __exit unregister_dmac(struct dma_info *info) | 275 | void unregister_dmac(struct dma_info *info) |
259 | { | 276 | { |
277 | unsigned int i; | ||
278 | |||
279 | for (i = 0; i < info->nr_channels; i++) | ||
280 | dma_remove_sysfs_files(info->channels + i, info); | ||
281 | |||
260 | if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) | 282 | if (!(info->flags & DMAC_CHANNELS_CONFIGURED)) |
261 | kfree(info->channels); | 283 | kfree(info->channels); |
262 | 284 | ||
263 | list_del(&info->list); | 285 | list_del(&info->list); |
286 | platform_device_unregister(info->pdev); | ||
264 | } | 287 | } |
265 | 288 | ||
266 | static int __init dma_api_init(void) | 289 | static int __init dma_api_init(void) |
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c index 231e3f6fb28f..5afab6f56ec3 100644 --- a/arch/sh/drivers/dma/dma-g2.c +++ b/arch/sh/drivers/dma/dma-g2.c | |||
@@ -140,7 +140,7 @@ static struct dma_ops g2_dma_ops = { | |||
140 | }; | 140 | }; |
141 | 141 | ||
142 | static struct dma_info g2_dma_info = { | 142 | static struct dma_info g2_dma_info = { |
143 | .name = "G2 DMA", | 143 | .name = "g2_dmac", |
144 | .nr_channels = 4, | 144 | .nr_channels = 4, |
145 | .ops = &g2_dma_ops, | 145 | .ops = &g2_dma_ops, |
146 | .flags = DMAC_CHANNELS_TEI_CAPABLE, | 146 | .flags = DMAC_CHANNELS_TEI_CAPABLE, |
@@ -160,6 +160,7 @@ static int __init g2_dma_init(void) | |||
160 | static void __exit g2_dma_exit(void) | 160 | static void __exit g2_dma_exit(void) |
161 | { | 161 | { |
162 | free_irq(HW_EVENT_G2_DMA, 0); | 162 | free_irq(HW_EVENT_G2_DMA, 0); |
163 | unregister_dmac(&g2_dma_info); | ||
163 | } | 164 | } |
164 | 165 | ||
165 | subsys_initcall(g2_dma_init); | 166 | subsys_initcall(g2_dma_init); |
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c index 1c9bc45b8bcb..05a74ffdb68d 100644 --- a/arch/sh/drivers/dma/dma-isa.c +++ b/arch/sh/drivers/dma/dma-isa.c | |||
@@ -25,14 +25,14 @@ | |||
25 | * such, this code is meant for only the simplest of tasks (and shouldn't be | 25 | * such, this code is meant for only the simplest of tasks (and shouldn't be |
26 | * used in any new drivers at all). | 26 | * used in any new drivers at all). |
27 | * | 27 | * |
28 | * It should also be noted that various functions here are labelled as | 28 | * NOTE: ops->xfer() is the preferred way of doing things. However, there |
29 | * being deprecated. This is due to the fact that the ops->xfer() method is | 29 | * are some users of the ISA DMA API that exist in common code that we |
30 | * the preferred way of doing things (as well as just grabbing the spinlock | 30 | * don't necessarily want to go out of our way to break, so we still |
31 | * directly). As such, any users of this interface will be warned rather | 31 | * allow for some compatability at that level. Any new code is strongly |
32 | * loudly. | 32 | * advised to run far away from the ISA DMA API and use the SH DMA API |
33 | * directly. | ||
33 | */ | 34 | */ |
34 | 35 | unsigned long claim_dma_lock(void) | |
35 | unsigned long __deprecated claim_dma_lock(void) | ||
36 | { | 36 | { |
37 | unsigned long flags; | 37 | unsigned long flags; |
38 | 38 | ||
@@ -42,19 +42,19 @@ unsigned long __deprecated claim_dma_lock(void) | |||
42 | } | 42 | } |
43 | EXPORT_SYMBOL(claim_dma_lock); | 43 | EXPORT_SYMBOL(claim_dma_lock); |
44 | 44 | ||
45 | void __deprecated release_dma_lock(unsigned long flags) | 45 | void release_dma_lock(unsigned long flags) |
46 | { | 46 | { |
47 | spin_unlock_irqrestore(&dma_spin_lock, flags); | 47 | spin_unlock_irqrestore(&dma_spin_lock, flags); |
48 | } | 48 | } |
49 | EXPORT_SYMBOL(release_dma_lock); | 49 | EXPORT_SYMBOL(release_dma_lock); |
50 | 50 | ||
51 | void __deprecated disable_dma(unsigned int chan) | 51 | void disable_dma(unsigned int chan) |
52 | { | 52 | { |
53 | /* Nothing */ | 53 | /* Nothing */ |
54 | } | 54 | } |
55 | EXPORT_SYMBOL(disable_dma); | 55 | EXPORT_SYMBOL(disable_dma); |
56 | 56 | ||
57 | void __deprecated enable_dma(unsigned int chan) | 57 | void enable_dma(unsigned int chan) |
58 | { | 58 | { |
59 | struct dma_info *info = get_dma_info(chan); | 59 | struct dma_info *info = get_dma_info(chan); |
60 | struct dma_channel *channel = &info->channels[chan]; | 60 | struct dma_channel *channel = &info->channels[chan]; |
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c index 2e1d58f2d1b9..df604975ccc8 100644 --- a/arch/sh/drivers/dma/dma-pvr2.c +++ b/arch/sh/drivers/dma/dma-pvr2.c | |||
@@ -80,7 +80,7 @@ static struct dma_ops pvr2_dma_ops = { | |||
80 | }; | 80 | }; |
81 | 81 | ||
82 | static struct dma_info pvr2_dma_info = { | 82 | static struct dma_info pvr2_dma_info = { |
83 | .name = "PowerVR 2 DMA", | 83 | .name = "pvr2_dmac", |
84 | .nr_channels = 1, | 84 | .nr_channels = 1, |
85 | .ops = &pvr2_dma_ops, | 85 | .ops = &pvr2_dma_ops, |
86 | .flags = DMAC_CHANNELS_TEI_CAPABLE, | 86 | .flags = DMAC_CHANNELS_TEI_CAPABLE, |
@@ -98,6 +98,7 @@ static void __exit pvr2_dma_exit(void) | |||
98 | { | 98 | { |
99 | free_dma(PVR2_CASCADE_CHAN); | 99 | free_dma(PVR2_CASCADE_CHAN); |
100 | free_irq(HW_EVENT_PVR2_DMA, 0); | 100 | free_irq(HW_EVENT_PVR2_DMA, 0); |
101 | unregister_dmac(&pvr2_dma_info); | ||
101 | } | 102 | } |
102 | 103 | ||
103 | subsys_initcall(pvr2_dma_init); | 104 | subsys_initcall(pvr2_dma_init); |
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 31dacd4444b2..cca26c4c9d1b 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2000 Takashi YOSHII | 6 | * Copyright (C) 2000 Takashi YOSHII |
7 | * Copyright (C) 2003, 2004 Paul Mundt | 7 | * Copyright (C) 2003, 2004 Paul Mundt |
8 | * Copyright (C) 2005 Andriy Skulysh | ||
8 | * | 9 | * |
9 | * This file is subject to the terms and conditions of the GNU General Public | 10 | * 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 | * License. See the file "COPYING" in the main directory of this archive |
@@ -16,51 +17,28 @@ | |||
16 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <asm/dreamcast/dma.h> | ||
19 | #include <asm/signal.h> | 21 | #include <asm/signal.h> |
20 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
21 | #include <asm/dma.h> | 23 | #include <asm/dma.h> |
22 | #include <asm/io.h> | 24 | #include <asm/io.h> |
23 | #include "dma-sh.h" | 25 | #include "dma-sh.h" |
24 | 26 | ||
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) | 27 | static inline unsigned int get_dmte_irq(unsigned int chan) |
51 | { | 28 | { |
52 | unsigned int irq; | 29 | unsigned int irq = 0; |
53 | 30 | ||
54 | /* | 31 | /* |
55 | * Normally we could just do DMTE0_IRQ + chan outright, though in the | 32 | * 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 | 33 | * case of the 7751R, the DMTE IRQs for channels > 4 start right above |
57 | * the SCIF | 34 | * the SCIF |
58 | */ | 35 | */ |
59 | |||
60 | if (chan < 4) { | 36 | if (chan < 4) { |
61 | irq = DMTE0_IRQ + chan; | 37 | irq = DMTE0_IRQ + chan; |
62 | } else { | 38 | } else { |
39 | #ifdef DMTE4_IRQ | ||
63 | irq = DMTE4_IRQ + chan - 4; | 40 | irq = DMTE4_IRQ + chan - 4; |
41 | #endif | ||
64 | } | 42 | } |
65 | 43 | ||
66 | return irq; | 44 | return irq; |
@@ -78,9 +56,7 @@ static inline unsigned int calc_xmit_shift(struct dma_channel *chan) | |||
78 | { | 56 | { |
79 | u32 chcr = ctrl_inl(CHCR[chan->chan]); | 57 | u32 chcr = ctrl_inl(CHCR[chan->chan]); |
80 | 58 | ||
81 | chcr >>= 4; | 59 | return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT]; |
82 | |||
83 | return ts_shift[chcr & 0x0007]; | ||
84 | } | 60 | } |
85 | 61 | ||
86 | /* | 62 | /* |
@@ -109,8 +85,13 @@ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) | |||
109 | 85 | ||
110 | static int sh_dmac_request_dma(struct dma_channel *chan) | 86 | static int sh_dmac_request_dma(struct dma_channel *chan) |
111 | { | 87 | { |
88 | char name[32]; | ||
89 | |||
90 | snprintf(name, sizeof(name), "DMAC Transfer End (Channel %d)", | ||
91 | chan->chan); | ||
92 | |||
112 | return request_irq(get_dmte_irq(chan->chan), dma_tei, | 93 | return request_irq(get_dmte_irq(chan->chan), dma_tei, |
113 | SA_INTERRUPT, "DMAC Transfer End", chan); | 94 | SA_INTERRUPT, name, chan); |
114 | } | 95 | } |
115 | 96 | ||
116 | static void sh_dmac_free_dma(struct dma_channel *chan) | 97 | static void sh_dmac_free_dma(struct dma_channel *chan) |
@@ -118,10 +99,18 @@ static void sh_dmac_free_dma(struct dma_channel *chan) | |||
118 | free_irq(get_dmte_irq(chan->chan), chan); | 99 | free_irq(get_dmte_irq(chan->chan), chan); |
119 | } | 100 | } |
120 | 101 | ||
121 | static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr) | 102 | static void |
103 | sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr) | ||
122 | { | 104 | { |
123 | if (!chcr) | 105 | if (!chcr) |
124 | chcr = RS_DUAL; | 106 | chcr = RS_DUAL | CHCR_IE; |
107 | |||
108 | if (chcr & CHCR_IE) { | ||
109 | chcr &= ~CHCR_IE; | ||
110 | chan->flags |= DMA_TEI_CAPABLE; | ||
111 | } else { | ||
112 | chan->flags &= ~DMA_TEI_CAPABLE; | ||
113 | } | ||
125 | 114 | ||
126 | ctrl_outl(chcr, CHCR[chan->chan]); | 115 | ctrl_outl(chcr, CHCR[chan->chan]); |
127 | 116 | ||
@@ -130,22 +119,32 @@ static void sh_dmac_configure_channel(struct dma_channel *chan, unsigned long ch | |||
130 | 119 | ||
131 | static void sh_dmac_enable_dma(struct dma_channel *chan) | 120 | static void sh_dmac_enable_dma(struct dma_channel *chan) |
132 | { | 121 | { |
133 | int irq = get_dmte_irq(chan->chan); | 122 | int irq; |
134 | u32 chcr; | 123 | u32 chcr; |
135 | 124 | ||
136 | chcr = ctrl_inl(CHCR[chan->chan]); | 125 | chcr = ctrl_inl(CHCR[chan->chan]); |
137 | chcr |= CHCR_DE | CHCR_IE; | 126 | chcr |= CHCR_DE; |
127 | |||
128 | if (chan->flags & DMA_TEI_CAPABLE) | ||
129 | chcr |= CHCR_IE; | ||
130 | |||
138 | ctrl_outl(chcr, CHCR[chan->chan]); | 131 | ctrl_outl(chcr, CHCR[chan->chan]); |
139 | 132 | ||
140 | enable_irq(irq); | 133 | if (chan->flags & DMA_TEI_CAPABLE) { |
134 | irq = get_dmte_irq(chan->chan); | ||
135 | enable_irq(irq); | ||
136 | } | ||
141 | } | 137 | } |
142 | 138 | ||
143 | static void sh_dmac_disable_dma(struct dma_channel *chan) | 139 | static void sh_dmac_disable_dma(struct dma_channel *chan) |
144 | { | 140 | { |
145 | int irq = get_dmte_irq(chan->chan); | 141 | int irq; |
146 | u32 chcr; | 142 | u32 chcr; |
147 | 143 | ||
148 | disable_irq(irq); | 144 | if (chan->flags & DMA_TEI_CAPABLE) { |
145 | irq = get_dmte_irq(chan->chan); | ||
146 | disable_irq(irq); | ||
147 | } | ||
149 | 148 | ||
150 | chcr = ctrl_inl(CHCR[chan->chan]); | 149 | chcr = ctrl_inl(CHCR[chan->chan]); |
151 | chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); | 150 | chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); |
@@ -158,7 +157,7 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan) | |||
158 | * If we haven't pre-configured the channel with special flags, use | 157 | * If we haven't pre-configured the channel with special flags, use |
159 | * the defaults. | 158 | * the defaults. |
160 | */ | 159 | */ |
161 | if (!(chan->flags & DMA_CONFIGURED)) | 160 | if (unlikely(!(chan->flags & DMA_CONFIGURED))) |
162 | sh_dmac_configure_channel(chan, 0); | 161 | sh_dmac_configure_channel(chan, 0); |
163 | 162 | ||
164 | sh_dmac_disable_dma(chan); | 163 | sh_dmac_disable_dma(chan); |
@@ -178,9 +177,11 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan) | |||
178 | * cascading to the PVR2 DMAC. In this case, we still need to write | 177 | * 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. | 178 | * SAR and DAR, regardless of value, in order for cascading to work. |
180 | */ | 179 | */ |
181 | if (chan->sar || (mach_is_dreamcast() && chan->chan == 2)) | 180 | if (chan->sar || (mach_is_dreamcast() && |
181 | chan->chan == PVR2_CASCADE_CHAN)) | ||
182 | ctrl_outl(chan->sar, SAR[chan->chan]); | 182 | ctrl_outl(chan->sar, SAR[chan->chan]); |
183 | if (chan->dar || (mach_is_dreamcast() && chan->chan == 2)) | 183 | if (chan->dar || (mach_is_dreamcast() && |
184 | chan->chan == PVR2_CASCADE_CHAN)) | ||
184 | ctrl_outl(chan->dar, DAR[chan->chan]); | 185 | ctrl_outl(chan->dar, DAR[chan->chan]); |
185 | 186 | ||
186 | ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]); | 187 | ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]); |
@@ -198,17 +199,38 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan) | |||
198 | return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); | 199 | return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); |
199 | } | 200 | } |
200 | 201 | ||
201 | #if defined(CONFIG_CPU_SH4) | 202 | #ifdef CONFIG_CPU_SUBTYPE_SH7780 |
202 | static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) | 203 | #define dmaor_read_reg() ctrl_inw(DMAOR) |
204 | #define dmaor_write_reg(data) ctrl_outw(data, DMAOR) | ||
205 | #else | ||
206 | #define dmaor_read_reg() ctrl_inl(DMAOR) | ||
207 | #define dmaor_write_reg(data) ctrl_outl(data, DMAOR) | ||
208 | #endif | ||
209 | |||
210 | static inline int dmaor_reset(void) | ||
203 | { | 211 | { |
204 | unsigned long dmaor = ctrl_inl(DMAOR); | 212 | unsigned long dmaor = dmaor_read_reg(); |
213 | |||
214 | /* Try to clear the error flags first, incase they are set */ | ||
215 | dmaor &= ~(DMAOR_NMIF | DMAOR_AE); | ||
216 | dmaor_write_reg(dmaor); | ||
205 | 217 | ||
206 | printk("DMAE: DMAOR=%lx\n", dmaor); | 218 | dmaor |= DMAOR_INIT; |
219 | dmaor_write_reg(dmaor); | ||
207 | 220 | ||
208 | ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR); | 221 | /* See if we got an error again */ |
209 | ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR); | 222 | if ((dmaor_read_reg() & (DMAOR_AE | DMAOR_NMIF))) { |
210 | ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR); | 223 | printk(KERN_ERR "dma-sh: Can't initialize DMAOR.\n"); |
224 | return -EINVAL; | ||
225 | } | ||
211 | 226 | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | #if defined(CONFIG_CPU_SH4) | ||
231 | static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) | ||
232 | { | ||
233 | dmaor_reset(); | ||
212 | disable_irq(irq); | 234 | disable_irq(irq); |
213 | 235 | ||
214 | return IRQ_HANDLED; | 236 | return IRQ_HANDLED; |
@@ -224,8 +246,8 @@ static struct dma_ops sh_dmac_ops = { | |||
224 | }; | 246 | }; |
225 | 247 | ||
226 | static struct dma_info sh_dmac_info = { | 248 | static struct dma_info sh_dmac_info = { |
227 | .name = "SuperH DMAC", | 249 | .name = "sh_dmac", |
228 | .nr_channels = 4, | 250 | .nr_channels = CONFIG_NR_ONCHIP_DMA_CHANNELS, |
229 | .ops = &sh_dmac_ops, | 251 | .ops = &sh_dmac_ops, |
230 | .flags = DMAC_CHANNELS_TEI_CAPABLE, | 252 | .flags = DMAC_CHANNELS_TEI_CAPABLE, |
231 | }; | 253 | }; |
@@ -248,7 +270,13 @@ static int __init sh_dmac_init(void) | |||
248 | make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); | 270 | make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); |
249 | } | 271 | } |
250 | 272 | ||
251 | ctrl_outl(0x8000 | DMAOR_DME, DMAOR); | 273 | /* |
274 | * Initialize DMAOR, and clean up any error flags that may have | ||
275 | * been set. | ||
276 | */ | ||
277 | i = dmaor_reset(); | ||
278 | if (i < 0) | ||
279 | return i; | ||
252 | 280 | ||
253 | return register_dmac(info); | 281 | return register_dmac(info); |
254 | } | 282 | } |
@@ -258,10 +286,12 @@ static void __exit sh_dmac_exit(void) | |||
258 | #ifdef CONFIG_CPU_SH4 | 286 | #ifdef CONFIG_CPU_SH4 |
259 | free_irq(DMAE_IRQ, 0); | 287 | free_irq(DMAE_IRQ, 0); |
260 | #endif | 288 | #endif |
289 | unregister_dmac(&sh_dmac_info); | ||
261 | } | 290 | } |
262 | 291 | ||
263 | subsys_initcall(sh_dmac_init); | 292 | subsys_initcall(sh_dmac_init); |
264 | module_exit(sh_dmac_exit); | 293 | module_exit(sh_dmac_exit); |
265 | 294 | ||
295 | MODULE_AUTHOR("Takashi YOSHII, Paul Mundt, Andriy Skulysh"); | ||
296 | MODULE_DESCRIPTION("SuperH On-Chip DMAC Support"); | ||
266 | MODULE_LICENSE("GPL"); | 297 | MODULE_LICENSE("GPL"); |
267 | |||
diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h index dd9d547539a2..0f591fbc922d 100644 --- a/arch/sh/drivers/dma/dma-sh.h +++ b/arch/sh/drivers/dma/dma-sh.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #ifndef __DMA_SH_H | 11 | #ifndef __DMA_SH_H |
12 | #define __DMA_SH_H | 12 | #define __DMA_SH_H |
13 | 13 | ||
14 | #include <asm/cpu/dma.h> | ||
15 | |||
14 | /* Definitions for the SuperH DMAC */ | 16 | /* Definitions for the SuperH DMAC */ |
15 | #define REQ_L 0x00000000 | 17 | #define REQ_L 0x00000000 |
16 | #define REQ_E 0x00080000 | 18 | #define REQ_E 0x00080000 |
@@ -26,27 +28,47 @@ | |||
26 | #define SM_DEC 0x00002000 | 28 | #define SM_DEC 0x00002000 |
27 | #define RS_IN 0x00000200 | 29 | #define RS_IN 0x00000200 |
28 | #define RS_OUT 0x00000300 | 30 | #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 | 31 | #define TS_BLK 0x00000040 |
35 | #define CHCR_DE 0x00000001 | 32 | #define CHCR_DE 0x00000001 |
36 | #define CHCR_TE 0x00000002 | 33 | #define CHCR_TE 0x00000002 |
37 | #define CHCR_IE 0x00000004 | 34 | #define CHCR_IE 0x00000004 |
38 | 35 | ||
39 | /* Define the default configuration for dual address memory-memory transfer. | 36 | /* DMAOR definitions */ |
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 | 37 | #define DMAOR_AE 0x00000004 |
46 | #define DMAOR_NMIF 0x00000002 | 38 | #define DMAOR_NMIF 0x00000002 |
47 | #define DMAOR_DME 0x00000001 | 39 | #define DMAOR_DME 0x00000001 |
48 | 40 | ||
41 | /* | ||
42 | * Define the default configuration for dual address memory-memory transfer. | ||
43 | * The 0x400 value represents auto-request, external->external. | ||
44 | */ | ||
45 | #define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32) | ||
46 | |||
49 | #define MAX_DMAC_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS) | 47 | #define MAX_DMAC_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS) |
50 | 48 | ||
49 | /* | ||
50 | * Subtypes that have fewer channels than this simply need to change | ||
51 | * CONFIG_NR_ONCHIP_DMA_CHANNELS. Likewise, subtypes with a larger number | ||
52 | * of channels should expand on this. | ||
53 | * | ||
54 | * For most subtypes we can easily figure these values out with some | ||
55 | * basic calculation, unfortunately on other subtypes these are more | ||
56 | * scattered, so we just leave it unrolled for simplicity. | ||
57 | */ | ||
58 | #define SAR ((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \ | ||
59 | SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30, \ | ||
60 | SH_DMAC_BASE + 0x50, SH_DMAC_BASE + 0x60}) | ||
61 | #define DAR ((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \ | ||
62 | SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34, \ | ||
63 | SH_DMAC_BASE + 0x54, SH_DMAC_BASE + 0x64}) | ||
64 | #define DMATCR ((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \ | ||
65 | SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38, \ | ||
66 | SH_DMAC_BASE + 0x58, SH_DMAC_BASE + 0x68}) | ||
67 | #define CHCR ((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \ | ||
68 | SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c, \ | ||
69 | SH_DMAC_BASE + 0x5c, SH_DMAC_BASE + 0x6c}) | ||
70 | |||
71 | #define DMAOR (SH_DMAC_BASE + 0x40) | ||
72 | |||
51 | #endif /* __DMA_SH_H */ | 73 | #endif /* __DMA_SH_H */ |
52 | 74 | ||
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c index 6e3b58bd8795..70a5d82eb2f8 100644 --- a/arch/sh/drivers/dma/dma-sysfs.c +++ b/arch/sh/drivers/dma/dma-sysfs.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * sysfs interface for SH DMA API | 4 | * sysfs interface for SH DMA API |
5 | * | 5 | * |
6 | * Copyright (C) 2004 Paul Mundt | 6 | * Copyright (C) 2004, 2005 Paul Mundt |
7 | * | 7 | * |
8 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * This file is subject to the terms and conditions of the GNU General Public |
9 | * License. See the file "COPYING" in the main directory of this archive | 9 | * License. See the file "COPYING" in the main directory of this archive |
@@ -12,7 +12,9 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/sysdev.h> | 14 | #include <linux/sysdev.h> |
15 | #include <linux/platform_device.h> | ||
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/err.h> | ||
16 | #include <linux/string.h> | 18 | #include <linux/string.h> |
17 | #include <asm/dma.h> | 19 | #include <asm/dma.h> |
18 | 20 | ||
@@ -77,7 +79,7 @@ static ssize_t dma_store_config(struct sys_device *dev, | |||
77 | unsigned long config; | 79 | unsigned long config; |
78 | 80 | ||
79 | config = simple_strtoul(buf, NULL, 0); | 81 | config = simple_strtoul(buf, NULL, 0); |
80 | dma_configure_channel(channel->chan, config); | 82 | dma_configure_channel(channel->vchan, config); |
81 | 83 | ||
82 | return count; | 84 | return count; |
83 | } | 85 | } |
@@ -111,12 +113,13 @@ static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL); | |||
111 | dma_ro_attr(count, "0x%08x\n"); | 113 | dma_ro_attr(count, "0x%08x\n"); |
112 | dma_ro_attr(flags, "0x%08lx\n"); | 114 | dma_ro_attr(flags, "0x%08lx\n"); |
113 | 115 | ||
114 | int __init dma_create_sysfs_files(struct dma_channel *chan) | 116 | int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info) |
115 | { | 117 | { |
116 | struct sys_device *dev = &chan->dev; | 118 | struct sys_device *dev = &chan->dev; |
119 | char name[16]; | ||
117 | int ret; | 120 | int ret; |
118 | 121 | ||
119 | dev->id = chan->chan; | 122 | dev->id = chan->vchan; |
120 | dev->cls = &dma_sysclass; | 123 | dev->cls = &dma_sysclass; |
121 | 124 | ||
122 | ret = sysdev_register(dev); | 125 | ret = sysdev_register(dev); |
@@ -129,6 +132,24 @@ int __init dma_create_sysfs_files(struct dma_channel *chan) | |||
129 | sysdev_create_file(dev, &attr_flags); | 132 | sysdev_create_file(dev, &attr_flags); |
130 | sysdev_create_file(dev, &attr_config); | 133 | sysdev_create_file(dev, &attr_config); |
131 | 134 | ||
132 | return 0; | 135 | snprintf(name, sizeof(name), "dma%d", chan->chan); |
136 | return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name); | ||
137 | } | ||
138 | |||
139 | void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info) | ||
140 | { | ||
141 | struct sys_device *dev = &chan->dev; | ||
142 | char name[16]; | ||
143 | |||
144 | sysdev_remove_file(dev, &attr_dev_id); | ||
145 | sysdev_remove_file(dev, &attr_count); | ||
146 | sysdev_remove_file(dev, &attr_mode); | ||
147 | sysdev_remove_file(dev, &attr_flags); | ||
148 | sysdev_remove_file(dev, &attr_config); | ||
149 | |||
150 | snprintf(name, sizeof(name), "dma%d", chan->chan); | ||
151 | sysfs_remove_link(&info->pdev->dev.kobj, name); | ||
152 | |||
153 | sysdev_unregister(dev); | ||
133 | } | 154 | } |
134 | 155 | ||
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 8b819698df14..7a86eeb22655 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile | |||
@@ -17,6 +17,4 @@ obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o | |||
17 | obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o | 17 | obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o |
18 | obj-$(CONFIG_MODULES) += module.o | 18 | obj-$(CONFIG_MODULES) += module.o |
19 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 19 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
20 | 20 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | |
21 | USE_STANDARD_AS_RULE := true | ||
22 | |||
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index cd43714df61a..5bfc33bec5d0 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile | |||
@@ -2,15 +2,12 @@ | |||
2 | # Makefile for the Linux/SuperH CPU-specifc backends. | 2 | # Makefile for the Linux/SuperH CPU-specifc backends. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := irq_ipr.o irq_imask.o init.o bus.o | 5 | obj-y += irq/ init.o bus.o clock.o |
6 | 6 | ||
7 | obj-$(CONFIG_CPU_SH2) += sh2/ | 7 | obj-$(CONFIG_CPU_SH2) += sh2/ |
8 | obj-$(CONFIG_CPU_SH3) += sh3/ | 8 | obj-$(CONFIG_CPU_SH3) += sh3/ |
9 | obj-$(CONFIG_CPU_SH4) += sh4/ | 9 | obj-$(CONFIG_CPU_SH4) += sh4/ |
10 | 10 | ||
11 | obj-$(CONFIG_SH_RTC) += rtc.o | 11 | obj-$(CONFIG_SH_RTC) += rtc.o |
12 | obj-$(CONFIG_UBC_WAKEUP) += ubc.o | 12 | obj-$(CONFIG_UBC_WAKEUP) += ubc.o |
13 | obj-$(CONFIG_SH_ADC) += adc.o | 13 | obj-$(CONFIG_SH_ADC) += adc.o |
14 | |||
15 | USE_STANDARD_AS_RULE := true | ||
16 | |||
diff --git a/arch/sh/kernel/cpu/bus.c b/arch/sh/kernel/cpu/bus.c index d4fee2a79373..fc6c4bd40c65 100644 --- a/arch/sh/kernel/cpu/bus.c +++ b/arch/sh/kernel/cpu/bus.c | |||
@@ -53,21 +53,6 @@ static int sh_bus_resume(struct device *dev) | |||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 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) | 56 | static int sh_device_probe(struct device *dev) |
72 | { | 57 | { |
73 | struct sh_dev *shdev = to_sh_dev(dev); | 58 | struct sh_dev *shdev = to_sh_dev(dev); |
@@ -90,6 +75,23 @@ static int sh_device_remove(struct device *dev) | |||
90 | return 0; | 75 | return 0; |
91 | } | 76 | } |
92 | 77 | ||
78 | static struct device sh_bus_devices[SH_NR_BUSES] = { | ||
79 | { | ||
80 | .bus_id = SH_BUS_NAME_VIRT, | ||
81 | }, | ||
82 | }; | ||
83 | |||
84 | struct bus_type sh_bus_types[SH_NR_BUSES] = { | ||
85 | { | ||
86 | .name = SH_BUS_NAME_VIRT, | ||
87 | .match = sh_bus_match, | ||
88 | .probe = sh_bus_probe, | ||
89 | .remove = sh_bus_remove, | ||
90 | .suspend = sh_bus_suspend, | ||
91 | .resume = sh_bus_resume, | ||
92 | }, | ||
93 | }; | ||
94 | |||
93 | int sh_device_register(struct sh_dev *dev) | 95 | int sh_device_register(struct sh_dev *dev) |
94 | { | 96 | { |
95 | if (!dev) | 97 | if (!dev) |
@@ -107,6 +109,8 @@ int sh_device_register(struct sh_dev *dev) | |||
107 | /* This is needed for USB OHCI to work */ | 109 | /* This is needed for USB OHCI to work */ |
108 | if (dev->dma_mask) | 110 | if (dev->dma_mask) |
109 | dev->dev.dma_mask = dev->dma_mask; | 111 | dev->dev.dma_mask = dev->dma_mask; |
112 | if (dev->coherent_dma_mask) | ||
113 | dev->dev.coherent_dma_mask = dev->coherent_dma_mask; | ||
110 | 114 | ||
111 | snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u", | 115 | snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%u", |
112 | dev->name, dev->dev_id); | 116 | dev->name, dev->dev_id); |
@@ -133,8 +137,6 @@ int sh_driver_register(struct sh_driver *drv) | |||
133 | return -EINVAL; | 137 | return -EINVAL; |
134 | } | 138 | } |
135 | 139 | ||
136 | drv->drv.probe = sh_device_probe; | ||
137 | drv->drv.remove = sh_device_remove; | ||
138 | drv->drv.bus = &sh_bus_types[drv->bus_id]; | 140 | drv->drv.bus = &sh_bus_types[drv->bus_id]; |
139 | 141 | ||
140 | return driver_register(&drv->drv); | 142 | return driver_register(&drv->drv); |
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c new file mode 100644 index 000000000000..989e7fdd524d --- /dev/null +++ b/arch/sh/kernel/cpu/clock.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/clock.c - SuperH clock framework | ||
3 | * | ||
4 | * Copyright (C) 2005 Paul Mundt | ||
5 | * | ||
6 | * This clock framework is derived from the OMAP version by: | ||
7 | * | ||
8 | * Copyright (C) 2004 Nokia Corporation | ||
9 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file "COPYING" in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/list.h> | ||
19 | #include <linux/kref.h> | ||
20 | #include <linux/seq_file.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <asm/clock.h> | ||
23 | #include <asm/timer.h> | ||
24 | |||
25 | static LIST_HEAD(clock_list); | ||
26 | static DEFINE_SPINLOCK(clock_lock); | ||
27 | static DECLARE_MUTEX(clock_list_sem); | ||
28 | |||
29 | /* | ||
30 | * Each subtype is expected to define the init routines for these clocks, | ||
31 | * as each subtype (or processor family) will have these clocks at the | ||
32 | * very least. These are all provided through the CPG, which even some of | ||
33 | * the more quirky parts (such as ST40, SH4-202, etc.) still have. | ||
34 | * | ||
35 | * The processor-specific code is expected to register any additional | ||
36 | * clock sources that are of interest. | ||
37 | */ | ||
38 | static struct clk master_clk = { | ||
39 | .name = "master_clk", | ||
40 | .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, | ||
41 | #ifdef CONFIG_SH_PCLK_FREQ_BOOL | ||
42 | .rate = CONFIG_SH_PCLK_FREQ, | ||
43 | #endif | ||
44 | }; | ||
45 | |||
46 | static struct clk module_clk = { | ||
47 | .name = "module_clk", | ||
48 | .parent = &master_clk, | ||
49 | .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, | ||
50 | }; | ||
51 | |||
52 | static struct clk bus_clk = { | ||
53 | .name = "bus_clk", | ||
54 | .parent = &master_clk, | ||
55 | .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, | ||
56 | }; | ||
57 | |||
58 | static struct clk cpu_clk = { | ||
59 | .name = "cpu_clk", | ||
60 | .parent = &master_clk, | ||
61 | .flags = CLK_ALWAYS_ENABLED, | ||
62 | }; | ||
63 | |||
64 | /* | ||
65 | * The ordering of these clocks matters, do not change it. | ||
66 | */ | ||
67 | static struct clk *onchip_clocks[] = { | ||
68 | &master_clk, | ||
69 | &module_clk, | ||
70 | &bus_clk, | ||
71 | &cpu_clk, | ||
72 | }; | ||
73 | |||
74 | static void propagate_rate(struct clk *clk) | ||
75 | { | ||
76 | struct clk *clkp; | ||
77 | |||
78 | list_for_each_entry(clkp, &clock_list, node) { | ||
79 | if (likely(clkp->parent != clk)) | ||
80 | continue; | ||
81 | if (likely(clkp->ops && clkp->ops->recalc)) | ||
82 | clkp->ops->recalc(clkp); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | int __clk_enable(struct clk *clk) | ||
87 | { | ||
88 | /* | ||
89 | * See if this is the first time we're enabling the clock, some | ||
90 | * clocks that are always enabled still require "special" | ||
91 | * initialization. This is especially true if the clock mode | ||
92 | * changes and the clock needs to hunt for the proper set of | ||
93 | * divisors to use before it can effectively recalc. | ||
94 | */ | ||
95 | if (unlikely(atomic_read(&clk->kref.refcount) == 1)) | ||
96 | if (clk->ops && clk->ops->init) | ||
97 | clk->ops->init(clk); | ||
98 | |||
99 | if (clk->flags & CLK_ALWAYS_ENABLED) | ||
100 | return 0; | ||
101 | |||
102 | if (likely(clk->ops && clk->ops->enable)) | ||
103 | clk->ops->enable(clk); | ||
104 | |||
105 | kref_get(&clk->kref); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int clk_enable(struct clk *clk) | ||
110 | { | ||
111 | unsigned long flags; | ||
112 | int ret; | ||
113 | |||
114 | spin_lock_irqsave(&clock_lock, flags); | ||
115 | ret = __clk_enable(clk); | ||
116 | spin_unlock_irqrestore(&clock_lock, flags); | ||
117 | |||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | static void clk_kref_release(struct kref *kref) | ||
122 | { | ||
123 | /* Nothing to do */ | ||
124 | } | ||
125 | |||
126 | void __clk_disable(struct clk *clk) | ||
127 | { | ||
128 | if (clk->flags & CLK_ALWAYS_ENABLED) | ||
129 | return; | ||
130 | |||
131 | kref_put(&clk->kref, clk_kref_release); | ||
132 | } | ||
133 | |||
134 | void clk_disable(struct clk *clk) | ||
135 | { | ||
136 | unsigned long flags; | ||
137 | |||
138 | spin_lock_irqsave(&clock_lock, flags); | ||
139 | __clk_disable(clk); | ||
140 | spin_unlock_irqrestore(&clock_lock, flags); | ||
141 | } | ||
142 | |||
143 | int clk_register(struct clk *clk) | ||
144 | { | ||
145 | down(&clock_list_sem); | ||
146 | |||
147 | list_add(&clk->node, &clock_list); | ||
148 | kref_init(&clk->kref); | ||
149 | |||
150 | up(&clock_list_sem); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | void clk_unregister(struct clk *clk) | ||
156 | { | ||
157 | down(&clock_list_sem); | ||
158 | list_del(&clk->node); | ||
159 | up(&clock_list_sem); | ||
160 | } | ||
161 | |||
162 | inline unsigned long clk_get_rate(struct clk *clk) | ||
163 | { | ||
164 | return clk->rate; | ||
165 | } | ||
166 | |||
167 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
168 | { | ||
169 | int ret = -EOPNOTSUPP; | ||
170 | |||
171 | if (likely(clk->ops && clk->ops->set_rate)) { | ||
172 | unsigned long flags; | ||
173 | |||
174 | spin_lock_irqsave(&clock_lock, flags); | ||
175 | ret = clk->ops->set_rate(clk, rate); | ||
176 | spin_unlock_irqrestore(&clock_lock, flags); | ||
177 | } | ||
178 | |||
179 | if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) | ||
180 | propagate_rate(clk); | ||
181 | |||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | void clk_recalc_rate(struct clk *clk) | ||
186 | { | ||
187 | if (likely(clk->ops && clk->ops->recalc)) { | ||
188 | unsigned long flags; | ||
189 | |||
190 | spin_lock_irqsave(&clock_lock, flags); | ||
191 | clk->ops->recalc(clk); | ||
192 | spin_unlock_irqrestore(&clock_lock, flags); | ||
193 | } | ||
194 | |||
195 | if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) | ||
196 | propagate_rate(clk); | ||
197 | } | ||
198 | |||
199 | struct clk *clk_get(const char *id) | ||
200 | { | ||
201 | struct clk *p, *clk = ERR_PTR(-ENOENT); | ||
202 | |||
203 | down(&clock_list_sem); | ||
204 | list_for_each_entry(p, &clock_list, node) { | ||
205 | if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | ||
206 | clk = p; | ||
207 | break; | ||
208 | } | ||
209 | } | ||
210 | up(&clock_list_sem); | ||
211 | |||
212 | return clk; | ||
213 | } | ||
214 | |||
215 | void clk_put(struct clk *clk) | ||
216 | { | ||
217 | if (clk && !IS_ERR(clk)) | ||
218 | module_put(clk->owner); | ||
219 | } | ||
220 | |||
221 | void __init __attribute__ ((weak)) | ||
222 | arch_init_clk_ops(struct clk_ops **ops, int type) | ||
223 | { | ||
224 | } | ||
225 | |||
226 | int __init clk_init(void) | ||
227 | { | ||
228 | int i, ret = 0; | ||
229 | |||
230 | if (unlikely(!master_clk.rate)) | ||
231 | /* | ||
232 | * NOTE: This will break if the default divisor has been | ||
233 | * changed. | ||
234 | * | ||
235 | * No one should be changing the default on us however, | ||
236 | * expect that a sane value for CONFIG_SH_PCLK_FREQ will | ||
237 | * be defined in the event of a different divisor. | ||
238 | */ | ||
239 | master_clk.rate = get_timer_frequency() * 4; | ||
240 | |||
241 | for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { | ||
242 | struct clk *clk = onchip_clocks[i]; | ||
243 | |||
244 | arch_init_clk_ops(&clk->ops, i); | ||
245 | ret |= clk_register(clk); | ||
246 | clk_enable(clk); | ||
247 | } | ||
248 | |||
249 | /* Kick the child clocks.. */ | ||
250 | propagate_rate(&master_clk); | ||
251 | propagate_rate(&bus_clk); | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | int show_clocks(struct seq_file *m) | ||
257 | { | ||
258 | struct clk *clk; | ||
259 | |||
260 | list_for_each_entry_reverse(clk, &clock_list, node) { | ||
261 | unsigned long rate = clk_get_rate(clk); | ||
262 | |||
263 | /* | ||
264 | * Don't bother listing dummy clocks with no ancestry | ||
265 | * that only support enable and disable ops. | ||
266 | */ | ||
267 | if (unlikely(!rate && !clk->parent)) | ||
268 | continue; | ||
269 | |||
270 | seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name, | ||
271 | rate / 1000000, (rate % 1000000) / 10000); | ||
272 | } | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | EXPORT_SYMBOL_GPL(clk_register); | ||
278 | EXPORT_SYMBOL_GPL(clk_unregister); | ||
279 | EXPORT_SYMBOL_GPL(clk_get); | ||
280 | EXPORT_SYMBOL_GPL(clk_put); | ||
281 | EXPORT_SYMBOL_GPL(clk_enable); | ||
282 | EXPORT_SYMBOL_GPL(clk_disable); | ||
283 | EXPORT_SYMBOL_GPL(__clk_enable); | ||
284 | EXPORT_SYMBOL_GPL(__clk_disable); | ||
285 | EXPORT_SYMBOL_GPL(clk_get_rate); | ||
286 | EXPORT_SYMBOL_GPL(clk_set_rate); | ||
287 | EXPORT_SYMBOL_GPL(clk_recalc_rate); | ||
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile new file mode 100644 index 000000000000..e3cccea15e1d --- /dev/null +++ b/arch/sh/kernel/cpu/irq/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for the Linux/SuperH CPU-specifc IRQ handlers. | ||
3 | # | ||
4 | obj-y += ipr.o imask.o | ||
5 | |||
6 | obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o | ||
7 | obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o | ||
diff --git a/arch/sh/kernel/cpu/irq_imask.c b/arch/sh/kernel/cpu/irq/imask.c index a963d00a971e..baed9a550d39 100644 --- a/arch/sh/kernel/cpu/irq_imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c | |||
@@ -1,16 +1,12 @@ | |||
1 | /* $Id: irq_imask.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $ | 1 | /* |
2 | * | 2 | * arch/sh/kernel/cpu/irq/imask.c |
3 | * linux/arch/sh/kernel/irq_imask.c | ||
4 | * | 3 | * |
5 | * Copyright (C) 1999, 2000 Niibe Yutaka | 4 | * Copyright (C) 1999, 2000 Niibe Yutaka |
6 | * | 5 | * |
7 | * Simple interrupt handling using IMASK of SR register. | 6 | * Simple interrupt handling using IMASK of SR register. |
8 | * | 7 | * |
9 | */ | 8 | */ |
10 | |||
11 | /* NOTE: Will not work on level 15 */ | 9 | /* NOTE: Will not work on level 15 */ |
12 | |||
13 | |||
14 | #include <linux/ptrace.h> | 10 | #include <linux/ptrace.h> |
15 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
16 | #include <linux/kernel_stat.h> | 12 | #include <linux/kernel_stat.h> |
@@ -19,13 +15,11 @@ | |||
19 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
20 | #include <linux/init.h> | 16 | #include <linux/init.h> |
21 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
22 | |||
23 | #include <asm/system.h> | ||
24 | #include <asm/irq.h> | ||
25 | |||
26 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
27 | #include <linux/cache.h> | 19 | #include <linux/cache.h> |
28 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <asm/system.h> | ||
22 | #include <asm/irq.h> | ||
29 | 23 | ||
30 | /* Bitmap of IRQ masked */ | 24 | /* Bitmap of IRQ masked */ |
31 | static unsigned long imask_mask = 0x7fff; | 25 | static unsigned long imask_mask = 0x7fff; |
@@ -40,7 +34,7 @@ static void end_imask_irq(unsigned int irq); | |||
40 | #define IMASK_PRIORITY 15 | 34 | #define IMASK_PRIORITY 15 |
41 | 35 | ||
42 | static unsigned int startup_imask_irq(unsigned int irq) | 36 | static unsigned int startup_imask_irq(unsigned int irq) |
43 | { | 37 | { |
44 | /* Nothing to do */ | 38 | /* Nothing to do */ |
45 | return 0; /* never anything pending */ | 39 | return 0; /* never anything pending */ |
46 | } | 40 | } |
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c new file mode 100644 index 000000000000..06e8afab32e4 --- /dev/null +++ b/arch/sh/kernel/cpu/irq/intc2.c | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * Interrupt handling for INTC2-based IRQ. | ||
3 | * | ||
4 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
5 | * Copyright (C) 2005, 2006 Paul Mundt (lethal@linux-sh.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 | * These are the "new Hitachi style" interrupts, as present on the | ||
11 | * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <asm/system.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <asm/machvec.h> | ||
20 | |||
21 | struct intc2_data { | ||
22 | unsigned char msk_offset; | ||
23 | unsigned char msk_shift; | ||
24 | |||
25 | int (*clear_irq) (int); | ||
26 | }; | ||
27 | |||
28 | static struct intc2_data intc2_data[NR_INTC2_IRQS]; | ||
29 | |||
30 | static void enable_intc2_irq(unsigned int irq); | ||
31 | static void disable_intc2_irq(unsigned int irq); | ||
32 | |||
33 | /* shutdown is same as "disable" */ | ||
34 | #define shutdown_intc2_irq disable_intc2_irq | ||
35 | |||
36 | static void mask_and_ack_intc2(unsigned int); | ||
37 | static void end_intc2_irq(unsigned int irq); | ||
38 | |||
39 | static unsigned int startup_intc2_irq(unsigned int irq) | ||
40 | { | ||
41 | enable_intc2_irq(irq); | ||
42 | return 0; /* never anything pending */ | ||
43 | } | ||
44 | |||
45 | static struct hw_interrupt_type intc2_irq_type = { | ||
46 | .typename = "INTC2-IRQ", | ||
47 | .startup = startup_intc2_irq, | ||
48 | .shutdown = shutdown_intc2_irq, | ||
49 | .enable = enable_intc2_irq, | ||
50 | .disable = disable_intc2_irq, | ||
51 | .ack = mask_and_ack_intc2, | ||
52 | .end = end_intc2_irq | ||
53 | }; | ||
54 | |||
55 | static void disable_intc2_irq(unsigned int irq) | ||
56 | { | ||
57 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
58 | int msk_shift, msk_offset; | ||
59 | |||
60 | /* Sanity check */ | ||
61 | if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) | ||
62 | return; | ||
63 | |||
64 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
65 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
66 | |||
67 | ctrl_outl(1 << msk_shift, | ||
68 | INTC2_BASE + INTC2_INTMSK_OFFSET + msk_offset); | ||
69 | } | ||
70 | |||
71 | static void enable_intc2_irq(unsigned int irq) | ||
72 | { | ||
73 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
74 | int msk_shift, msk_offset; | ||
75 | |||
76 | /* Sanity check */ | ||
77 | if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) | ||
78 | return; | ||
79 | |||
80 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
81 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
82 | |||
83 | ctrl_outl(1 << msk_shift, | ||
84 | INTC2_BASE + INTC2_INTMSKCLR_OFFSET + msk_offset); | ||
85 | } | ||
86 | |||
87 | static void mask_and_ack_intc2(unsigned int irq) | ||
88 | { | ||
89 | disable_intc2_irq(irq); | ||
90 | } | ||
91 | |||
92 | static void end_intc2_irq(unsigned int irq) | ||
93 | { | ||
94 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
95 | enable_intc2_irq(irq); | ||
96 | |||
97 | if (unlikely(intc2_data[irq - INTC2_FIRST_IRQ].clear_irq)) | ||
98 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq(irq); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Setup an INTC2 style interrupt. | ||
103 | * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, | ||
104 | * allowing the use of the numbers straight out of the datasheet. | ||
105 | * For example: | ||
106 | * PIO1 which is INTPRI00[19,16] and INTMSK00[13] | ||
107 | * would be: ^ ^ ^ ^ | ||
108 | * | | | | | ||
109 | * make_intc2_irq(84, 0, 16, 0, 13); | ||
110 | */ | ||
111 | void make_intc2_irq(unsigned int irq, | ||
112 | unsigned int ipr_offset, unsigned int ipr_shift, | ||
113 | unsigned int msk_offset, unsigned int msk_shift, | ||
114 | unsigned int priority) | ||
115 | { | ||
116 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
117 | unsigned int flags; | ||
118 | unsigned long ipr; | ||
119 | |||
120 | if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) | ||
121 | return; | ||
122 | |||
123 | disable_irq_nosync(irq); | ||
124 | |||
125 | /* Fill the data we need */ | ||
126 | intc2_data[irq_offset].msk_offset = msk_offset; | ||
127 | intc2_data[irq_offset].msk_shift = msk_shift; | ||
128 | intc2_data[irq_offset].clear_irq = NULL; | ||
129 | |||
130 | /* Set the priority level */ | ||
131 | local_irq_save(flags); | ||
132 | |||
133 | ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); | ||
134 | ipr &= ~(0xf << ipr_shift); | ||
135 | ipr |= priority << ipr_shift; | ||
136 | ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); | ||
137 | |||
138 | local_irq_restore(flags); | ||
139 | |||
140 | irq_desc[irq].handler = &intc2_irq_type; | ||
141 | |||
142 | disable_intc2_irq(irq); | ||
143 | } | ||
144 | |||
145 | static struct intc2_init { | ||
146 | unsigned short irq; | ||
147 | unsigned char ipr_offset, ipr_shift; | ||
148 | unsigned char msk_offset, msk_shift; | ||
149 | unsigned char priority; | ||
150 | } intc2_init_data[] __initdata = { | ||
151 | #if defined(CONFIG_CPU_SUBTYPE_ST40) | ||
152 | {64, 0, 0, 0, 0, 13}, /* PCI serr */ | ||
153 | {65, 0, 4, 0, 1, 13}, /* PCI err */ | ||
154 | {66, 0, 4, 0, 2, 13}, /* PCI ad */ | ||
155 | {67, 0, 4, 0, 3, 13}, /* PCI pwd down */ | ||
156 | {72, 0, 8, 0, 5, 13}, /* DMAC INT0 */ | ||
157 | {73, 0, 8, 0, 6, 13}, /* DMAC INT1 */ | ||
158 | {74, 0, 8, 0, 7, 13}, /* DMAC INT2 */ | ||
159 | {75, 0, 8, 0, 8, 13}, /* DMAC INT3 */ | ||
160 | {76, 0, 8, 0, 9, 13}, /* DMAC INT4 */ | ||
161 | {78, 0, 8, 0, 11, 13}, /* DMAC ERR */ | ||
162 | {80, 0, 12, 0, 12, 13}, /* PIO0 */ | ||
163 | {84, 0, 16, 0, 13, 13}, /* PIO1 */ | ||
164 | {88, 0, 20, 0, 14, 13}, /* PIO2 */ | ||
165 | {112, 4, 0, 4, 0, 13}, /* Mailbox */ | ||
166 | #ifdef CONFIG_CPU_SUBTYPE_ST40GX1 | ||
167 | {116, 4, 4, 4, 4, 13}, /* SSC0 */ | ||
168 | {120, 4, 8, 4, 8, 13}, /* IR Blaster */ | ||
169 | {124, 4, 12, 4, 12, 13}, /* USB host */ | ||
170 | {128, 4, 16, 4, 16, 13}, /* Video processor BLITTER */ | ||
171 | {132, 4, 20, 4, 20, 13}, /* UART0 */ | ||
172 | {134, 4, 20, 4, 22, 13}, /* UART2 */ | ||
173 | {136, 4, 24, 4, 24, 13}, /* IO_PIO0 */ | ||
174 | {140, 4, 28, 4, 28, 13}, /* EMPI */ | ||
175 | {144, 8, 0, 8, 0, 13}, /* MAFE */ | ||
176 | {148, 8, 4, 8, 4, 13}, /* PWM */ | ||
177 | {152, 8, 8, 8, 8, 13}, /* SSC1 */ | ||
178 | {156, 8, 12, 8, 12, 13}, /* IO_PIO1 */ | ||
179 | {160, 8, 16, 8, 16, 13}, /* USB target */ | ||
180 | {164, 8, 20, 8, 20, 13}, /* UART1 */ | ||
181 | {168, 8, 24, 8, 24, 13}, /* Teletext */ | ||
182 | {172, 8, 28, 8, 28, 13}, /* VideoSync VTG */ | ||
183 | {173, 8, 28, 8, 29, 13}, /* VideoSync DVP0 */ | ||
184 | {174, 8, 28, 8, 30, 13}, /* VideoSync DVP1 */ | ||
185 | #endif | ||
186 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
187 | /* | ||
188 | * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 | ||
189 | */ | ||
190 | /* INTPRIO0 | INTMSK0 */ | ||
191 | {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ | ||
192 | {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ | ||
193 | {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ | ||
194 | {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ | ||
195 | /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ | ||
196 | /* INTPRIO4 | INTMSK0 */ | ||
197 | {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ | ||
198 | {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ | ||
199 | {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ | ||
200 | {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ | ||
201 | {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ | ||
202 | {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ | ||
203 | {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ | ||
204 | {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ | ||
205 | /* INTPRIO8 | INTMSK0 */ | ||
206 | {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ | ||
207 | {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ | ||
208 | {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ | ||
209 | {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ | ||
210 | {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ | ||
211 | {65, 8, 24, 0, 16, 3}, /* LCDC */ | ||
212 | /* 66, 67 unused */ | ||
213 | {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ | ||
214 | {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ | ||
215 | {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ | ||
216 | /* 71 unused */ | ||
217 | {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ | ||
218 | {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ | ||
219 | {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ | ||
220 | {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ | ||
221 | {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ | ||
222 | {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ | ||
223 | {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ | ||
224 | {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ | ||
225 | /* | INTMSK4 */ | ||
226 | {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ | ||
227 | {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ | ||
228 | {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ | ||
229 | {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ | ||
230 | {84, 8, 0, 4, 19, 3}, /* HSPII */ | ||
231 | /* INTPRIOC | INTMSK4 */ | ||
232 | /* 85-87 unused/reserved */ | ||
233 | {88, 12, 20, 4, 18, 3}, /* MMCI0 */ | ||
234 | {89, 12, 20, 4, 17, 3}, /* MMCI1 */ | ||
235 | {90, 12, 20, 4, 16, 3}, /* MMCI2 */ | ||
236 | {91, 12, 20, 4, 15, 3}, /* MMCI3 */ | ||
237 | {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ | ||
238 | /* 93-107 reserved/undocumented */ | ||
239 | {108,12, 4, 4, 1, 3}, /* ADC */ | ||
240 | {109,12, 0, 4, 0, 3}, /* CMTI */ | ||
241 | /* 110-111 reserved/unused */ | ||
242 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
243 | { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, | ||
244 | #ifdef CONFIG_SH_RTC | ||
245 | { RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, | ||
246 | #endif | ||
247 | { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
248 | { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
249 | { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
250 | { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, | ||
251 | |||
252 | { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
253 | { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
254 | { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
255 | { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, | ||
256 | |||
257 | { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, | ||
258 | { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, | ||
259 | { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, | ||
260 | { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, | ||
261 | { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, | ||
262 | #endif | ||
263 | }; | ||
264 | |||
265 | void __init init_IRQ_intc2(void) | ||
266 | { | ||
267 | int i; | ||
268 | |||
269 | for (i = 0; i < ARRAY_SIZE(intc2_init_data); i++) { | ||
270 | struct intc2_init *p = intc2_init_data + i; | ||
271 | make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift, | ||
272 | p-> msk_offset, p->msk_shift, p->priority); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /* Adds a termination callback to the interrupt */ | ||
277 | void intc2_add_clear_irq(int irq, int (*fn)(int)) | ||
278 | { | ||
279 | if (unlikely(irq < INTC2_FIRST_IRQ)) | ||
280 | return; | ||
281 | |||
282 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; | ||
283 | } | ||
284 | |||
diff --git a/arch/sh/kernel/cpu/irq_ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 71f92096132b..fdbd718ae5c6 100644 --- a/arch/sh/kernel/cpu/irq_ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* $Id: irq_ipr.c,v 1.1.2.1 2002/11/17 10:53:43 mrbrown Exp $ | 1 | /* |
2 | * | 2 | * arch/sh/kernel/cpu/irq/ipr.c |
3 | * linux/arch/sh/kernel/irq_ipr.c | ||
4 | * | 3 | * |
5 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi | 4 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi |
6 | * Copyright (C) 2000 Kazumoto Kojima | 5 | * Copyright (C) 2000 Kazumoto Kojima |
@@ -109,7 +108,8 @@ static void end_ipr_irq(unsigned int irq) | |||
109 | enable_ipr_irq(irq); | 108 | enable_ipr_irq(irq); |
110 | } | 109 | } |
111 | 110 | ||
112 | void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) | 111 | void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, |
112 | int priority, int maskpos) | ||
113 | { | 113 | { |
114 | disable_irq_nosync(irq); | 114 | disable_irq_nosync(irq); |
115 | ipr_data[irq].addr = addr; | 115 | ipr_data[irq].addr = addr; |
@@ -120,126 +120,47 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) | |||
120 | disable_ipr_irq(irq); | 120 | disable_ipr_irq(irq); |
121 | } | 121 | } |
122 | 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 | .typename = "PINT-IRQ", | ||
146 | .startup = startup_pint_irq, | ||
147 | .shutdown = shutdown_pint_irq, | ||
148 | .enable = enable_pint_irq, | ||
149 | .disable = disable_pint_irq, | ||
150 | .ack = mask_and_ack_pint, | ||
151 | .end = 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) | 123 | void __init init_IRQ(void) |
198 | { | 124 | { |
199 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 125 | #ifndef CONFIG_CPU_SUBTYPE_SH7780 |
200 | defined(CONFIG_CPU_SUBTYPE_SH7707) || \ | 126 | make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY, 0); |
201 | defined(CONFIG_CPU_SUBTYPE_SH7709) | 127 | make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY, 0); |
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) | 128 | #if defined(CONFIG_SH_RTC) |
208 | make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); | 129 | make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY, 0); |
209 | #endif | 130 | #endif |
210 | 131 | ||
211 | #ifdef SCI_ERI_IRQ | 132 | #ifdef SCI_ERI_IRQ |
212 | make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); | 133 | make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); |
213 | make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); | 134 | make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); |
214 | make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); | 135 | make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY, 0); |
215 | #endif | 136 | #endif |
216 | 137 | ||
217 | #ifdef SCIF1_ERI_IRQ | 138 | #ifdef SCIF1_ERI_IRQ |
218 | make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 139 | make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
219 | make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 140 | make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
220 | make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 141 | make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
221 | make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); | 142 | make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY, 0); |
222 | #endif | 143 | #endif |
223 | 144 | ||
224 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | 145 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) |
225 | make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY); | 146 | make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY, 0); |
226 | make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | 147 | make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0); |
227 | make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | 148 | make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY, 0); |
228 | make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); | 149 | make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY, 0); |
229 | #endif | 150 | #endif |
230 | 151 | ||
231 | #ifdef SCIF_ERI_IRQ | 152 | #ifdef SCIF_ERI_IRQ |
232 | make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 153 | make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
233 | make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 154 | make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
234 | make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 155 | make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
235 | make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); | 156 | make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY, 0); |
236 | #endif | 157 | #endif |
237 | 158 | ||
238 | #ifdef IRDA_ERI_IRQ | 159 | #ifdef IRDA_ERI_IRQ |
239 | make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 160 | make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
240 | make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 161 | make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
241 | make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 162 | make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
242 | make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); | 163 | make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY, 0); |
243 | #endif | 164 | #endif |
244 | 165 | ||
245 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ | 166 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ |
@@ -254,86 +175,32 @@ void __init init_IRQ(void) | |||
254 | * You should set corresponding bits of PFC to "00" | 175 | * You should set corresponding bits of PFC to "00" |
255 | * to enable these interrupts. | 176 | * to enable these interrupts. |
256 | */ | 177 | */ |
257 | make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY); | 178 | make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY, 0); |
258 | make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); | 179 | make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY, 0); |
259 | make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); | 180 | make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY, 0); |
260 | make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY); | 181 | make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY, 0); |
261 | make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY); | 182 | make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY, 0); |
262 | make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY); | 183 | make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY, 0); |
263 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) | 184 | #endif |
264 | make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); | 185 | #endif |
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 | 186 | ||
269 | for(i = 0; i < 16; i++) | 187 | #ifdef CONFIG_CPU_HAS_PINT_IRQ |
270 | make_pint_irq(PINT_IRQ_BASE + i); | 188 | init_IRQ_pint(); |
271 | for(i = 0; i < 256; i++) | 189 | #endif |
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 | 190 | ||
285 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | 191 | #ifdef CONFIG_CPU_HAS_INTC2_IRQ |
286 | init_IRQ_intc2(); | 192 | init_IRQ_intc2(); |
287 | #endif | 193 | #endif |
288 | |||
289 | /* Perform the machine specific initialisation */ | 194 | /* Perform the machine specific initialisation */ |
290 | if (sh_mv.mv_init_irq != NULL) { | 195 | if (sh_mv.mv_init_irq != NULL) |
291 | sh_mv.mv_init_irq(); | 196 | sh_mv.mv_init_irq(); |
292 | } | ||
293 | } | 197 | } |
294 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ | 198 | |
295 | defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) | 199 | #if !defined(CONFIG_CPU_HAS_PINT_IRQ) |
296 | int ipr_irq_demux(int irq) | 200 | int ipr_irq_demux(int irq) |
297 | { | 201 | { |
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; | 202 | return irq; |
335 | } | 203 | } |
336 | #endif | 204 | #endif |
337 | 205 | ||
338 | EXPORT_SYMBOL(make_ipr_irq); | 206 | EXPORT_SYMBOL(make_ipr_irq); |
339 | |||
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c new file mode 100644 index 000000000000..95d6024fe1ae --- /dev/null +++ b/arch/sh/kernel/cpu/irq/pint.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/irq/pint.c - Interrupt handling for PINT-based IRQs. | ||
3 | * | ||
4 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi | ||
5 | * Copyright (C) 2000 Kazumoto Kojima | ||
6 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
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/irq.h> | ||
16 | #include <linux/module.h> | ||
17 | |||
18 | #include <asm/system.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/machvec.h> | ||
21 | |||
22 | static unsigned char pint_map[256]; | ||
23 | static unsigned long portcr_mask; | ||
24 | |||
25 | static void enable_pint_irq(unsigned int irq); | ||
26 | static void disable_pint_irq(unsigned int irq); | ||
27 | |||
28 | /* shutdown is same as "disable" */ | ||
29 | #define shutdown_pint_irq disable_pint_irq | ||
30 | |||
31 | static void mask_and_ack_pint(unsigned int); | ||
32 | static void end_pint_irq(unsigned int irq); | ||
33 | |||
34 | static unsigned int startup_pint_irq(unsigned int irq) | ||
35 | { | ||
36 | enable_pint_irq(irq); | ||
37 | return 0; /* never anything pending */ | ||
38 | } | ||
39 | |||
40 | static struct hw_interrupt_type pint_irq_type = { | ||
41 | .typename = "PINT-IRQ", | ||
42 | .startup = startup_pint_irq, | ||
43 | .shutdown = shutdown_pint_irq, | ||
44 | .enable = enable_pint_irq, | ||
45 | .disable = disable_pint_irq, | ||
46 | .ack = mask_and_ack_pint, | ||
47 | .end = end_pint_irq | ||
48 | }; | ||
49 | |||
50 | static void disable_pint_irq(unsigned int irq) | ||
51 | { | ||
52 | unsigned long val, flags; | ||
53 | |||
54 | local_irq_save(flags); | ||
55 | val = ctrl_inw(INTC_INTER); | ||
56 | val &= ~(1 << (irq - PINT_IRQ_BASE)); | ||
57 | ctrl_outw(val, INTC_INTER); /* disable PINTn */ | ||
58 | portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2); | ||
59 | local_irq_restore(flags); | ||
60 | } | ||
61 | |||
62 | static void enable_pint_irq(unsigned int irq) | ||
63 | { | ||
64 | unsigned long val, flags; | ||
65 | |||
66 | local_irq_save(flags); | ||
67 | val = ctrl_inw(INTC_INTER); | ||
68 | val |= 1 << (irq - PINT_IRQ_BASE); | ||
69 | ctrl_outw(val, INTC_INTER); /* enable PINTn */ | ||
70 | portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2; | ||
71 | local_irq_restore(flags); | ||
72 | } | ||
73 | |||
74 | static void mask_and_ack_pint(unsigned int irq) | ||
75 | { | ||
76 | disable_pint_irq(irq); | ||
77 | } | ||
78 | |||
79 | static void end_pint_irq(unsigned int irq) | ||
80 | { | ||
81 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
82 | enable_pint_irq(irq); | ||
83 | } | ||
84 | |||
85 | void make_pint_irq(unsigned int irq) | ||
86 | { | ||
87 | disable_irq_nosync(irq); | ||
88 | irq_desc[irq].handler = &pint_irq_type; | ||
89 | disable_pint_irq(irq); | ||
90 | } | ||
91 | |||
92 | void __init init_IRQ_pint(void) | ||
93 | { | ||
94 | int i; | ||
95 | |||
96 | make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); | ||
97 | make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); | ||
98 | |||
99 | enable_irq(PINT0_IRQ); | ||
100 | enable_irq(PINT8_IRQ); | ||
101 | |||
102 | for(i = 0; i < 16; i++) | ||
103 | make_pint_irq(PINT_IRQ_BASE + i); | ||
104 | |||
105 | for(i = 0; i < 256; i++) { | ||
106 | if (i & 1) | ||
107 | pint_map[i] = 0; | ||
108 | else if (i & 2) | ||
109 | pint_map[i] = 1; | ||
110 | else if (i & 4) | ||
111 | pint_map[i] = 2; | ||
112 | else if (i & 8) | ||
113 | pint_map[i] = 3; | ||
114 | else if (i & 0x10) | ||
115 | pint_map[i] = 4; | ||
116 | else if (i & 0x20) | ||
117 | pint_map[i] = 5; | ||
118 | else if (i & 0x40) | ||
119 | pint_map[i] = 6; | ||
120 | else if (i & 0x80) | ||
121 | pint_map[i] = 7; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | int ipr_irq_demux(int irq) | ||
126 | { | ||
127 | unsigned long creg, dreg, d, sav; | ||
128 | |||
129 | if (irq == PINT0_IRQ) { | ||
130 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) | ||
131 | creg = PORT_PACR; | ||
132 | dreg = PORT_PADR; | ||
133 | #else | ||
134 | creg = PORT_PCCR; | ||
135 | dreg = PORT_PCDR; | ||
136 | #endif | ||
137 | sav = ctrl_inw(creg); | ||
138 | ctrl_outw(sav | portcr_mask, creg); | ||
139 | d = (~ctrl_inb(dreg) ^ ctrl_inw(INTC_ICR2)) & | ||
140 | ctrl_inw(INTC_INTER) & 0xff; | ||
141 | ctrl_outw(sav, creg); | ||
142 | |||
143 | if (d == 0) | ||
144 | return irq; | ||
145 | |||
146 | return PINT_IRQ_BASE + pint_map[d]; | ||
147 | } else if (irq == PINT8_IRQ) { | ||
148 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) | ||
149 | creg = PORT_PBCR; | ||
150 | dreg = PORT_PBDR; | ||
151 | #else | ||
152 | creg = PORT_PFCR; | ||
153 | dreg = PORT_PFDR; | ||
154 | #endif | ||
155 | sav = ctrl_inw(creg); | ||
156 | ctrl_outw(sav | (portcr_mask >> 16), creg); | ||
157 | d = (~ctrl_inb(dreg) ^ (ctrl_inw(INTC_ICR2) >> 8)) & | ||
158 | (ctrl_inw(INTC_INTER) >> 8) & 0xff; | ||
159 | ctrl_outw(sav, creg); | ||
160 | |||
161 | if (d == 0) | ||
162 | return irq; | ||
163 | |||
164 | return PINT_IRQ_BASE + 8 + pint_map[d]; | ||
165 | } | ||
166 | |||
167 | return irq; | ||
168 | } | ||
169 | |||
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index a64532e4dc63..b54dbb9a0c86 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile | |||
@@ -4,3 +4,10 @@ | |||
4 | 4 | ||
5 | obj-y := ex.o probe.o | 5 | obj-y := ex.o probe.o |
6 | 6 | ||
7 | clock-$(CONFIG_CPU_SH3) := clock-sh3.o | ||
8 | clock-$(CONFIG_CPU_SUBTYPE_SH7300) := clock-sh7300.o | ||
9 | clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o | ||
10 | clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o | ||
11 | |||
12 | obj-y += $(clock-y) | ||
13 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh3.c b/arch/sh/kernel/cpu/sh3/clock-sh3.c new file mode 100644 index 000000000000..c3c945958baf --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh3.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh3/clock-sh3.c | ||
3 | * | ||
4 | * Generic SH-3 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 Paul Mundt | ||
7 | * | ||
8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
9 | * | ||
10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
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 <asm/clock.h> | ||
22 | #include <asm/freq.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
26 | static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; | ||
27 | static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
28 | |||
29 | static void master_clk_init(struct clk *clk) | ||
30 | { | ||
31 | int frqcr = ctrl_inw(FRQCR); | ||
32 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
33 | |||
34 | clk->rate *= pfc_divisors[idx]; | ||
35 | } | ||
36 | |||
37 | static struct clk_ops sh3_master_clk_ops = { | ||
38 | .init = master_clk_init, | ||
39 | }; | ||
40 | |||
41 | static void module_clk_recalc(struct clk *clk) | ||
42 | { | ||
43 | int frqcr = ctrl_inw(FRQCR); | ||
44 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
45 | |||
46 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
47 | } | ||
48 | |||
49 | static struct clk_ops sh3_module_clk_ops = { | ||
50 | .recalc = module_clk_recalc, | ||
51 | }; | ||
52 | |||
53 | static void bus_clk_recalc(struct clk *clk) | ||
54 | { | ||
55 | int frqcr = ctrl_inw(FRQCR); | ||
56 | int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); | ||
57 | |||
58 | clk->rate = clk->parent->rate / stc_multipliers[idx]; | ||
59 | } | ||
60 | |||
61 | static struct clk_ops sh3_bus_clk_ops = { | ||
62 | .recalc = bus_clk_recalc, | ||
63 | }; | ||
64 | |||
65 | static void cpu_clk_recalc(struct clk *clk) | ||
66 | { | ||
67 | int frqcr = ctrl_inw(FRQCR); | ||
68 | int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); | ||
69 | |||
70 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
71 | } | ||
72 | |||
73 | static struct clk_ops sh3_cpu_clk_ops = { | ||
74 | .recalc = cpu_clk_recalc, | ||
75 | }; | ||
76 | |||
77 | static struct clk_ops *sh3_clk_ops[] = { | ||
78 | &sh3_master_clk_ops, | ||
79 | &sh3_module_clk_ops, | ||
80 | &sh3_bus_clk_ops, | ||
81 | &sh3_cpu_clk_ops, | ||
82 | }; | ||
83 | |||
84 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
85 | { | ||
86 | if (idx < ARRAY_SIZE(sh3_clk_ops)) | ||
87 | *ops = sh3_clk_ops[idx]; | ||
88 | } | ||
89 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7300.c b/arch/sh/kernel/cpu/sh3/clock-sh7300.c new file mode 100644 index 000000000000..e804174b9625 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh7300.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh3/clock-sh7300.c | ||
3 | * | ||
4 | * SH7300 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 Paul Mundt | ||
7 | * | ||
8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
9 | * | ||
10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
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 <asm/clock.h> | ||
22 | #include <asm/freq.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; | ||
26 | |||
27 | static void master_clk_init(struct clk *clk) | ||
28 | { | ||
29 | clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007]; | ||
30 | } | ||
31 | |||
32 | static struct clk_ops sh7300_master_clk_ops = { | ||
33 | .init = master_clk_init, | ||
34 | }; | ||
35 | |||
36 | static void module_clk_recalc(struct clk *clk) | ||
37 | { | ||
38 | int idx = (ctrl_inw(FRQCR) & 0x0007); | ||
39 | clk->rate = clk->parent->rate / md_table[idx]; | ||
40 | } | ||
41 | |||
42 | static struct clk_ops sh7300_module_clk_ops = { | ||
43 | .recalc = module_clk_recalc, | ||
44 | }; | ||
45 | |||
46 | static void bus_clk_recalc(struct clk *clk) | ||
47 | { | ||
48 | int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8; | ||
49 | clk->rate = clk->parent->rate / md_table[idx]; | ||
50 | } | ||
51 | |||
52 | static struct clk_ops sh7300_bus_clk_ops = { | ||
53 | .recalc = bus_clk_recalc, | ||
54 | }; | ||
55 | |||
56 | static void cpu_clk_recalc(struct clk *clk) | ||
57 | { | ||
58 | int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4; | ||
59 | clk->rate = clk->parent->rate / md_table[idx]; | ||
60 | } | ||
61 | |||
62 | static struct clk_ops sh7300_cpu_clk_ops = { | ||
63 | .recalc = cpu_clk_recalc, | ||
64 | }; | ||
65 | |||
66 | static struct clk_ops *sh7300_clk_ops[] = { | ||
67 | &sh7300_master_clk_ops, | ||
68 | &sh7300_module_clk_ops, | ||
69 | &sh7300_bus_clk_ops, | ||
70 | &sh7300_cpu_clk_ops, | ||
71 | }; | ||
72 | |||
73 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
74 | { | ||
75 | if (idx < ARRAY_SIZE(sh7300_clk_ops)) | ||
76 | *ops = sh7300_clk_ops[idx]; | ||
77 | } | ||
78 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7705.c b/arch/sh/kernel/cpu/sh3/clock-sh7705.c new file mode 100644 index 000000000000..dfdbf3277fd7 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh7705.c | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh3/clock-sh7705.c | ||
3 | * | ||
4 | * SH7705 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 Paul Mundt | ||
7 | * | ||
8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
9 | * | ||
10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
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 <asm/clock.h> | ||
22 | #include <asm/freq.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | /* | ||
26 | * SH7705 uses the same divisors as the generic SH-3 case, it's just the | ||
27 | * FRQCR layout that is a bit different.. | ||
28 | */ | ||
29 | static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
30 | static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; | ||
31 | static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
32 | |||
33 | static void master_clk_init(struct clk *clk) | ||
34 | { | ||
35 | clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003]; | ||
36 | } | ||
37 | |||
38 | static struct clk_ops sh7705_master_clk_ops = { | ||
39 | .init = master_clk_init, | ||
40 | }; | ||
41 | |||
42 | static void module_clk_recalc(struct clk *clk) | ||
43 | { | ||
44 | int idx = ctrl_inw(FRQCR) & 0x0003; | ||
45 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
46 | } | ||
47 | |||
48 | static struct clk_ops sh7705_module_clk_ops = { | ||
49 | .recalc = module_clk_recalc, | ||
50 | }; | ||
51 | |||
52 | static void bus_clk_recalc(struct clk *clk) | ||
53 | { | ||
54 | int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8; | ||
55 | clk->rate = clk->parent->rate / stc_multipliers[idx]; | ||
56 | } | ||
57 | |||
58 | static struct clk_ops sh7705_bus_clk_ops = { | ||
59 | .recalc = bus_clk_recalc, | ||
60 | }; | ||
61 | |||
62 | static void cpu_clk_recalc(struct clk *clk) | ||
63 | { | ||
64 | int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4; | ||
65 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
66 | } | ||
67 | |||
68 | static struct clk_ops sh7705_cpu_clk_ops = { | ||
69 | .recalc = cpu_clk_recalc, | ||
70 | }; | ||
71 | |||
72 | static struct clk_ops *sh7705_clk_ops[] = { | ||
73 | &sh7705_master_clk_ops, | ||
74 | &sh7705_module_clk_ops, | ||
75 | &sh7705_bus_clk_ops, | ||
76 | &sh7705_cpu_clk_ops, | ||
77 | }; | ||
78 | |||
79 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
80 | { | ||
81 | if (idx < ARRAY_SIZE(sh7705_clk_ops)) | ||
82 | *ops = sh7705_clk_ops[idx]; | ||
83 | } | ||
84 | |||
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c new file mode 100644 index 000000000000..10461a745e5f --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh3/clock-sh7709.c | ||
3 | * | ||
4 | * SH7709 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 Andriy Skulysh | ||
7 | * | ||
8 | * Based on arch/sh/kernel/cpu/sh3/clock-sh7705.c | ||
9 | * Copyright (C) 2005 Paul Mundt | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file "COPYING" in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <asm/clock.h> | ||
18 | #include <asm/freq.h> | ||
19 | #include <asm/io.h> | ||
20 | |||
21 | static int stc_multipliers[] = { 1, 2, 4, 8, 3, 6, 1, 1 }; | ||
22 | static int ifc_divisors[] = { 1, 2, 4, 1, 3, 1, 1, 1 }; | ||
23 | static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; | ||
24 | |||
25 | static void set_bus_parent(struct clk *clk) | ||
26 | { | ||
27 | struct clk *bus_clk = clk_get("bus_clk"); | ||
28 | clk->parent = bus_clk; | ||
29 | clk_put(bus_clk); | ||
30 | } | ||
31 | |||
32 | static void master_clk_init(struct clk *clk) | ||
33 | { | ||
34 | int frqcr = ctrl_inw(FRQCR); | ||
35 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
36 | |||
37 | clk->rate *= pfc_divisors[idx]; | ||
38 | } | ||
39 | |||
40 | static struct clk_ops sh7709_master_clk_ops = { | ||
41 | .init = master_clk_init, | ||
42 | }; | ||
43 | |||
44 | static void module_clk_recalc(struct clk *clk) | ||
45 | { | ||
46 | int frqcr = ctrl_inw(FRQCR); | ||
47 | int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); | ||
48 | |||
49 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
50 | } | ||
51 | |||
52 | static struct clk_ops sh7709_module_clk_ops = { | ||
53 | #ifdef CLOCK_MODE_0_1_2_7 | ||
54 | .init = set_bus_parent, | ||
55 | #endif | ||
56 | .recalc = module_clk_recalc, | ||
57 | }; | ||
58 | |||
59 | static void bus_clk_recalc(struct clk *clk) | ||
60 | { | ||
61 | int frqcr = ctrl_inw(FRQCR); | ||
62 | int idx = (frqcr & 0x0080) ? | ||
63 | ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1; | ||
64 | |||
65 | clk->rate = clk->parent->rate * stc_multipliers[idx]; | ||
66 | } | ||
67 | |||
68 | static struct clk_ops sh7709_bus_clk_ops = { | ||
69 | .recalc = bus_clk_recalc, | ||
70 | }; | ||
71 | |||
72 | static void cpu_clk_recalc(struct clk *clk) | ||
73 | { | ||
74 | int frqcr = ctrl_inw(FRQCR); | ||
75 | int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); | ||
76 | |||
77 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
78 | } | ||
79 | |||
80 | static struct clk_ops sh7709_cpu_clk_ops = { | ||
81 | .init = set_bus_parent, | ||
82 | .recalc = cpu_clk_recalc, | ||
83 | }; | ||
84 | |||
85 | static struct clk_ops *sh7709_clk_ops[] = { | ||
86 | &sh7709_master_clk_ops, | ||
87 | &sh7709_module_clk_ops, | ||
88 | &sh7709_bus_clk_ops, | ||
89 | &sh7709_cpu_clk_ops, | ||
90 | }; | ||
91 | |||
92 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
93 | { | ||
94 | if (idx < ARRAY_SIZE(sh7709_clk_ops)) | ||
95 | *ops = sh7709_clk_ops[idx]; | ||
96 | } | ||
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index ead1071eac73..3d5cafc71ae3 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile | |||
@@ -5,6 +5,15 @@ | |||
5 | obj-y := ex.o probe.o | 5 | obj-y := ex.o probe.o |
6 | 6 | ||
7 | obj-$(CONFIG_SH_FPU) += fpu.o | 7 | obj-$(CONFIG_SH_FPU) += fpu.o |
8 | obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += irq_intc2.o | ||
9 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o | 8 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o |
10 | 9 | ||
10 | # Primary on-chip clocks (common) | ||
11 | clock-$(CONFIG_CPU_SH4) := clock-sh4.o | ||
12 | clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o | ||
13 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o | ||
14 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o | ||
15 | |||
16 | # Additional clocks by subtype | ||
17 | clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o | ||
18 | |||
19 | obj-y += $(clock-y) | ||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c new file mode 100644 index 000000000000..bfdf5fe8d948 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4/clock-sh4-202.c | ||
3 | * | ||
4 | * Additional SH4-202 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 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/err.h> | ||
15 | #include <asm/clock.h> | ||
16 | #include <asm/freq.h> | ||
17 | #include <asm/io.h> | ||
18 | |||
19 | #define CPG2_FRQCR3 0xfe0a0018 | ||
20 | |||
21 | static int frqcr3_divisors[] = { 1, 2, 3, 4, 6, 8, 16 }; | ||
22 | static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 }; | ||
23 | |||
24 | static void emi_clk_recalc(struct clk *clk) | ||
25 | { | ||
26 | int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; | ||
27 | clk->rate = clk->parent->rate / frqcr3_divisors[idx]; | ||
28 | } | ||
29 | |||
30 | static inline int frqcr3_lookup(struct clk *clk, unsigned long rate) | ||
31 | { | ||
32 | int divisor = clk->parent->rate / rate; | ||
33 | int i; | ||
34 | |||
35 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) | ||
36 | if (frqcr3_divisors[i] == divisor) | ||
37 | return frqcr3_values[i]; | ||
38 | |||
39 | /* Safe fallback */ | ||
40 | return 5; | ||
41 | } | ||
42 | |||
43 | static struct clk_ops sh4202_emi_clk_ops = { | ||
44 | .recalc = emi_clk_recalc, | ||
45 | }; | ||
46 | |||
47 | static struct clk sh4202_emi_clk = { | ||
48 | .name = "emi_clk", | ||
49 | .flags = CLK_ALWAYS_ENABLED, | ||
50 | .ops = &sh4202_emi_clk_ops, | ||
51 | }; | ||
52 | |||
53 | static void femi_clk_recalc(struct clk *clk) | ||
54 | { | ||
55 | int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007; | ||
56 | clk->rate = clk->parent->rate / frqcr3_divisors[idx]; | ||
57 | } | ||
58 | |||
59 | static struct clk_ops sh4202_femi_clk_ops = { | ||
60 | .recalc = femi_clk_recalc, | ||
61 | }; | ||
62 | |||
63 | static struct clk sh4202_femi_clk = { | ||
64 | .name = "femi_clk", | ||
65 | .flags = CLK_ALWAYS_ENABLED, | ||
66 | .ops = &sh4202_femi_clk_ops, | ||
67 | }; | ||
68 | |||
69 | static void shoc_clk_init(struct clk *clk) | ||
70 | { | ||
71 | int i; | ||
72 | |||
73 | /* | ||
74 | * For some reason, the shoc_clk seems to be set to some really | ||
75 | * insane value at boot (values outside of the allowable frequency | ||
76 | * range for instance). We deal with this by scaling it back down | ||
77 | * to something sensible just in case. | ||
78 | * | ||
79 | * Start scaling from the high end down until we find something | ||
80 | * that passes rate verification.. | ||
81 | */ | ||
82 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { | ||
83 | int divisor = frqcr3_divisors[i]; | ||
84 | |||
85 | if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0) | ||
86 | break; | ||
87 | } | ||
88 | |||
89 | WARN_ON(i == ARRAY_SIZE(frqcr3_divisors)); /* Undefined clock */ | ||
90 | } | ||
91 | |||
92 | static void shoc_clk_recalc(struct clk *clk) | ||
93 | { | ||
94 | int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; | ||
95 | clk->rate = clk->parent->rate / frqcr3_divisors[idx]; | ||
96 | } | ||
97 | |||
98 | static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) | ||
99 | { | ||
100 | struct clk *bclk = clk_get("bus_clk"); | ||
101 | unsigned long bclk_rate = clk_get_rate(bclk); | ||
102 | |||
103 | clk_put(bclk); | ||
104 | |||
105 | if (rate > bclk_rate) | ||
106 | return 1; | ||
107 | if (rate > 66000000) | ||
108 | return 1; | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) | ||
114 | { | ||
115 | unsigned long frqcr3; | ||
116 | unsigned int tmp; | ||
117 | |||
118 | /* Make sure we have something sensible to switch to */ | ||
119 | if (shoc_clk_verify_rate(clk, rate) != 0) | ||
120 | return -EINVAL; | ||
121 | |||
122 | tmp = frqcr3_lookup(clk, rate); | ||
123 | |||
124 | frqcr3 = ctrl_inl(CPG2_FRQCR3); | ||
125 | frqcr3 &= ~(0x0007 << 6); | ||
126 | frqcr3 |= tmp << 6; | ||
127 | ctrl_outl(frqcr3, CPG2_FRQCR3); | ||
128 | |||
129 | clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct clk_ops sh4202_shoc_clk_ops = { | ||
135 | .init = shoc_clk_init, | ||
136 | .recalc = shoc_clk_recalc, | ||
137 | .set_rate = shoc_clk_set_rate, | ||
138 | }; | ||
139 | |||
140 | static struct clk sh4202_shoc_clk = { | ||
141 | .name = "shoc_clk", | ||
142 | .flags = CLK_ALWAYS_ENABLED, | ||
143 | .ops = &sh4202_shoc_clk_ops, | ||
144 | }; | ||
145 | |||
146 | static struct clk *sh4202_onchip_clocks[] = { | ||
147 | &sh4202_emi_clk, | ||
148 | &sh4202_femi_clk, | ||
149 | &sh4202_shoc_clk, | ||
150 | }; | ||
151 | |||
152 | static int __init sh4202_clk_init(void) | ||
153 | { | ||
154 | struct clk *clk = clk_get("master_clk"); | ||
155 | int i; | ||
156 | |||
157 | for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { | ||
158 | struct clk *clkp = sh4202_onchip_clocks[i]; | ||
159 | |||
160 | clkp->parent = clk; | ||
161 | clk_register(clkp); | ||
162 | clk_enable(clkp); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Now that we have the rest of the clocks registered, we need to | ||
167 | * force the parent clock to propagate so that these clocks will | ||
168 | * automatically figure out their rate. We cheat by handing the | ||
169 | * parent clock its current rate and forcing child propagation. | ||
170 | */ | ||
171 | clk_set_rate(clk, clk_get_rate(clk)); | ||
172 | |||
173 | clk_put(clk); | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | arch_initcall(sh4202_clk_init); | ||
179 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4.c b/arch/sh/kernel/cpu/sh4/clock-sh4.c new file mode 100644 index 000000000000..dca9f87a12d6 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh4.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4/clock-sh4.c | ||
3 | * | ||
4 | * Generic SH-4 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 Paul Mundt | ||
7 | * | ||
8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
9 | * | ||
10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
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 <asm/clock.h> | ||
22 | #include <asm/freq.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; | ||
26 | #define bfc_divisors ifc_divisors /* Same */ | ||
27 | static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; | ||
28 | |||
29 | static void master_clk_init(struct clk *clk) | ||
30 | { | ||
31 | clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007]; | ||
32 | } | ||
33 | |||
34 | static struct clk_ops sh4_master_clk_ops = { | ||
35 | .init = master_clk_init, | ||
36 | }; | ||
37 | |||
38 | static void module_clk_recalc(struct clk *clk) | ||
39 | { | ||
40 | int idx = (ctrl_inw(FRQCR) & 0x0007); | ||
41 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
42 | } | ||
43 | |||
44 | static struct clk_ops sh4_module_clk_ops = { | ||
45 | .recalc = module_clk_recalc, | ||
46 | }; | ||
47 | |||
48 | static void bus_clk_recalc(struct clk *clk) | ||
49 | { | ||
50 | int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007; | ||
51 | clk->rate = clk->parent->rate / bfc_divisors[idx]; | ||
52 | } | ||
53 | |||
54 | static struct clk_ops sh4_bus_clk_ops = { | ||
55 | .recalc = bus_clk_recalc, | ||
56 | }; | ||
57 | |||
58 | static void cpu_clk_recalc(struct clk *clk) | ||
59 | { | ||
60 | int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007; | ||
61 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
62 | } | ||
63 | |||
64 | static struct clk_ops sh4_cpu_clk_ops = { | ||
65 | .recalc = cpu_clk_recalc, | ||
66 | }; | ||
67 | |||
68 | static struct clk_ops *sh4_clk_ops[] = { | ||
69 | &sh4_master_clk_ops, | ||
70 | &sh4_module_clk_ops, | ||
71 | &sh4_bus_clk_ops, | ||
72 | &sh4_cpu_clk_ops, | ||
73 | }; | ||
74 | |||
75 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
76 | { | ||
77 | if (idx < ARRAY_SIZE(sh4_clk_ops)) | ||
78 | *ops = sh4_clk_ops[idx]; | ||
79 | } | ||
80 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh73180.c b/arch/sh/kernel/cpu/sh4/clock-sh73180.c new file mode 100644 index 000000000000..2fa5cb2ae68d --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh73180.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4/clock-sh73180.c | ||
3 | * | ||
4 | * SH73180 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 Paul Mundt | ||
7 | * | ||
8 | * FRQCR parsing hacked out of arch/sh/kernel/time.c | ||
9 | * | ||
10 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
11 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
12 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
13 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
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 <asm/clock.h> | ||
22 | #include <asm/freq.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | /* | ||
26 | * SH73180 uses a common set of divisors, so this is quite simple.. | ||
27 | */ | ||
28 | static int divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; | ||
29 | |||
30 | static void master_clk_init(struct clk *clk) | ||
31 | { | ||
32 | clk->rate *= divisors[ctrl_inl(FRQCR) & 0x0007]; | ||
33 | } | ||
34 | |||
35 | static struct clk_ops sh73180_master_clk_ops = { | ||
36 | .init = master_clk_init, | ||
37 | }; | ||
38 | |||
39 | static void module_clk_recalc(struct clk *clk) | ||
40 | { | ||
41 | int idx = (ctrl_inl(FRQCR) & 0x0007); | ||
42 | clk->rate = clk->parent->rate / divisors[idx]; | ||
43 | } | ||
44 | |||
45 | static struct clk_ops sh73180_module_clk_ops = { | ||
46 | .recalc = module_clk_recalc, | ||
47 | }; | ||
48 | |||
49 | static void bus_clk_recalc(struct clk *clk) | ||
50 | { | ||
51 | int idx = (ctrl_inl(FRQCR) >> 12) & 0x0007; | ||
52 | clk->rate = clk->parent->rate / divisors[idx]; | ||
53 | } | ||
54 | |||
55 | static struct clk_ops sh73180_bus_clk_ops = { | ||
56 | .recalc = bus_clk_recalc, | ||
57 | }; | ||
58 | |||
59 | static void cpu_clk_recalc(struct clk *clk) | ||
60 | { | ||
61 | int idx = (ctrl_inl(FRQCR) >> 20) & 0x0007; | ||
62 | clk->rate = clk->parent->rate / divisors[idx]; | ||
63 | } | ||
64 | |||
65 | static struct clk_ops sh73180_cpu_clk_ops = { | ||
66 | .recalc = cpu_clk_recalc, | ||
67 | }; | ||
68 | |||
69 | static struct clk_ops *sh73180_clk_ops[] = { | ||
70 | &sh73180_master_clk_ops, | ||
71 | &sh73180_module_clk_ops, | ||
72 | &sh73180_bus_clk_ops, | ||
73 | &sh73180_cpu_clk_ops, | ||
74 | }; | ||
75 | |||
76 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
77 | { | ||
78 | if (idx < ARRAY_SIZE(sh73180_clk_ops)) | ||
79 | *ops = sh73180_clk_ops[idx]; | ||
80 | } | ||
81 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7770.c b/arch/sh/kernel/cpu/sh4/clock-sh7770.c new file mode 100644 index 000000000000..c8694bac6477 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh7770.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4/clock-sh7770.c | ||
3 | * | ||
4 | * SH7770 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 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/clock.h> | ||
15 | #include <asm/freq.h> | ||
16 | #include <asm/io.h> | ||
17 | |||
18 | static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 }; | ||
19 | static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 }; | ||
20 | static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 }; | ||
21 | |||
22 | static void master_clk_init(struct clk *clk) | ||
23 | { | ||
24 | clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; | ||
25 | } | ||
26 | |||
27 | static struct clk_ops sh7770_master_clk_ops = { | ||
28 | .init = master_clk_init, | ||
29 | }; | ||
30 | |||
31 | static void module_clk_recalc(struct clk *clk) | ||
32 | { | ||
33 | int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); | ||
34 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
35 | } | ||
36 | |||
37 | static struct clk_ops sh7770_module_clk_ops = { | ||
38 | .recalc = module_clk_recalc, | ||
39 | }; | ||
40 | |||
41 | static void bus_clk_recalc(struct clk *clk) | ||
42 | { | ||
43 | int idx = (ctrl_inl(FRQCR) & 0x000f); | ||
44 | clk->rate = clk->parent->rate / bfc_divisors[idx]; | ||
45 | } | ||
46 | |||
47 | static struct clk_ops sh7770_bus_clk_ops = { | ||
48 | .recalc = bus_clk_recalc, | ||
49 | }; | ||
50 | |||
51 | static void cpu_clk_recalc(struct clk *clk) | ||
52 | { | ||
53 | int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); | ||
54 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
55 | } | ||
56 | |||
57 | static struct clk_ops sh7770_cpu_clk_ops = { | ||
58 | .recalc = cpu_clk_recalc, | ||
59 | }; | ||
60 | |||
61 | static struct clk_ops *sh7770_clk_ops[] = { | ||
62 | &sh7770_master_clk_ops, | ||
63 | &sh7770_module_clk_ops, | ||
64 | &sh7770_bus_clk_ops, | ||
65 | &sh7770_cpu_clk_ops, | ||
66 | }; | ||
67 | |||
68 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
69 | { | ||
70 | if (idx < ARRAY_SIZE(sh7770_clk_ops)) | ||
71 | *ops = sh7770_clk_ops[idx]; | ||
72 | } | ||
73 | |||
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/arch/sh/kernel/cpu/sh4/clock-sh7780.c new file mode 100644 index 000000000000..93ad367342c9 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4/clock-sh7780.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4/clock-sh7780.c | ||
3 | * | ||
4 | * SH7780 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2005 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/clock.h> | ||
15 | #include <asm/freq.h> | ||
16 | #include <asm/io.h> | ||
17 | |||
18 | static int ifc_divisors[] = { 2, 4 }; | ||
19 | static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 }; | ||
20 | static int pfc_divisors[] = { 1, 24, 24, 1 }; | ||
21 | static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 }; | ||
22 | |||
23 | static void master_clk_init(struct clk *clk) | ||
24 | { | ||
25 | clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; | ||
26 | } | ||
27 | |||
28 | static struct clk_ops sh7780_master_clk_ops = { | ||
29 | .init = master_clk_init, | ||
30 | }; | ||
31 | |||
32 | static void module_clk_recalc(struct clk *clk) | ||
33 | { | ||
34 | int idx = (ctrl_inl(FRQCR) & 0x0003); | ||
35 | clk->rate = clk->parent->rate / pfc_divisors[idx]; | ||
36 | } | ||
37 | |||
38 | static struct clk_ops sh7780_module_clk_ops = { | ||
39 | .recalc = module_clk_recalc, | ||
40 | }; | ||
41 | |||
42 | static void bus_clk_recalc(struct clk *clk) | ||
43 | { | ||
44 | int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); | ||
45 | clk->rate = clk->parent->rate / bfc_divisors[idx]; | ||
46 | } | ||
47 | |||
48 | static struct clk_ops sh7780_bus_clk_ops = { | ||
49 | .recalc = bus_clk_recalc, | ||
50 | }; | ||
51 | |||
52 | static void cpu_clk_recalc(struct clk *clk) | ||
53 | { | ||
54 | int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); | ||
55 | clk->rate = clk->parent->rate / ifc_divisors[idx]; | ||
56 | } | ||
57 | |||
58 | static struct clk_ops sh7780_cpu_clk_ops = { | ||
59 | .recalc = cpu_clk_recalc, | ||
60 | }; | ||
61 | |||
62 | static struct clk_ops *sh7780_clk_ops[] = { | ||
63 | &sh7780_master_clk_ops, | ||
64 | &sh7780_module_clk_ops, | ||
65 | &sh7780_bus_clk_ops, | ||
66 | &sh7780_cpu_clk_ops, | ||
67 | }; | ||
68 | |||
69 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
70 | { | ||
71 | if (idx < ARRAY_SIZE(sh7780_clk_ops)) | ||
72 | *ops = sh7780_clk_ops[idx]; | ||
73 | } | ||
74 | |||
75 | static void shyway_clk_recalc(struct clk *clk) | ||
76 | { | ||
77 | int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); | ||
78 | clk->rate = clk->parent->rate / cfc_divisors[idx]; | ||
79 | } | ||
80 | |||
81 | static struct clk_ops sh7780_shyway_clk_ops = { | ||
82 | .recalc = shyway_clk_recalc, | ||
83 | }; | ||
84 | |||
85 | static struct clk sh7780_shyway_clk = { | ||
86 | .name = "shyway_clk", | ||
87 | .flags = CLK_ALWAYS_ENABLED, | ||
88 | .ops = &sh7780_shyway_clk_ops, | ||
89 | }; | ||
90 | |||
91 | /* | ||
92 | * Additional SH7780-specific on-chip clocks that aren't already part of the | ||
93 | * clock framework | ||
94 | */ | ||
95 | static struct clk *sh7780_onchip_clocks[] = { | ||
96 | &sh7780_shyway_clk, | ||
97 | }; | ||
98 | |||
99 | static int __init sh7780_clk_init(void) | ||
100 | { | ||
101 | struct clk *clk = clk_get("master_clk"); | ||
102 | int i; | ||
103 | |||
104 | for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { | ||
105 | struct clk *clkp = sh7780_onchip_clocks[i]; | ||
106 | |||
107 | clkp->parent = clk; | ||
108 | clk_register(clkp); | ||
109 | clk_enable(clkp); | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Now that we have the rest of the clocks registered, we need to | ||
114 | * force the parent clock to propagate so that these clocks will | ||
115 | * automatically figure out their rate. We cheat by handing the | ||
116 | * parent clock its current rate and forcing child propagation. | ||
117 | */ | ||
118 | clk_set_rate(clk, clk_get_rate(clk)); | ||
119 | |||
120 | clk_put(clk); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | arch_initcall(sh7780_clk_init); | ||
126 | |||
diff --git a/arch/sh/kernel/cpu/sh4/irq_intc2.c b/arch/sh/kernel/cpu/sh4/irq_intc2.c deleted file mode 100644 index f6b16ba01932..000000000000 --- a/arch/sh/kernel/cpu/sh4/irq_intc2.c +++ /dev/null | |||
@@ -1,222 +0,0 @@ | |||
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 | .typename = "INTC2-IRQ", | ||
52 | .startup = startup_intc2_irq, | ||
53 | .shutdown = shutdown_intc2_irq, | ||
54 | .enable = enable_intc2_irq, | ||
55 | .disable = disable_intc2_irq, | ||
56 | .ack = mask_and_ack_intc2, | ||
57 | .end = 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/io.c b/arch/sh/kernel/io.c index d9932f25993b..71c9fde2fd90 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c | |||
@@ -2,58 +2,73 @@ | |||
2 | * linux/arch/sh/kernel/io.c | 2 | * linux/arch/sh/kernel/io.c |
3 | * | 3 | * |
4 | * Copyright (C) 2000 Stuart Menefy | 4 | * Copyright (C) 2000 Stuart Menefy |
5 | * Copyright (C) 2005 Paul Mundt | ||
5 | * | 6 | * |
6 | * Provide real functions which expand to whatever the header file defined. | 7 | * Provide real functions which expand to whatever the header file defined. |
7 | * Also definitions of machine independent IO functions. | 8 | * Also definitions of machine independent IO functions. |
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. | ||
8 | */ | 13 | */ |
9 | |||
10 | #include <asm/io.h> | ||
11 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <asm/machvec.h> | ||
16 | #include <asm/io.h> | ||
12 | 17 | ||
13 | /* | 18 | /* |
14 | * Copy data from IO memory space to "real" memory space. | 19 | * Copy data from IO memory space to "real" memory space. |
15 | * This needs to be optimized. | 20 | * This needs to be optimized. |
16 | */ | 21 | */ |
17 | void memcpy_fromio(void * to, unsigned long from, unsigned long count) | 22 | void memcpy_fromio(void *to, volatile void __iomem *from, unsigned long count) |
18 | { | 23 | { |
19 | char *p = to; | 24 | char *p = to; |
20 | while (count) { | 25 | while (count) { |
21 | count--; | 26 | count--; |
22 | *p = readb(from); | 27 | *p = readb((void __iomem *)from); |
23 | p++; | 28 | p++; |
24 | from++; | 29 | from++; |
25 | } | 30 | } |
26 | } | 31 | } |
27 | 32 | EXPORT_SYMBOL(memcpy_fromio); | |
33 | |||
28 | /* | 34 | /* |
29 | * Copy data from "real" memory space to IO memory space. | 35 | * Copy data from "real" memory space to IO memory space. |
30 | * This needs to be optimized. | 36 | * This needs to be optimized. |
31 | */ | 37 | */ |
32 | void memcpy_toio(unsigned long to, const void * from, unsigned long count) | 38 | void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count) |
33 | { | 39 | { |
34 | const char *p = from; | 40 | const char *p = from; |
35 | while (count) { | 41 | while (count) { |
36 | count--; | 42 | count--; |
37 | writeb(*p, to); | 43 | writeb(*p, (void __iomem *)to); |
38 | p++; | 44 | p++; |
39 | to++; | 45 | to++; |
40 | } | 46 | } |
41 | } | 47 | } |
42 | 48 | EXPORT_SYMBOL(memcpy_toio); | |
49 | |||
43 | /* | 50 | /* |
44 | * "memset" on IO memory space. | 51 | * "memset" on IO memory space. |
45 | * This needs to be optimized. | 52 | * This needs to be optimized. |
46 | */ | 53 | */ |
47 | void memset_io(unsigned long dst, int c, unsigned long count) | 54 | void memset_io(volatile void __iomem *dst, int c, unsigned long count) |
48 | { | 55 | { |
49 | while (count) { | 56 | while (count) { |
50 | count--; | 57 | count--; |
51 | writeb(c, dst); | 58 | writeb(c, (void __iomem *)dst); |
52 | dst++; | 59 | dst++; |
53 | } | 60 | } |
54 | } | 61 | } |
55 | |||
56 | EXPORT_SYMBOL(memcpy_fromio); | ||
57 | EXPORT_SYMBOL(memcpy_toio); | ||
58 | EXPORT_SYMBOL(memset_io); | 62 | EXPORT_SYMBOL(memset_io); |
59 | 63 | ||
64 | void __iomem *ioport_map(unsigned long port, unsigned int nr) | ||
65 | { | ||
66 | return sh_mv.mv_ioport_map(port, nr); | ||
67 | } | ||
68 | EXPORT_SYMBOL(ioport_map); | ||
69 | |||
70 | void ioport_unmap(void __iomem *addr) | ||
71 | { | ||
72 | sh_mv.mv_ioport_unmap(addr); | ||
73 | } | ||
74 | EXPORT_SYMBOL(ioport_unmap); | ||
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c index a911b0149d1f..28ec7487de8c 100644 --- a/arch/sh/kernel/io_generic.c +++ b/arch/sh/kernel/io_generic.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * linux/arch/sh/kernel/io_generic.c | 3 | * linux/arch/sh/kernel/io_generic.c |
4 | * | 4 | * |
5 | * Copyright (C) 2000 Niibe Yutaka | 5 | * Copyright (C) 2000 Niibe Yutaka |
6 | * Copyright (C) 2005 Paul Mundt | ||
6 | * | 7 | * |
7 | * Generic I/O routine. These can be used where a machine specific version | 8 | * Generic I/O routine. These can be used where a machine specific version |
8 | * is not required. | 9 | * is not required. |
@@ -10,21 +11,20 @@ | |||
10 | * This file is subject to the terms and conditions of the GNU General Public | 11 | * 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 | * License. See the file "COPYING" in the main directory of this archive |
12 | * for more details. | 13 | * for more details. |
13 | * | ||
14 | */ | 14 | */ |
15 | 15 | #include <linux/module.h> | |
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <asm/machvec.h> | 17 | #include <asm/machvec.h> |
18 | #include <linux/module.h> | ||
19 | 18 | ||
20 | #if defined(CONFIG_CPU_SH3) | 19 | #ifdef CONFIG_CPU_SH3 |
20 | /* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a | ||
21 | * workaround. */ | ||
21 | /* I'm not sure SH7709 has this kind of bug */ | 22 | /* I'm not sure SH7709 has this kind of bug */ |
22 | #define SH3_PCMCIA_BUG_WORKAROUND 1 | 23 | #define dummy_read() ctrl_inb(0xba000000) |
23 | #define DUMMY_READ_AREA6 0xba000000 | 24 | #else |
25 | #define dummy_read() | ||
24 | #endif | 26 | #endif |
25 | 27 | ||
26 | #define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x)) | ||
27 | |||
28 | unsigned long generic_io_base; | 28 | unsigned long generic_io_base; |
29 | 29 | ||
30 | static inline void delay(void) | 30 | static inline void delay(void) |
@@ -32,40 +32,40 @@ static inline void delay(void) | |||
32 | ctrl_inw(0xa0000000); | 32 | ctrl_inw(0xa0000000); |
33 | } | 33 | } |
34 | 34 | ||
35 | unsigned char generic_inb(unsigned long port) | 35 | u8 generic_inb(unsigned long port) |
36 | { | 36 | { |
37 | return *(volatile unsigned char*)PORT2ADDR(port); | 37 | return ctrl_inb((unsigned long __force)ioport_map(port, 1)); |
38 | } | 38 | } |
39 | 39 | ||
40 | unsigned short generic_inw(unsigned long port) | 40 | u16 generic_inw(unsigned long port) |
41 | { | 41 | { |
42 | return *(volatile unsigned short*)PORT2ADDR(port); | 42 | return ctrl_inw((unsigned long __force)ioport_map(port, 2)); |
43 | } | 43 | } |
44 | 44 | ||
45 | unsigned int generic_inl(unsigned long port) | 45 | u32 generic_inl(unsigned long port) |
46 | { | 46 | { |
47 | return *(volatile unsigned long*)PORT2ADDR(port); | 47 | return ctrl_inl((unsigned long __force)ioport_map(port, 4)); |
48 | } | 48 | } |
49 | 49 | ||
50 | unsigned char generic_inb_p(unsigned long port) | 50 | u8 generic_inb_p(unsigned long port) |
51 | { | 51 | { |
52 | unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); | 52 | unsigned long v = generic_inb(port); |
53 | 53 | ||
54 | delay(); | 54 | delay(); |
55 | return v; | 55 | return v; |
56 | } | 56 | } |
57 | 57 | ||
58 | unsigned short generic_inw_p(unsigned long port) | 58 | u16 generic_inw_p(unsigned long port) |
59 | { | 59 | { |
60 | unsigned long v = *(volatile unsigned short*)PORT2ADDR(port); | 60 | unsigned long v = generic_inw(port); |
61 | 61 | ||
62 | delay(); | 62 | delay(); |
63 | return v; | 63 | return v; |
64 | } | 64 | } |
65 | 65 | ||
66 | unsigned int generic_inl_p(unsigned long port) | 66 | u32 generic_inl_p(unsigned long port) |
67 | { | 67 | { |
68 | unsigned long v = *(volatile unsigned long*)PORT2ADDR(port); | 68 | unsigned long v = generic_inl(port); |
69 | 69 | ||
70 | delay(); | 70 | delay(); |
71 | return v; | 71 | return v; |
@@ -77,75 +77,70 @@ unsigned int generic_inl_p(unsigned long port) | |||
77 | * convert the port address to real address once. | 77 | * convert the port address to real address once. |
78 | */ | 78 | */ |
79 | 79 | ||
80 | void generic_insb(unsigned long port, void *buffer, unsigned long count) | 80 | void generic_insb(unsigned long port, void *dst, unsigned long count) |
81 | { | 81 | { |
82 | volatile unsigned char *port_addr; | 82 | volatile u8 *port_addr; |
83 | unsigned char *buf=buffer; | 83 | u8 *buf = dst; |
84 | |||
85 | port_addr = (volatile unsigned char *)PORT2ADDR(port); | ||
86 | 84 | ||
87 | while(count--) | 85 | port_addr = (volatile u8 *)ioport_map(port, 1); |
88 | *buf++ = *port_addr; | 86 | while (count--) |
87 | *buf++ = *port_addr; | ||
89 | } | 88 | } |
90 | 89 | ||
91 | void generic_insw(unsigned long port, void *buffer, unsigned long count) | 90 | void generic_insw(unsigned long port, void *dst, unsigned long count) |
92 | { | 91 | { |
93 | volatile unsigned short *port_addr; | 92 | volatile u16 *port_addr; |
94 | unsigned short *buf=buffer; | 93 | u16 *buf = dst; |
95 | 94 | ||
96 | port_addr = (volatile unsigned short *)PORT2ADDR(port); | 95 | port_addr = (volatile u16 *)ioport_map(port, 2); |
96 | while (count--) | ||
97 | *buf++ = *port_addr; | ||
97 | 98 | ||
98 | while(count--) | 99 | dummy_read(); |
99 | *buf++ = *port_addr; | ||
100 | #ifdef SH3_PCMCIA_BUG_WORKAROUND | ||
101 | ctrl_inb (DUMMY_READ_AREA6); | ||
102 | #endif | ||
103 | } | 100 | } |
104 | 101 | ||
105 | void generic_insl(unsigned long port, void *buffer, unsigned long count) | 102 | void generic_insl(unsigned long port, void *dst, unsigned long count) |
106 | { | 103 | { |
107 | volatile unsigned long *port_addr; | 104 | volatile u32 *port_addr; |
108 | unsigned long *buf=buffer; | 105 | u32 *buf = dst; |
109 | 106 | ||
110 | port_addr = (volatile unsigned long *)PORT2ADDR(port); | 107 | port_addr = (volatile u32 *)ioport_map(port, 4); |
108 | while (count--) | ||
109 | *buf++ = *port_addr; | ||
111 | 110 | ||
112 | while(count--) | 111 | dummy_read(); |
113 | *buf++ = *port_addr; | ||
114 | #ifdef SH3_PCMCIA_BUG_WORKAROUND | ||
115 | ctrl_inb (DUMMY_READ_AREA6); | ||
116 | #endif | ||
117 | } | 112 | } |
118 | 113 | ||
119 | void generic_outb(unsigned char b, unsigned long port) | 114 | void generic_outb(u8 b, unsigned long port) |
120 | { | 115 | { |
121 | *(volatile unsigned char*)PORT2ADDR(port) = b; | 116 | ctrl_outb(b, (unsigned long __force)ioport_map(port, 1)); |
122 | } | 117 | } |
123 | 118 | ||
124 | void generic_outw(unsigned short b, unsigned long port) | 119 | void generic_outw(u16 b, unsigned long port) |
125 | { | 120 | { |
126 | *(volatile unsigned short*)PORT2ADDR(port) = b; | 121 | ctrl_outw(b, (unsigned long __force)ioport_map(port, 2)); |
127 | } | 122 | } |
128 | 123 | ||
129 | void generic_outl(unsigned int b, unsigned long port) | 124 | void generic_outl(u32 b, unsigned long port) |
130 | { | 125 | { |
131 | *(volatile unsigned long*)PORT2ADDR(port) = b; | 126 | ctrl_outl(b, (unsigned long __force)ioport_map(port, 4)); |
132 | } | 127 | } |
133 | 128 | ||
134 | void generic_outb_p(unsigned char b, unsigned long port) | 129 | void generic_outb_p(u8 b, unsigned long port) |
135 | { | 130 | { |
136 | *(volatile unsigned char*)PORT2ADDR(port) = b; | 131 | generic_outb(b, port); |
137 | delay(); | 132 | delay(); |
138 | } | 133 | } |
139 | 134 | ||
140 | void generic_outw_p(unsigned short b, unsigned long port) | 135 | void generic_outw_p(u16 b, unsigned long port) |
141 | { | 136 | { |
142 | *(volatile unsigned short*)PORT2ADDR(port) = b; | 137 | generic_outw(b, port); |
143 | delay(); | 138 | delay(); |
144 | } | 139 | } |
145 | 140 | ||
146 | void generic_outl_p(unsigned int b, unsigned long port) | 141 | void generic_outl_p(u32 b, unsigned long port) |
147 | { | 142 | { |
148 | *(volatile unsigned long*)PORT2ADDR(port) = b; | 143 | generic_outl(b, port); |
149 | delay(); | 144 | delay(); |
150 | } | 145 | } |
151 | 146 | ||
@@ -154,90 +149,77 @@ void generic_outl_p(unsigned int b, unsigned long port) | |||
154 | * address. However as the port address doesn't change we only need to | 149 | * address. However as the port address doesn't change we only need to |
155 | * convert the port address to real address once. | 150 | * convert the port address to real address once. |
156 | */ | 151 | */ |
157 | 152 | void generic_outsb(unsigned long port, const void *src, unsigned long count) | |
158 | void generic_outsb(unsigned long port, const void *buffer, unsigned long count) | ||
159 | { | 153 | { |
160 | volatile unsigned char *port_addr; | 154 | volatile u8 *port_addr; |
161 | const unsigned char *buf=buffer; | 155 | const u8 *buf = src; |
162 | 156 | ||
163 | port_addr = (volatile unsigned char *)PORT2ADDR(port); | 157 | port_addr = (volatile u8 __force *)ioport_map(port, 1); |
164 | 158 | ||
165 | while(count--) | 159 | while (count--) |
166 | *port_addr = *buf++; | 160 | *port_addr = *buf++; |
167 | } | 161 | } |
168 | 162 | ||
169 | void generic_outsw(unsigned long port, const void *buffer, unsigned long count) | 163 | void generic_outsw(unsigned long port, const void *src, unsigned long count) |
170 | { | 164 | { |
171 | volatile unsigned short *port_addr; | 165 | volatile u16 *port_addr; |
172 | const unsigned short *buf=buffer; | 166 | const u16 *buf = src; |
173 | 167 | ||
174 | port_addr = (volatile unsigned short *)PORT2ADDR(port); | 168 | port_addr = (volatile u16 __force *)ioport_map(port, 2); |
175 | 169 | ||
176 | while(count--) | 170 | while (count--) |
177 | *port_addr = *buf++; | 171 | *port_addr = *buf++; |
178 | 172 | ||
179 | #ifdef SH3_PCMCIA_BUG_WORKAROUND | 173 | dummy_read(); |
180 | ctrl_inb (DUMMY_READ_AREA6); | ||
181 | #endif | ||
182 | } | 174 | } |
183 | 175 | ||
184 | void generic_outsl(unsigned long port, const void *buffer, unsigned long count) | 176 | void generic_outsl(unsigned long port, const void *src, unsigned long count) |
185 | { | 177 | { |
186 | volatile unsigned long *port_addr; | 178 | volatile u32 *port_addr; |
187 | const unsigned long *buf=buffer; | 179 | const u32 *buf = src; |
188 | 180 | ||
189 | port_addr = (volatile unsigned long *)PORT2ADDR(port); | 181 | port_addr = (volatile u32 __force *)ioport_map(port, 4); |
182 | while (count--) | ||
183 | *port_addr = *buf++; | ||
190 | 184 | ||
191 | while(count--) | 185 | dummy_read(); |
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 | } | 186 | } |
203 | 187 | ||
204 | unsigned short generic_readw(unsigned long addr) | 188 | u8 generic_readb(void __iomem *addr) |
205 | { | 189 | { |
206 | return *(volatile unsigned short*)addr; | 190 | return ctrl_inb((unsigned long __force)addr); |
207 | } | 191 | } |
208 | 192 | ||
209 | unsigned int generic_readl(unsigned long addr) | 193 | u16 generic_readw(void __iomem *addr) |
210 | { | 194 | { |
211 | return *(volatile unsigned long*)addr; | 195 | return ctrl_inw((unsigned long __force)addr); |
212 | } | 196 | } |
213 | 197 | ||
214 | void generic_writeb(unsigned char b, unsigned long addr) | 198 | u32 generic_readl(void __iomem *addr) |
215 | { | 199 | { |
216 | *(volatile unsigned char*)addr = b; | 200 | return ctrl_inl((unsigned long __force)addr); |
217 | } | 201 | } |
218 | 202 | ||
219 | void generic_writew(unsigned short b, unsigned long addr) | 203 | void generic_writeb(u8 b, void __iomem *addr) |
220 | { | 204 | { |
221 | *(volatile unsigned short*)addr = b; | 205 | ctrl_outb(b, (unsigned long __force)addr); |
222 | } | 206 | } |
223 | 207 | ||
224 | void generic_writel(unsigned int b, unsigned long addr) | 208 | void generic_writew(u16 b, void __iomem *addr) |
225 | { | 209 | { |
226 | *(volatile unsigned long*)addr = b; | 210 | ctrl_outw(b, (unsigned long __force)addr); |
227 | } | 211 | } |
228 | 212 | ||
229 | void * generic_ioremap(unsigned long offset, unsigned long size) | 213 | void generic_writel(u32 b, void __iomem *addr) |
230 | { | 214 | { |
231 | return (void *) P2SEGADDR(offset); | 215 | ctrl_outl(b, (unsigned long __force)addr); |
232 | } | 216 | } |
233 | EXPORT_SYMBOL(generic_ioremap); | ||
234 | 217 | ||
235 | void generic_iounmap(void *addr) | 218 | void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) |
236 | { | 219 | { |
220 | return (void __iomem *)(addr + generic_io_base); | ||
237 | } | 221 | } |
238 | EXPORT_SYMBOL(generic_iounmap); | ||
239 | 222 | ||
240 | unsigned long generic_isa_port2addr(unsigned long offset) | 223 | void generic_ioport_unmap(void __iomem *addr) |
241 | { | 224 | { |
242 | return offset + generic_io_base; | ||
243 | } | 225 | } |
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 54c171225b78..6883c00728cb 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -8,38 +8,13 @@ | |||
8 | * SuperH version: Copyright (C) 1999 Niibe Yutaka | 8 | * SuperH version: Copyright (C) 1999 Niibe Yutaka |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* | 11 | #include <linux/irq.h> |
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> | 12 | #include <linux/interrupt.h> |
25 | #include <linux/timex.h> | 13 | #include <linux/kernel_stat.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> | 14 | #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> | 15 | #include <asm/irq.h> |
41 | #include <linux/irq.h> | 16 | #include <asm/processor.h> |
42 | 17 | #include <asm/cpu/mmu_context.h> | |
43 | 18 | ||
44 | /* | 19 | /* |
45 | * 'what should we do if we get a hw irq event on an illegal vector'. | 20 | * 'what should we do if we get a hw irq event on an illegal vector'. |
@@ -66,7 +41,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
66 | seq_putc(p, '\n'); | 41 | seq_putc(p, '\n'); |
67 | } | 42 | } |
68 | 43 | ||
69 | if (i < ACTUAL_NR_IRQS) { | 44 | if (i < NR_IRQS) { |
70 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 45 | spin_lock_irqsave(&irq_desc[i].lock, flags); |
71 | action = irq_desc[i].action; | 46 | action = irq_desc[i].action; |
72 | if (!action) | 47 | if (!action) |
@@ -86,19 +61,32 @@ unlock: | |||
86 | } | 61 | } |
87 | #endif | 62 | #endif |
88 | 63 | ||
64 | |||
89 | asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, | 65 | asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, |
90 | unsigned long r6, unsigned long r7, | 66 | unsigned long r6, unsigned long r7, |
91 | struct pt_regs regs) | 67 | struct pt_regs regs) |
92 | { | 68 | { |
93 | int irq; | 69 | int irq = r4; |
94 | 70 | ||
95 | irq_enter(); | 71 | irq_enter(); |
96 | asm volatile("stc r2_bank, %0\n\t" | 72 | |
97 | "shlr2 %0\n\t" | 73 | #ifdef CONFIG_CPU_HAS_INTEVT |
98 | "shlr2 %0\n\t" | 74 | __asm__ __volatile__ ( |
99 | "shlr %0\n\t" | 75 | #ifdef CONFIG_CPU_HAS_SR_RB |
100 | "add #-16, %0\n\t" | 76 | "stc r2_bank, %0\n\t" |
101 | :"=z" (irq)); | 77 | #else |
78 | "mov.l @%1, %0\n\t" | ||
79 | #endif | ||
80 | "shlr2 %0\n\t" | ||
81 | "shlr2 %0\n\t" | ||
82 | "shlr %0\n\t" | ||
83 | "add #-16, %0\n\t" | ||
84 | : "=z" (irq), "=r" (r4) | ||
85 | : "1" (INTEVT) | ||
86 | : "memory" | ||
87 | ); | ||
88 | #endif | ||
89 | |||
102 | irq = irq_demux(irq); | 90 | irq = irq_demux(irq); |
103 | __do_IRQ(irq, ®s); | 91 | __do_IRQ(irq, ®s); |
104 | irq_exit(); | 92 | irq_exit(); |
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c new file mode 100644 index 000000000000..43546525f28f --- /dev/null +++ b/arch/sh/kernel/machine_kexec.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz | ||
6 | * LANDISK/sh4 supported by kogiidena | ||
7 | * | ||
8 | * This source code is licensed under the GNU General Public License, | ||
9 | * Version 2. See the file COPYING for more details. | ||
10 | */ | ||
11 | |||
12 | #include <linux/mm.h> | ||
13 | #include <linux/kexec.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <asm/pgtable.h> | ||
17 | #include <asm/pgalloc.h> | ||
18 | #include <asm/mmu_context.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/cacheflush.h> | ||
21 | |||
22 | typedef NORET_TYPE void (*relocate_new_kernel_t)( | ||
23 | unsigned long indirection_page, | ||
24 | unsigned long reboot_code_buffer, | ||
25 | unsigned long start_address, | ||
26 | unsigned long vbr_reg) ATTRIB_NORET; | ||
27 | |||
28 | const extern unsigned char relocate_new_kernel[]; | ||
29 | const extern unsigned int relocate_new_kernel_size; | ||
30 | extern void *gdb_vbr_vector; | ||
31 | |||
32 | /* | ||
33 | * Provide a dummy crash_notes definition while crash dump arrives to ppc. | ||
34 | * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. | ||
35 | */ | ||
36 | void *crash_notes = NULL; | ||
37 | |||
38 | void machine_shutdown(void) | ||
39 | { | ||
40 | } | ||
41 | |||
42 | void machine_crash_shutdown(struct pt_regs *regs) | ||
43 | { | ||
44 | } | ||
45 | |||
46 | /* | ||
47 | * Do what every setup is needed on image and the | ||
48 | * reboot code buffer to allow us to avoid allocations | ||
49 | * later. | ||
50 | */ | ||
51 | int machine_kexec_prepare(struct kimage *image) | ||
52 | { | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | void machine_kexec_cleanup(struct kimage *image) | ||
57 | { | ||
58 | } | ||
59 | |||
60 | static void kexec_info(struct kimage *image) | ||
61 | { | ||
62 | int i; | ||
63 | printk("kexec information\n"); | ||
64 | for (i = 0; i < image->nr_segments; i++) { | ||
65 | printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n", | ||
66 | i, | ||
67 | (unsigned int)image->segment[i].mem, | ||
68 | (unsigned int)image->segment[i].mem + image->segment[i].memsz, | ||
69 | (unsigned int)image->segment[i].memsz); | ||
70 | } | ||
71 | printk(" start : 0x%08x\n\n", (unsigned int)image->start); | ||
72 | } | ||
73 | |||
74 | |||
75 | /* | ||
76 | * Do not allocate memory (or fail in any way) in machine_kexec(). | ||
77 | * We are past the point of no return, committed to rebooting now. | ||
78 | */ | ||
79 | NORET_TYPE void machine_kexec(struct kimage *image) | ||
80 | { | ||
81 | |||
82 | unsigned long page_list; | ||
83 | unsigned long reboot_code_buffer; | ||
84 | unsigned long vbr_reg; | ||
85 | relocate_new_kernel_t rnk; | ||
86 | |||
87 | #if defined(CONFIG_SH_STANDARD_BIOS) | ||
88 | vbr_reg = ((unsigned long )gdb_vbr_vector) - 0x100; | ||
89 | #else | ||
90 | vbr_reg = 0x80000000; // dummy | ||
91 | #endif | ||
92 | /* Interrupts aren't acceptable while we reboot */ | ||
93 | local_irq_disable(); | ||
94 | |||
95 | page_list = image->head; | ||
96 | |||
97 | /* we need both effective and real address here */ | ||
98 | reboot_code_buffer = | ||
99 | (unsigned long)page_address(image->control_code_page); | ||
100 | |||
101 | /* copy our kernel relocation code to the control code page */ | ||
102 | memcpy((void *)reboot_code_buffer, relocate_new_kernel, | ||
103 | relocate_new_kernel_size); | ||
104 | |||
105 | kexec_info(image); | ||
106 | flush_cache_all(); | ||
107 | |||
108 | /* now call it */ | ||
109 | rnk = (relocate_new_kernel_t) reboot_code_buffer; | ||
110 | (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); | ||
111 | } | ||
112 | |||
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index aac15e42d03b..a4dc2b532e10 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c | |||
@@ -71,6 +71,16 @@ void cpu_idle(void) | |||
71 | 71 | ||
72 | void machine_restart(char * __unused) | 72 | void machine_restart(char * __unused) |
73 | { | 73 | { |
74 | |||
75 | #ifdef CONFIG_KEXEC | ||
76 | struct kimage *image; | ||
77 | image = xchg(&kexec_image, 0); | ||
78 | if (image) { | ||
79 | machine_shutdown(); | ||
80 | machine_kexec(image); | ||
81 | } | ||
82 | #endif | ||
83 | |||
74 | /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ | 84 | /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ |
75 | asm volatile("ldc %0, sr\n\t" | 85 | asm volatile("ldc %0, sr\n\t" |
76 | "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); | 86 | "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); |
diff --git a/arch/sh/kernel/relocate_kernel.S b/arch/sh/kernel/relocate_kernel.S new file mode 100644 index 000000000000..b0695cffec6e --- /dev/null +++ b/arch/sh/kernel/relocate_kernel.S | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * relocate_kernel.S - put the kernel image in place to boot | ||
3 | * 2005.9.17 kogiidena@eggplant.ddo.jp | ||
4 | * | ||
5 | * LANDISK/sh4 is supported. Maybe, SH archtecture works well. | ||
6 | * | ||
7 | * This source code is licensed under the GNU General Public License, | ||
8 | * Version 2. See the file COPYING for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #include <linux/linkage.h> | ||
13 | |||
14 | #define PAGE_SIZE 4096 /* must be same value as in <asm/page.h> */ | ||
15 | |||
16 | |||
17 | .globl relocate_new_kernel | ||
18 | relocate_new_kernel: | ||
19 | /* r4 = indirection_page */ | ||
20 | /* r5 = reboot_code_buffer */ | ||
21 | /* r6 = start_address */ | ||
22 | /* r7 = vbr_reg */ | ||
23 | |||
24 | mov.l 10f,r8 /* 4096 */ | ||
25 | mov.l 11f,r9 /* 0xa0000000 */ | ||
26 | |||
27 | /* stack setting */ | ||
28 | add r8,r5 | ||
29 | mov r5,r15 | ||
30 | |||
31 | bra 1f | ||
32 | mov r4,r0 /* cmd = indirection_page */ | ||
33 | 0: | ||
34 | mov.l @r4+,r0 /* cmd = *ind++ */ | ||
35 | |||
36 | 1: /* addr = (cmd | 0xa0000000) & 0xfffffff0 */ | ||
37 | mov r0,r2 | ||
38 | or r9,r2 | ||
39 | mov #-16,r1 | ||
40 | and r1,r2 | ||
41 | |||
42 | /* if(cmd & IND_DESTINATION) dst = addr */ | ||
43 | tst #1,r0 | ||
44 | bt 2f | ||
45 | bra 0b | ||
46 | mov r2,r5 | ||
47 | |||
48 | 2: /* else if(cmd & IND_INDIRECTION) ind = addr */ | ||
49 | tst #2,r0 | ||
50 | bt 3f | ||
51 | bra 0b | ||
52 | mov r2,r4 | ||
53 | |||
54 | 3: /* else if(cmd & IND_DONE) goto 6 */ | ||
55 | tst #4,r0 | ||
56 | bt 4f | ||
57 | bra 6f | ||
58 | nop | ||
59 | |||
60 | 4: /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */ | ||
61 | tst #8,r0 | ||
62 | bt 0b | ||
63 | |||
64 | mov r8,r3 | ||
65 | shlr2 r3 | ||
66 | shlr2 r3 | ||
67 | 5: | ||
68 | dt r3 | ||
69 | mov.l @r2+,r1 /* 16n+0 */ | ||
70 | mov.l r1,@r5 | ||
71 | add #4,r5 | ||
72 | mov.l @r2+,r1 /* 16n+4 */ | ||
73 | mov.l r1,@r5 | ||
74 | add #4,r5 | ||
75 | mov.l @r2+,r1 /* 16n+8 */ | ||
76 | mov.l r1,@r5 | ||
77 | add #4,r5 | ||
78 | mov.l @r2+,r1 /* 16n+12 */ | ||
79 | mov.l r1,@r5 | ||
80 | add #4,r5 | ||
81 | bf 5b | ||
82 | |||
83 | bra 0b | ||
84 | nop | ||
85 | 6: | ||
86 | #ifdef CONFIG_SH_STANDARD_BIOS | ||
87 | ldc r7, vbr | ||
88 | #endif | ||
89 | jmp @r6 | ||
90 | nop | ||
91 | |||
92 | .align 2 | ||
93 | 10: | ||
94 | .long PAGE_SIZE | ||
95 | 11: | ||
96 | .long 0xa0000000 | ||
97 | |||
98 | relocate_new_kernel_end: | ||
99 | |||
100 | .globl relocate_new_kernel_size | ||
101 | relocate_new_kernel_size: | ||
102 | .long relocate_new_kernel_end - relocate_new_kernel | ||
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 671b876416bf..314a275c04e0 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | 4 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka |
5 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | 5 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> |
6 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | 6 | * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt |
7 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | 7 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> |
8 | * | 8 | * |
9 | * Some code taken from i386 version. | 9 | * Some code taken from i386 version. |
@@ -11,50 +11,21 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 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> | 14 | #include <linux/kernel.h> |
18 | #include <linux/param.h> | 15 | #include <linux/module.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> | 16 | #include <linux/init.h> |
25 | #include <linux/smp.h> | ||
26 | #include <linux/profile.h> | 17 | #include <linux/profile.h> |
27 | 18 | #include <asm/clock.h> | |
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> | 19 | #include <asm/rtc.h> |
35 | #include <asm/freq.h> | 20 | #include <asm/timer.h> |
36 | #include <asm/cpu/timer.h> | ||
37 | #ifdef CONFIG_SH_KGDB | ||
38 | #include <asm/kgdb.h> | 21 | #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 | 22 | ||
55 | extern unsigned long wall_jiffies; | 23 | extern unsigned long wall_jiffies; |
56 | #define TICK_SIZE (tick_nsec / 1000) | 24 | struct sys_timer *sys_timer; |
57 | DEFINE_SPINLOCK(tmu0_lock); | 25 | |
26 | /* Move this somewhere more sensible.. */ | ||
27 | DEFINE_SPINLOCK(rtc_lock); | ||
28 | EXPORT_SYMBOL(rtc_lock); | ||
58 | 29 | ||
59 | /* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want | 30 | /* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want |
60 | * these routines anywhere... */ | 31 | * these routines anywhere... */ |
@@ -66,98 +37,14 @@ void (*rtc_get_time)(struct timespec *); | |||
66 | int (*rtc_set_time)(const time_t); | 37 | int (*rtc_set_time)(const time_t); |
67 | #endif | 38 | #endif |
68 | 39 | ||
69 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
70 | static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; | ||
71 | #endif | ||
72 | #if defined(CONFIG_CPU_SH3) | ||
73 | static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
74 | static int stc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; | ||
75 | #define bfc_divisors stc_multipliers | ||
76 | #define bfc_values stc_values | ||
77 | static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; | ||
78 | static int ifc_values[] = { 0, 1, 4, 2, 0, 0, 0, 0 }; | ||
79 | static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; | ||
80 | static int pfc_values[] = { 0, 1, 4, 2, 5, 0, 0, 0 }; | ||
81 | #elif defined(CONFIG_CPU_SH4) | ||
82 | #if defined(CONFIG_CPU_SUBTYPE_SH73180) | ||
83 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; | ||
84 | static int ifc_values[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; | ||
85 | #define bfc_divisors ifc_divisors /* Same */ | ||
86 | #define bfc_values ifc_values | ||
87 | #define pfc_divisors ifc_divisors /* Same */ | ||
88 | #define pfc_values ifc_values | ||
89 | #else | ||
90 | static int ifc_divisors[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; | ||
91 | static int ifc_values[] = { 0, 1, 2, 3, 0, 4, 0, 5 }; | ||
92 | #define bfc_divisors ifc_divisors /* Same */ | ||
93 | #define bfc_values ifc_values | ||
94 | static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; | ||
95 | static int pfc_values[] = { 0, 0, 1, 2, 0, 3, 0, 4 }; | ||
96 | #endif | ||
97 | #else | ||
98 | #error "Unknown ifc/bfc/pfc/stc values for this processor" | ||
99 | #endif | ||
100 | |||
101 | /* | 40 | /* |
102 | * Scheduler clock - returns current time in nanosec units. | 41 | * Scheduler clock - returns current time in nanosec units. |
103 | */ | 42 | */ |
104 | unsigned long long sched_clock(void) | 43 | unsigned long long __attribute__ ((weak)) sched_clock(void) |
105 | { | 44 | { |
106 | return (unsigned long long)jiffies * (1000000000 / HZ); | 45 | return (unsigned long long)jiffies * (1000000000 / HZ); |
107 | } | 46 | } |
108 | 47 | ||
109 | static unsigned long do_gettimeoffset(void) | ||
110 | { | ||
111 | int count; | ||
112 | unsigned long flags; | ||
113 | |||
114 | static int count_p = 0x7fffffff; /* for the first call after boot */ | ||
115 | static unsigned long jiffies_p = 0; | ||
116 | |||
117 | /* | ||
118 | * cache volatile jiffies temporarily; we have IRQs turned off. | ||
119 | */ | ||
120 | unsigned long jiffies_t; | ||
121 | |||
122 | spin_lock_irqsave(&tmu0_lock, flags); | ||
123 | /* timer count may underflow right here */ | ||
124 | count = ctrl_inl(TMU0_TCNT); /* read the latched count */ | ||
125 | |||
126 | jiffies_t = jiffies; | ||
127 | |||
128 | /* | ||
129 | * avoiding timer inconsistencies (they are rare, but they happen)... | ||
130 | * there is one kind of problem that must be avoided here: | ||
131 | * 1. the timer counter underflows | ||
132 | */ | ||
133 | |||
134 | if( jiffies_t == jiffies_p ) { | ||
135 | if( count > count_p ) { | ||
136 | /* the nutcase */ | ||
137 | |||
138 | if(ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */ | ||
139 | /* | ||
140 | * We cannot detect lost timer interrupts ... | ||
141 | * well, that's why we call them lost, don't we? :) | ||
142 | * [hmm, on the Pentium and Alpha we can ... sort of] | ||
143 | */ | ||
144 | count -= LATCH; | ||
145 | } else { | ||
146 | printk("do_slow_gettimeoffset(): hardware timer problem?\n"); | ||
147 | } | ||
148 | } | ||
149 | } else | ||
150 | jiffies_p = jiffies_t; | ||
151 | |||
152 | count_p = count; | ||
153 | spin_unlock_irqrestore(&tmu0_lock, flags); | ||
154 | |||
155 | count = ((LATCH-1) - count) * TICK_SIZE; | ||
156 | count = (count + LATCH/2) / LATCH; | ||
157 | |||
158 | return count; | ||
159 | } | ||
160 | |||
161 | void do_gettimeofday(struct timeval *tv) | 48 | void do_gettimeofday(struct timeval *tv) |
162 | { | 49 | { |
163 | unsigned long seq; | 50 | unsigned long seq; |
@@ -166,7 +53,7 @@ void do_gettimeofday(struct timeval *tv) | |||
166 | 53 | ||
167 | do { | 54 | do { |
168 | seq = read_seqbegin(&xtime_lock); | 55 | seq = read_seqbegin(&xtime_lock); |
169 | usec = do_gettimeoffset(); | 56 | usec = get_timer_offset(); |
170 | 57 | ||
171 | lost = jiffies - wall_jiffies; | 58 | lost = jiffies - wall_jiffies; |
172 | if (lost) | 59 | if (lost) |
@@ -202,7 +89,7 @@ int do_settimeofday(struct timespec *tv) | |||
202 | * wall time. Discover what correction gettimeofday() would have | 89 | * wall time. Discover what correction gettimeofday() would have |
203 | * made, and then undo it! | 90 | * made, and then undo it! |
204 | */ | 91 | */ |
205 | nsec -= 1000 * (do_gettimeoffset() + | 92 | nsec -= 1000 * (get_timer_offset() + |
206 | (jiffies - wall_jiffies) * (1000000 / HZ)); | 93 | (jiffies - wall_jiffies) * (1000000 / HZ)); |
207 | 94 | ||
208 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); | 95 | wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); |
@@ -224,10 +111,10 @@ EXPORT_SYMBOL(do_settimeofday); | |||
224 | static long last_rtc_update; | 111 | static long last_rtc_update; |
225 | 112 | ||
226 | /* | 113 | /* |
227 | * timer_interrupt() needs to keep up the real-time clock, | 114 | * handle_timer_tick() needs to keep up the real-time clock, |
228 | * as well as call the "do_timer()" routine every clocktick | 115 | * as well as call the "do_timer()" routine every clocktick |
229 | */ | 116 | */ |
230 | static inline void do_timer_interrupt(int irq, struct pt_regs *regs) | 117 | void handle_timer_tick(struct pt_regs *regs) |
231 | { | 118 | { |
232 | do_timer(regs); | 119 | do_timer(regs); |
233 | #ifndef CONFIG_SMP | 120 | #ifndef CONFIG_SMP |
@@ -252,337 +139,35 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) | |||
252 | if (rtc_set_time(xtime.tv_sec) == 0) | 139 | if (rtc_set_time(xtime.tv_sec) == 0) |
253 | last_rtc_update = xtime.tv_sec; | 140 | last_rtc_update = xtime.tv_sec; |
254 | else | 141 | else |
255 | last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ | 142 | /* do it again in 60s */ |
143 | last_rtc_update = xtime.tv_sec - 600; | ||
256 | } | 144 | } |
257 | } | 145 | } |
258 | 146 | ||
259 | /* | 147 | static struct sysdev_class timer_sysclass = { |
260 | * This is the same as the above, except we _also_ save the current | 148 | set_kset_name("timer"), |
261 | * Time Stamp Counter value at the time of the timer interrupt, so that | ||
262 | * we later on can estimate the time of day more exactly. | ||
263 | */ | ||
264 | static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
265 | { | ||
266 | unsigned long timer_status; | ||
267 | |||
268 | /* Clear UNF bit */ | ||
269 | timer_status = ctrl_inw(TMU0_TCR); | ||
270 | timer_status &= ~0x100; | ||
271 | ctrl_outw(timer_status, TMU0_TCR); | ||
272 | |||
273 | /* | ||
274 | * Here we are in the timer irq handler. We just have irqs locally | ||
275 | * disabled but we don't know if the timer_bh is running on the other | ||
276 | * CPU. We need to avoid to SMP race with it. NOTE: we don' t need | ||
277 | * the irq version of write_lock because as just said we have irq | ||
278 | * locally disabled. -arca | ||
279 | */ | ||
280 | write_seqlock(&xtime_lock); | ||
281 | do_timer_interrupt(irq, regs); | ||
282 | write_sequnlock(&xtime_lock); | ||
283 | |||
284 | return IRQ_HANDLED; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Hah! We'll see if this works (switching from usecs to nsecs). | ||
289 | */ | ||
290 | static unsigned int __init get_timer_frequency(void) | ||
291 | { | ||
292 | u32 freq; | ||
293 | struct timespec ts1, ts2; | ||
294 | unsigned long diff_nsec; | ||
295 | unsigned long factor; | ||
296 | |||
297 | /* Setup the timer: We don't want to generate interrupts, just | ||
298 | * have it count down at its natural rate. | ||
299 | */ | ||
300 | ctrl_outb(0, TMU_TSTR); | ||
301 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
302 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
303 | #endif | ||
304 | ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); | ||
305 | ctrl_outl(0xffffffff, TMU0_TCOR); | ||
306 | ctrl_outl(0xffffffff, TMU0_TCNT); | ||
307 | |||
308 | rtc_get_time(&ts2); | ||
309 | |||
310 | do { | ||
311 | rtc_get_time(&ts1); | ||
312 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
313 | |||
314 | /* actually start the timer */ | ||
315 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
316 | |||
317 | do { | ||
318 | rtc_get_time(&ts2); | ||
319 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
320 | |||
321 | freq = 0xffffffff - ctrl_inl(TMU0_TCNT); | ||
322 | if (ts2.tv_nsec < ts1.tv_nsec) { | ||
323 | ts2.tv_nsec += 1000000000; | ||
324 | ts2.tv_sec--; | ||
325 | } | ||
326 | |||
327 | diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); | ||
328 | |||
329 | /* this should work well if the RTC has a precision of n Hz, where | ||
330 | * n is an integer. I don't think we have to worry about the other | ||
331 | * cases. */ | ||
332 | factor = (1000000000 + diff_nsec/2) / diff_nsec; | ||
333 | |||
334 | if (factor * diff_nsec > 1100000000 || | ||
335 | factor * diff_nsec < 900000000) | ||
336 | panic("weird RTC (diff_nsec %ld)", diff_nsec); | ||
337 | |||
338 | return freq * factor; | ||
339 | } | ||
340 | |||
341 | void (*board_time_init)(void); | ||
342 | void (*board_timer_setup)(struct irqaction *irq); | ||
343 | |||
344 | static unsigned int sh_pclk_freq __initdata = CONFIG_SH_PCLK_FREQ; | ||
345 | |||
346 | static int __init sh_pclk_setup(char *str) | ||
347 | { | ||
348 | unsigned int freq; | ||
349 | |||
350 | if (get_option(&str, &freq)) | ||
351 | sh_pclk_freq = freq; | ||
352 | |||
353 | return 1; | ||
354 | } | ||
355 | __setup("sh_pclk=", sh_pclk_setup); | ||
356 | |||
357 | static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; | ||
358 | |||
359 | void get_current_frequency_divisors(unsigned int *ifc, unsigned int *bfc, unsigned int *pfc) | ||
360 | { | ||
361 | unsigned int frqcr = ctrl_inw(FRQCR); | ||
362 | |||
363 | #if defined(CONFIG_CPU_SH3) | ||
364 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
365 | *ifc = md_table[((frqcr & 0x0070) >> 4)]; | ||
366 | *bfc = md_table[((frqcr & 0x0700) >> 8)]; | ||
367 | *pfc = md_table[frqcr & 0x0007]; | ||
368 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
369 | *bfc = stc_multipliers[(frqcr & 0x0300) >> 8]; | ||
370 | *ifc = ifc_divisors[(frqcr & 0x0030) >> 4]; | ||
371 | *pfc = pfc_divisors[frqcr & 0x0003]; | ||
372 | #else | ||
373 | unsigned int tmp; | ||
374 | |||
375 | tmp = (frqcr & 0x8000) >> 13; | ||
376 | tmp |= (frqcr & 0x0030) >> 4; | ||
377 | *bfc = stc_multipliers[tmp]; | ||
378 | tmp = (frqcr & 0x4000) >> 12; | ||
379 | tmp |= (frqcr & 0x000c) >> 2; | ||
380 | *ifc = ifc_divisors[tmp]; | ||
381 | tmp = (frqcr & 0x2000) >> 11; | ||
382 | tmp |= frqcr & 0x0003; | ||
383 | *pfc = pfc_divisors[tmp]; | ||
384 | #endif | ||
385 | #elif defined(CONFIG_CPU_SH4) | ||
386 | #if defined(CONFIG_CPU_SUBTYPE_SH73180) | ||
387 | *ifc = ifc_divisors[(frqcr>> 20) & 0x0007]; | ||
388 | *bfc = bfc_divisors[(frqcr>> 12) & 0x0007]; | ||
389 | *pfc = pfc_divisors[frqcr & 0x0007]; | ||
390 | #else | ||
391 | *ifc = ifc_divisors[(frqcr >> 6) & 0x0007]; | ||
392 | *bfc = bfc_divisors[(frqcr >> 3) & 0x0007]; | ||
393 | *pfc = pfc_divisors[frqcr & 0x0007]; | ||
394 | #endif | ||
395 | #endif | ||
396 | } | ||
397 | |||
398 | /* | ||
399 | * This bit of ugliness builds up accessor routines to get at both | ||
400 | * the divisors and the physical values. | ||
401 | */ | ||
402 | #define _FREQ_TABLE(x) \ | ||
403 | unsigned int get_##x##_divisor(unsigned int value) \ | ||
404 | { return x##_divisors[value]; } \ | ||
405 | \ | ||
406 | unsigned int get_##x##_value(unsigned int divisor) \ | ||
407 | { return x##_values[(divisor - 1)]; } | ||
408 | |||
409 | _FREQ_TABLE(ifc); | ||
410 | _FREQ_TABLE(bfc); | ||
411 | _FREQ_TABLE(pfc); | ||
412 | |||
413 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
414 | |||
415 | /* | ||
416 | * The ST40 divisors are totally different so we set the cpu data | ||
417 | * clocks using a different algorithm | ||
418 | * | ||
419 | * I've just plugged this from the 2.4 code | ||
420 | * - Alex Bennee <kernel-hacker@bennee.com> | ||
421 | */ | ||
422 | #define CCN_PVR_CHIP_SHIFT 24 | ||
423 | #define CCN_PVR_CHIP_MASK 0xff | ||
424 | #define CCN_PVR_CHIP_ST40STB1 0x4 | ||
425 | |||
426 | |||
427 | struct frqcr_data { | ||
428 | unsigned short frqcr; | ||
429 | |||
430 | struct { | ||
431 | unsigned char multiplier; | ||
432 | unsigned char divisor; | ||
433 | } factor[3]; | ||
434 | }; | ||
435 | |||
436 | static struct frqcr_data st40_frqcr_table[] = { | ||
437 | { 0x000, {{1,1}, {1,1}, {1,2}}}, | ||
438 | { 0x002, {{1,1}, {1,1}, {1,4}}}, | ||
439 | { 0x004, {{1,1}, {1,1}, {1,8}}}, | ||
440 | { 0x008, {{1,1}, {1,2}, {1,2}}}, | ||
441 | { 0x00A, {{1,1}, {1,2}, {1,4}}}, | ||
442 | { 0x00C, {{1,1}, {1,2}, {1,8}}}, | ||
443 | { 0x011, {{1,1}, {2,3}, {1,6}}}, | ||
444 | { 0x013, {{1,1}, {2,3}, {1,3}}}, | ||
445 | { 0x01A, {{1,1}, {1,2}, {1,4}}}, | ||
446 | { 0x01C, {{1,1}, {1,2}, {1,8}}}, | ||
447 | { 0x023, {{1,1}, {2,3}, {1,3}}}, | ||
448 | { 0x02C, {{1,1}, {1,2}, {1,8}}}, | ||
449 | { 0x048, {{1,2}, {1,2}, {1,4}}}, | ||
450 | { 0x04A, {{1,2}, {1,2}, {1,6}}}, | ||
451 | { 0x04C, {{1,2}, {1,2}, {1,8}}}, | ||
452 | { 0x05A, {{1,2}, {1,3}, {1,6}}}, | ||
453 | { 0x05C, {{1,2}, {1,3}, {1,6}}}, | ||
454 | { 0x063, {{1,2}, {1,4}, {1,4}}}, | ||
455 | { 0x06C, {{1,2}, {1,4}, {1,8}}}, | ||
456 | { 0x091, {{1,3}, {1,3}, {1,6}}}, | ||
457 | { 0x093, {{1,3}, {1,3}, {1,6}}}, | ||
458 | { 0x0A3, {{1,3}, {1,6}, {1,6}}}, | ||
459 | { 0x0DA, {{1,4}, {1,4}, {1,8}}}, | ||
460 | { 0x0DC, {{1,4}, {1,4}, {1,8}}}, | ||
461 | { 0x0EC, {{1,4}, {1,8}, {1,8}}}, | ||
462 | { 0x123, {{1,4}, {1,4}, {1,8}}}, | ||
463 | { 0x16C, {{1,4}, {1,8}, {1,8}}}, | ||
464 | }; | 149 | }; |
465 | 150 | ||
466 | struct memclk_data { | 151 | static int __init timer_init_sysfs(void) |
467 | unsigned char multiplier; | ||
468 | unsigned char divisor; | ||
469 | }; | ||
470 | |||
471 | static struct memclk_data st40_memclk_table[8] = { | ||
472 | {1,1}, // 000 | ||
473 | {1,2}, // 001 | ||
474 | {1,3}, // 010 | ||
475 | {2,3}, // 011 | ||
476 | {1,4}, // 100 | ||
477 | {1,6}, // 101 | ||
478 | {1,8}, // 110 | ||
479 | {1,8} // 111 | ||
480 | }; | ||
481 | |||
482 | static void st40_specific_time_init(unsigned int module_clock, unsigned short frqcr) | ||
483 | { | 152 | { |
484 | unsigned int cpu_clock, master_clock, bus_clock, memory_clock; | 153 | int ret = sysdev_class_register(&timer_sysclass); |
485 | struct frqcr_data *d; | 154 | if (ret != 0) |
486 | int a; | 155 | return ret; |
487 | unsigned long memclkcr; | ||
488 | struct memclk_data *e; | ||
489 | 156 | ||
490 | for (a = 0; a < ARRAY_SIZE(st40_frqcr_table); a++) { | 157 | sys_timer->dev.cls = &timer_sysclass; |
491 | d = &st40_frqcr_table[a]; | 158 | return sysdev_register(&sys_timer->dev); |
492 | 159 | } | |
493 | if (d->frqcr == (frqcr & 0x1ff)) | ||
494 | break; | ||
495 | } | ||
496 | 160 | ||
497 | if (a == ARRAY_SIZE(st40_frqcr_table)) { | 161 | device_initcall(timer_init_sysfs); |
498 | d = st40_frqcr_table; | ||
499 | 162 | ||
500 | printk("ERROR: Unrecognised FRQCR value (0x%x), " | 163 | void (*board_time_init)(void); |
501 | "using default multipliers\n", frqcr); | ||
502 | } | ||
503 | |||
504 | memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR); | ||
505 | e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK]; | ||
506 | |||
507 | printk(KERN_INFO "Clock multipliers: CPU: %d/%d Bus: %d/%d " | ||
508 | "Mem: %d/%d Periph: %d/%d\n", | ||
509 | d->factor[0].multiplier, d->factor[0].divisor, | ||
510 | d->factor[1].multiplier, d->factor[1].divisor, | ||
511 | e->multiplier, e->divisor, | ||
512 | d->factor[2].multiplier, d->factor[2].divisor); | ||
513 | |||
514 | master_clock = module_clock * d->factor[2].divisor | ||
515 | / d->factor[2].multiplier; | ||
516 | bus_clock = master_clock * d->factor[1].multiplier | ||
517 | / d->factor[1].divisor; | ||
518 | memory_clock = master_clock * e->multiplier | ||
519 | / e->divisor; | ||
520 | cpu_clock = master_clock * d->factor[0].multiplier | ||
521 | / d->factor[0].divisor; | ||
522 | |||
523 | current_cpu_data.cpu_clock = cpu_clock; | ||
524 | current_cpu_data.master_clock = master_clock; | ||
525 | current_cpu_data.bus_clock = bus_clock; | ||
526 | current_cpu_data.memory_clock = memory_clock; | ||
527 | current_cpu_data.module_clock = module_clock; | ||
528 | } | ||
529 | #endif | ||
530 | 164 | ||
531 | void __init time_init(void) | 165 | void __init time_init(void) |
532 | { | 166 | { |
533 | unsigned int timer_freq = 0; | ||
534 | unsigned int ifc, pfc, bfc; | ||
535 | unsigned long interval; | ||
536 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
537 | unsigned long pvr; | ||
538 | unsigned short frqcr; | ||
539 | #endif | ||
540 | |||
541 | if (board_time_init) | 167 | if (board_time_init) |
542 | board_time_init(); | 168 | board_time_init(); |
543 | 169 | ||
544 | /* | 170 | clk_init(); |
545 | * If we don't have an RTC (such as with the SH7300), don't attempt to | ||
546 | * probe the timer frequency. Rely on an either hardcoded peripheral | ||
547 | * clock value, or on the sh_pclk command line option. Note that we | ||
548 | * still need to have CONFIG_SH_PCLK_FREQ set in order for things like | ||
549 | * CLOCK_TICK_RATE to be sane. | ||
550 | */ | ||
551 | current_cpu_data.module_clock = sh_pclk_freq; | ||
552 | |||
553 | #ifdef CONFIG_SH_PCLK_CALC | ||
554 | /* XXX: Switch this over to a more generic test. */ | ||
555 | { | ||
556 | unsigned int freq; | ||
557 | |||
558 | /* | ||
559 | * If we've specified a peripheral clock frequency, and we have | ||
560 | * an RTC, compare it against the autodetected value. Complain | ||
561 | * if there's a mismatch. | ||
562 | */ | ||
563 | timer_freq = get_timer_frequency(); | ||
564 | freq = timer_freq * 4; | ||
565 | |||
566 | if (sh_pclk_freq && (sh_pclk_freq/100*99 > freq || sh_pclk_freq/100*101 < freq)) { | ||
567 | printk(KERN_NOTICE "Calculated peripheral clock value " | ||
568 | "%d differs from sh_pclk value %d, fixing..\n", | ||
569 | freq, sh_pclk_freq); | ||
570 | current_cpu_data.module_clock = freq; | ||
571 | } | ||
572 | } | ||
573 | #endif | ||
574 | |||
575 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
576 | /* XXX: Update ST40 code to use board_time_init() */ | ||
577 | pvr = ctrl_inl(CCN_PVR); | ||
578 | frqcr = ctrl_inw(FRQCR); | ||
579 | printk("time.c ST40 Probe: PVR %08lx, FRQCR %04hx\n", pvr, frqcr); | ||
580 | |||
581 | if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) | ||
582 | st40_specific_time_init(current_cpu_data.module_clock, frqcr); | ||
583 | else | ||
584 | #endif | ||
585 | get_current_frequency_divisors(&ifc, &bfc, &pfc); | ||
586 | 171 | ||
587 | if (rtc_get_time) { | 172 | if (rtc_get_time) { |
588 | rtc_get_time(&xtime); | 173 | rtc_get_time(&xtime); |
@@ -594,51 +179,12 @@ void __init time_init(void) | |||
594 | set_normalized_timespec(&wall_to_monotonic, | 179 | set_normalized_timespec(&wall_to_monotonic, |
595 | -xtime.tv_sec, -xtime.tv_nsec); | 180 | -xtime.tv_sec, -xtime.tv_nsec); |
596 | 181 | ||
597 | if (board_timer_setup) { | ||
598 | board_timer_setup(&irq0); | ||
599 | } else { | ||
600 | setup_irq(TIMER_IRQ, &irq0); | ||
601 | } | ||
602 | |||
603 | /* | 182 | /* |
604 | * for ST40 chips the current_cpu_data should already be set | 183 | * Find the timer to use as the system timer, it will be |
605 | * so not having valid pfc/bfc/ifc shouldn't be a problem | 184 | * initialized for us. |
606 | */ | 185 | */ |
607 | if (!current_cpu_data.master_clock) | 186 | sys_timer = get_sys_timer(); |
608 | current_cpu_data.master_clock = current_cpu_data.module_clock * pfc; | 187 | printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); |
609 | if (!current_cpu_data.bus_clock) | ||
610 | current_cpu_data.bus_clock = current_cpu_data.master_clock / bfc; | ||
611 | if (!current_cpu_data.cpu_clock) | ||
612 | current_cpu_data.cpu_clock = current_cpu_data.master_clock / ifc; | ||
613 | |||
614 | printk("CPU clock: %d.%02dMHz\n", | ||
615 | (current_cpu_data.cpu_clock / 1000000), | ||
616 | (current_cpu_data.cpu_clock % 1000000)/10000); | ||
617 | printk("Bus clock: %d.%02dMHz\n", | ||
618 | (current_cpu_data.bus_clock / 1000000), | ||
619 | (current_cpu_data.bus_clock % 1000000)/10000); | ||
620 | #ifdef CONFIG_CPU_SUBTYPE_ST40STB1 | ||
621 | printk("Memory clock: %d.%02dMHz\n", | ||
622 | (current_cpu_data.memory_clock / 1000000), | ||
623 | (current_cpu_data.memory_clock % 1000000)/10000); | ||
624 | #endif | ||
625 | printk("Module clock: %d.%02dMHz\n", | ||
626 | (current_cpu_data.module_clock / 1000000), | ||
627 | (current_cpu_data.module_clock % 1000000)/10000); | ||
628 | |||
629 | interval = (current_cpu_data.module_clock/4 + HZ/2) / HZ; | ||
630 | |||
631 | printk("Interval = %ld\n", interval); | ||
632 | |||
633 | /* Start TMU0 */ | ||
634 | ctrl_outb(0, TMU_TSTR); | ||
635 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
636 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
637 | #endif | ||
638 | ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); | ||
639 | ctrl_outl(interval, TMU0_TCOR); | ||
640 | ctrl_outl(interval, TMU0_TCNT); | ||
641 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
642 | 188 | ||
643 | #if defined(CONFIG_SH_KGDB) | 189 | #if defined(CONFIG_SH_KGDB) |
644 | /* | 190 | /* |
diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile new file mode 100644 index 000000000000..151a6a304cec --- /dev/null +++ b/arch/sh/kernel/timers/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the various Linux/SuperH timers | ||
3 | # | ||
4 | |||
5 | obj-y := timer.o | ||
6 | |||
7 | obj-$(CONFIG_SH_TMU) += timer-tmu.o | ||
8 | |||
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c new file mode 100644 index 000000000000..96a64cb13106 --- /dev/null +++ b/arch/sh/kernel/timers/timer-tmu.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/timers/timer-tmu.c - TMU Timer Support | ||
3 | * | ||
4 | * Copyright (C) 2005 Paul Mundt | ||
5 | * | ||
6 | * TMU handling code hacked out of arch/sh/kernel/time.c | ||
7 | * | ||
8 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
9 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
10 | * Copyright (C) 2002, 2003, 2004 Paul Mundt | ||
11 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | ||
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 <linux/kernel.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/seqlock.h> | ||
22 | #include <asm/timer.h> | ||
23 | #include <asm/rtc.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/irq.h> | ||
26 | #include <asm/clock.h> | ||
27 | |||
28 | #define TMU_TOCR_INIT 0x00 | ||
29 | #define TMU0_TCR_INIT 0x0020 | ||
30 | #define TMU_TSTR_INIT 1 | ||
31 | |||
32 | #define TMU0_TCR_CALIB 0x0000 | ||
33 | |||
34 | static DEFINE_SPINLOCK(tmu0_lock); | ||
35 | |||
36 | static unsigned long tmu_timer_get_offset(void) | ||
37 | { | ||
38 | int count; | ||
39 | unsigned long flags; | ||
40 | |||
41 | static int count_p = 0x7fffffff; /* for the first call after boot */ | ||
42 | static unsigned long jiffies_p = 0; | ||
43 | |||
44 | /* | ||
45 | * cache volatile jiffies temporarily; we have IRQs turned off. | ||
46 | */ | ||
47 | unsigned long jiffies_t; | ||
48 | |||
49 | spin_lock_irqsave(&tmu0_lock, flags); | ||
50 | /* timer count may underflow right here */ | ||
51 | count = ctrl_inl(TMU0_TCNT); /* read the latched count */ | ||
52 | |||
53 | jiffies_t = jiffies; | ||
54 | |||
55 | /* | ||
56 | * avoiding timer inconsistencies (they are rare, but they happen)... | ||
57 | * there is one kind of problem that must be avoided here: | ||
58 | * 1. the timer counter underflows | ||
59 | */ | ||
60 | |||
61 | if (jiffies_t == jiffies_p) { | ||
62 | if (count > count_p) { | ||
63 | /* the nutcase */ | ||
64 | if (ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */ | ||
65 | count -= LATCH; | ||
66 | } else { | ||
67 | printk("%s (): hardware timer problem?\n", | ||
68 | __FUNCTION__); | ||
69 | } | ||
70 | } | ||
71 | } else | ||
72 | jiffies_p = jiffies_t; | ||
73 | |||
74 | count_p = count; | ||
75 | spin_unlock_irqrestore(&tmu0_lock, flags); | ||
76 | |||
77 | count = ((LATCH-1) - count) * TICK_SIZE; | ||
78 | count = (count + LATCH/2) / LATCH; | ||
79 | |||
80 | return count; | ||
81 | } | ||
82 | |||
83 | static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id, | ||
84 | struct pt_regs *regs) | ||
85 | { | ||
86 | unsigned long timer_status; | ||
87 | |||
88 | /* Clear UNF bit */ | ||
89 | timer_status = ctrl_inw(TMU0_TCR); | ||
90 | timer_status &= ~0x100; | ||
91 | ctrl_outw(timer_status, TMU0_TCR); | ||
92 | |||
93 | /* | ||
94 | * Here we are in the timer irq handler. We just have irqs locally | ||
95 | * disabled but we don't know if the timer_bh is running on the other | ||
96 | * CPU. We need to avoid to SMP race with it. NOTE: we don' t need | ||
97 | * the irq version of write_lock because as just said we have irq | ||
98 | * locally disabled. -arca | ||
99 | */ | ||
100 | write_seqlock(&xtime_lock); | ||
101 | handle_timer_tick(regs); | ||
102 | write_sequnlock(&xtime_lock); | ||
103 | |||
104 | return IRQ_HANDLED; | ||
105 | } | ||
106 | |||
107 | static struct irqaction tmu_irq = { | ||
108 | .name = "timer", | ||
109 | .handler = tmu_timer_interrupt, | ||
110 | .flags = SA_INTERRUPT, | ||
111 | .mask = CPU_MASK_NONE, | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * Hah! We'll see if this works (switching from usecs to nsecs). | ||
116 | */ | ||
117 | static unsigned long tmu_timer_get_frequency(void) | ||
118 | { | ||
119 | u32 freq; | ||
120 | struct timespec ts1, ts2; | ||
121 | unsigned long diff_nsec; | ||
122 | unsigned long factor; | ||
123 | |||
124 | /* Setup the timer: We don't want to generate interrupts, just | ||
125 | * have it count down at its natural rate. | ||
126 | */ | ||
127 | ctrl_outb(0, TMU_TSTR); | ||
128 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
129 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
130 | #endif | ||
131 | ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); | ||
132 | ctrl_outl(0xffffffff, TMU0_TCOR); | ||
133 | ctrl_outl(0xffffffff, TMU0_TCNT); | ||
134 | |||
135 | rtc_get_time(&ts2); | ||
136 | |||
137 | do { | ||
138 | rtc_get_time(&ts1); | ||
139 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
140 | |||
141 | /* actually start the timer */ | ||
142 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
143 | |||
144 | do { | ||
145 | rtc_get_time(&ts2); | ||
146 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
147 | |||
148 | freq = 0xffffffff - ctrl_inl(TMU0_TCNT); | ||
149 | if (ts2.tv_nsec < ts1.tv_nsec) { | ||
150 | ts2.tv_nsec += 1000000000; | ||
151 | ts2.tv_sec--; | ||
152 | } | ||
153 | |||
154 | diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); | ||
155 | |||
156 | /* this should work well if the RTC has a precision of n Hz, where | ||
157 | * n is an integer. I don't think we have to worry about the other | ||
158 | * cases. */ | ||
159 | factor = (1000000000 + diff_nsec/2) / diff_nsec; | ||
160 | |||
161 | if (factor * diff_nsec > 1100000000 || | ||
162 | factor * diff_nsec < 900000000) | ||
163 | panic("weird RTC (diff_nsec %ld)", diff_nsec); | ||
164 | |||
165 | return freq * factor; | ||
166 | } | ||
167 | |||
168 | static void tmu_clk_init(struct clk *clk) | ||
169 | { | ||
170 | u8 divisor = TMU0_TCR_INIT & 0x7; | ||
171 | ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); | ||
172 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); | ||
173 | } | ||
174 | |||
175 | static void tmu_clk_recalc(struct clk *clk) | ||
176 | { | ||
177 | u8 divisor = ctrl_inw(TMU0_TCR) & 0x7; | ||
178 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); | ||
179 | } | ||
180 | |||
181 | static struct clk_ops tmu_clk_ops = { | ||
182 | .init = tmu_clk_init, | ||
183 | .recalc = tmu_clk_recalc, | ||
184 | }; | ||
185 | |||
186 | static struct clk tmu0_clk = { | ||
187 | .name = "tmu0_clk", | ||
188 | .ops = &tmu_clk_ops, | ||
189 | }; | ||
190 | |||
191 | static int tmu_timer_init(void) | ||
192 | { | ||
193 | unsigned long interval; | ||
194 | |||
195 | setup_irq(TIMER_IRQ, &tmu_irq); | ||
196 | |||
197 | tmu0_clk.parent = clk_get("module_clk"); | ||
198 | |||
199 | /* Start TMU0 */ | ||
200 | ctrl_outb(0, TMU_TSTR); | ||
201 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
202 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
203 | #endif | ||
204 | |||
205 | clk_register(&tmu0_clk); | ||
206 | clk_enable(&tmu0_clk); | ||
207 | |||
208 | interval = (clk_get_rate(&tmu0_clk) + HZ / 2) / HZ; | ||
209 | printk(KERN_INFO "Interval = %ld\n", interval); | ||
210 | |||
211 | ctrl_outl(interval, TMU0_TCOR); | ||
212 | ctrl_outl(interval, TMU0_TCNT); | ||
213 | |||
214 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | struct sys_timer_ops tmu_timer_ops = { | ||
220 | .init = tmu_timer_init, | ||
221 | .get_frequency = tmu_timer_get_frequency, | ||
222 | .get_offset = tmu_timer_get_offset, | ||
223 | }; | ||
224 | |||
225 | struct sys_timer tmu_timer = { | ||
226 | .name = "tmu", | ||
227 | .ops = &tmu_timer_ops, | ||
228 | }; | ||
229 | |||
diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c new file mode 100644 index 000000000000..dc1f631053a8 --- /dev/null +++ b/arch/sh/kernel/timers/timer.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/timers/timer.c - Common timer code | ||
3 | * | ||
4 | * Copyright (C) 2005 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/init.h> | ||
12 | #include <linux/timer.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <asm/timer.h> | ||
15 | |||
16 | static struct sys_timer *sys_timers[] __initdata = { | ||
17 | #ifdef CONFIG_SH_TMU | ||
18 | &tmu_timer, | ||
19 | #endif | ||
20 | NULL, | ||
21 | }; | ||
22 | |||
23 | static char timer_override[10] __initdata; | ||
24 | static int __init timer_setup(char *str) | ||
25 | { | ||
26 | if (str) | ||
27 | strlcpy(timer_override, str, sizeof(timer_override)); | ||
28 | return 1; | ||
29 | } | ||
30 | __setup("timer=", timer_setup); | ||
31 | |||
32 | struct sys_timer *get_sys_timer(void) | ||
33 | { | ||
34 | int i; | ||
35 | |||
36 | for (i = 0; i < ARRAY_SIZE(sys_timers); i++) { | ||
37 | struct sys_timer *t = sys_timers[i]; | ||
38 | |||
39 | if (unlikely(!t)) | ||
40 | break; | ||
41 | if (unlikely(timer_override[0])) | ||
42 | if ((strcmp(timer_override, t->name) != 0)) | ||
43 | continue; | ||
44 | if (likely(t->ops->init() == 0)) | ||
45 | return t; | ||
46 | } | ||
47 | |||
48 | return NULL; | ||
49 | } | ||
50 | |||
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig new file mode 100644 index 000000000000..fb586b1cf8bb --- /dev/null +++ b/arch/sh/mm/Kconfig | |||
@@ -0,0 +1,233 @@ | |||
1 | menu "Processor selection" | ||
2 | |||
3 | # | ||
4 | # Processor families | ||
5 | # | ||
6 | config CPU_SH2 | ||
7 | bool | ||
8 | select SH_WRITETHROUGH | ||
9 | |||
10 | config CPU_SH3 | ||
11 | bool | ||
12 | select CPU_HAS_INTEVT | ||
13 | select CPU_HAS_SR_RB | ||
14 | |||
15 | config CPU_SH4 | ||
16 | bool | ||
17 | select CPU_HAS_INTEVT | ||
18 | select CPU_HAS_SR_RB | ||
19 | |||
20 | config CPU_SH4A | ||
21 | bool | ||
22 | select CPU_SH4 | ||
23 | select CPU_HAS_INTC2_IRQ | ||
24 | |||
25 | config CPU_SUBTYPE_ST40 | ||
26 | bool | ||
27 | select CPU_SH4 | ||
28 | select CPU_HAS_INTC2_IRQ | ||
29 | |||
30 | # | ||
31 | # Processor subtypes | ||
32 | # | ||
33 | |||
34 | comment "SH-2 Processor Support" | ||
35 | |||
36 | config CPU_SUBTYPE_SH7604 | ||
37 | bool "Support SH7604 processor" | ||
38 | select CPU_SH2 | ||
39 | |||
40 | comment "SH-3 Processor Support" | ||
41 | |||
42 | config CPU_SUBTYPE_SH7300 | ||
43 | bool "Support SH7300 processor" | ||
44 | select CPU_SH3 | ||
45 | |||
46 | config CPU_SUBTYPE_SH7705 | ||
47 | bool "Support SH7705 processor" | ||
48 | select CPU_SH3 | ||
49 | select CPU_HAS_PINT_IRQ | ||
50 | |||
51 | config CPU_SUBTYPE_SH7707 | ||
52 | bool "Support SH7707 processor" | ||
53 | select CPU_SH3 | ||
54 | select CPU_HAS_PINT_IRQ | ||
55 | help | ||
56 | Select SH7707 if you have a 60 Mhz SH-3 HD6417707 CPU. | ||
57 | |||
58 | config CPU_SUBTYPE_SH7708 | ||
59 | bool "Support SH7708 processor" | ||
60 | select CPU_SH3 | ||
61 | help | ||
62 | Select SH7708 if you have a 60 Mhz SH-3 HD6417708S or | ||
63 | if you have a 100 Mhz SH-3 HD6417708R CPU. | ||
64 | |||
65 | config CPU_SUBTYPE_SH7709 | ||
66 | bool "Support SH7709 processor" | ||
67 | select CPU_SH3 | ||
68 | select CPU_HAS_PINT_IRQ | ||
69 | help | ||
70 | Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. | ||
71 | |||
72 | comment "SH-4 Processor Support" | ||
73 | |||
74 | config CPU_SUBTYPE_SH7750 | ||
75 | bool "Support SH7750 processor" | ||
76 | select CPU_SH4 | ||
77 | help | ||
78 | Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. | ||
79 | |||
80 | config CPU_SUBTYPE_SH7091 | ||
81 | bool "Support SH7091 processor" | ||
82 | select CPU_SH4 | ||
83 | select CPU_SUBTYPE_SH7750 | ||
84 | help | ||
85 | Select SH7091 if you have an SH-4 based Sega device (such as | ||
86 | the Dreamcast, Naomi, and Naomi 2). | ||
87 | |||
88 | config CPU_SUBTYPE_SH7750R | ||
89 | bool "Support SH7750R processor" | ||
90 | select CPU_SH4 | ||
91 | select CPU_SUBTYPE_SH7750 | ||
92 | |||
93 | config CPU_SUBTYPE_SH7750S | ||
94 | bool "Support SH7750S processor" | ||
95 | select CPU_SH4 | ||
96 | select CPU_SUBTYPE_SH7750 | ||
97 | |||
98 | config CPU_SUBTYPE_SH7751 | ||
99 | bool "Support SH7751 processor" | ||
100 | select CPU_SH4 | ||
101 | help | ||
102 | Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, | ||
103 | or if you have a HD6417751R CPU. | ||
104 | |||
105 | config CPU_SUBTYPE_SH7751R | ||
106 | bool "Support SH7751R processor" | ||
107 | select CPU_SH4 | ||
108 | select CPU_SUBTYPE_SH7751 | ||
109 | |||
110 | config CPU_SUBTYPE_SH7760 | ||
111 | bool "Support SH7760 processor" | ||
112 | select CPU_SH4 | ||
113 | select CPU_HAS_INTC2_IRQ | ||
114 | |||
115 | config CPU_SUBTYPE_SH4_202 | ||
116 | bool "Support SH4-202 processor" | ||
117 | select CPU_SH4 | ||
118 | |||
119 | comment "ST40 Processor Support" | ||
120 | |||
121 | config CPU_SUBTYPE_ST40STB1 | ||
122 | bool "Support ST40STB1/ST40RA processors" | ||
123 | select CPU_SUBTYPE_ST40 | ||
124 | help | ||
125 | Select ST40STB1 if you have a ST40RA CPU. | ||
126 | This was previously called the ST40STB1, hence the option name. | ||
127 | |||
128 | config CPU_SUBTYPE_ST40GX1 | ||
129 | bool "Support ST40GX1 processor" | ||
130 | select CPU_SUBTYPE_ST40 | ||
131 | help | ||
132 | Select ST40GX1 if you have a ST40GX1 CPU. | ||
133 | |||
134 | comment "SH-4A Processor Support" | ||
135 | |||
136 | config CPU_SUBTYPE_SH73180 | ||
137 | bool "Support SH73180 processor" | ||
138 | select CPU_SH4A | ||
139 | |||
140 | config CPU_SUBTYPE_SH7770 | ||
141 | bool "Support SH7770 processor" | ||
142 | select CPU_SH4A | ||
143 | |||
144 | config CPU_SUBTYPE_SH7780 | ||
145 | bool "Support SH7780 processor" | ||
146 | select CPU_SH4A | ||
147 | |||
148 | endmenu | ||
149 | |||
150 | menu "Memory management options" | ||
151 | |||
152 | config MMU | ||
153 | bool "Support for memory management hardware" | ||
154 | depends on !CPU_SH2 | ||
155 | default y | ||
156 | help | ||
157 | Some SH processors (such as SH-2/SH-2A) lack an MMU. In order to | ||
158 | boot on these systems, this option must not be set. | ||
159 | |||
160 | On other systems (such as the SH-3 and 4) where an MMU exists, | ||
161 | turning this off will boot the kernel on these machines with the | ||
162 | MMU implicitly switched off. | ||
163 | |||
164 | config 32BIT | ||
165 | bool "Support 32-bit physical addressing through PMB" | ||
166 | depends on CPU_SH4A | ||
167 | default y | ||
168 | help | ||
169 | If you say Y here, physical addressing will be extended to | ||
170 | 32-bits through the SH-4A PMB. If this is not set, legacy | ||
171 | 29-bit physical addressing will be used. | ||
172 | |||
173 | choice | ||
174 | prompt "HugeTLB page size" | ||
175 | depends on HUGETLB_PAGE && CPU_SH4 && MMU | ||
176 | default HUGETLB_PAGE_SIZE_64K | ||
177 | |||
178 | config HUGETLB_PAGE_SIZE_64K | ||
179 | bool "64K" | ||
180 | |||
181 | config HUGETLB_PAGE_SIZE_1MB | ||
182 | bool "1MB" | ||
183 | |||
184 | endchoice | ||
185 | |||
186 | source "mm/Kconfig" | ||
187 | |||
188 | endmenu | ||
189 | |||
190 | menu "Cache configuration" | ||
191 | |||
192 | config SH7705_CACHE_32KB | ||
193 | bool "Enable 32KB cache size for SH7705" | ||
194 | depends on CPU_SUBTYPE_SH7705 | ||
195 | default y | ||
196 | |||
197 | config SH_DIRECT_MAPPED | ||
198 | bool "Use direct-mapped caching" | ||
199 | default n | ||
200 | help | ||
201 | Selecting this option will configure the caches to be direct-mapped, | ||
202 | even if the cache supports a 2 or 4-way mode. This is useful primarily | ||
203 | for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R, | ||
204 | SH4-202, SH4-501, etc.) | ||
205 | |||
206 | Turn this option off for platforms that do not have a direct-mapped | ||
207 | cache, and you have no need to run the caches in such a configuration. | ||
208 | |||
209 | config SH_WRITETHROUGH | ||
210 | bool "Use write-through caching" | ||
211 | default y if CPU_SH2 | ||
212 | help | ||
213 | Selecting this option will configure the caches in write-through | ||
214 | mode, as opposed to the default write-back configuration. | ||
215 | |||
216 | Since there's sill some aliasing issues on SH-4, this option will | ||
217 | unfortunately still require the majority of flushing functions to | ||
218 | be implemented to deal with aliasing. | ||
219 | |||
220 | If unsure, say N. | ||
221 | |||
222 | config SH_OCRAM | ||
223 | bool "Operand Cache RAM (OCRAM) support" | ||
224 | help | ||
225 | Selecting this option will automatically tear down the number of | ||
226 | sets in the dcache by half, which in turn exposes a memory range. | ||
227 | |||
228 | The addresses for the OC RAM base will vary according to the | ||
229 | processor version. Consult vendor documentation for specifics. | ||
230 | |||
231 | If unsure, say N. | ||
232 | |||
233 | endmenu | ||
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index e794e27a72f1..96fa4a999e2a 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c | |||
@@ -6,13 +6,19 @@ | |||
6 | * 640k-1MB IO memory area on PC's | 6 | * 640k-1MB IO memory area on PC's |
7 | * | 7 | * |
8 | * (C) Copyright 1995 1996 Linus Torvalds | 8 | * (C) Copyright 1995 1996 Linus Torvalds |
9 | * (C) Copyright 2005, 2006 Paul Mundt | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General | ||
12 | * Public License. See the file "COPYING" in the main directory of this | ||
13 | * archive for more details. | ||
9 | */ | 14 | */ |
10 | |||
11 | #include <linux/vmalloc.h> | 15 | #include <linux/vmalloc.h> |
16 | #include <linux/module.h> | ||
12 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
13 | #include <asm/io.h> | 18 | #include <asm/io.h> |
14 | #include <asm/page.h> | 19 | #include <asm/page.h> |
15 | #include <asm/pgalloc.h> | 20 | #include <asm/pgalloc.h> |
21 | #include <asm/addrspace.h> | ||
16 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
17 | #include <asm/tlbflush.h> | 23 | #include <asm/tlbflush.h> |
18 | 24 | ||
@@ -80,9 +86,15 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
80 | if (address >= end) | 86 | if (address >= end) |
81 | BUG(); | 87 | BUG(); |
82 | do { | 88 | do { |
89 | pud_t *pud; | ||
83 | pmd_t *pmd; | 90 | pmd_t *pmd; |
84 | pmd = pmd_alloc(&init_mm, dir, address); | 91 | |
85 | error = -ENOMEM; | 92 | error = -ENOMEM; |
93 | |||
94 | pud = pud_alloc(&init_mm, dir, address); | ||
95 | if (!pud) | ||
96 | break; | ||
97 | pmd = pmd_alloc(&init_mm, pud, address); | ||
86 | if (!pmd) | 98 | if (!pmd) |
87 | break; | 99 | break; |
88 | if (remap_area_pmd(pmd, address, end - address, | 100 | if (remap_area_pmd(pmd, address, end - address, |
@@ -97,10 +109,6 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
97 | } | 109 | } |
98 | 110 | ||
99 | /* | 111 | /* |
100 | * Generic mapping function (not visible outside): | ||
101 | */ | ||
102 | |||
103 | /* | ||
104 | * Remap an arbitrary physical address space into the kernel virtual | 112 | * Remap an arbitrary physical address space into the kernel virtual |
105 | * address space. Needed when the kernel wants to access high addresses | 113 | * address space. Needed when the kernel wants to access high addresses |
106 | * directly. | 114 | * directly. |
@@ -109,11 +117,11 @@ int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
109 | * have to convert them into an offset in a page-aligned mapping, but the | 117 | * have to convert them into an offset in a page-aligned mapping, but the |
110 | * caller shouldn't need to know that small detail. | 118 | * caller shouldn't need to know that small detail. |
111 | */ | 119 | */ |
112 | void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) | 120 | void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, |
121 | unsigned long flags) | ||
113 | { | 122 | { |
114 | void * addr; | ||
115 | struct vm_struct * area; | 123 | struct vm_struct * area; |
116 | unsigned long offset, last_addr; | 124 | unsigned long offset, last_addr, addr, orig_addr; |
117 | 125 | ||
118 | /* Don't allow wraparound or zero size */ | 126 | /* Don't allow wraparound or zero size */ |
119 | last_addr = phys_addr + size - 1; | 127 | last_addr = phys_addr + size - 1; |
@@ -124,7 +132,7 @@ void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long fla | |||
124 | * Don't remap the low PCI/ISA area, it's always mapped.. | 132 | * Don't remap the low PCI/ISA area, it's always mapped.. |
125 | */ | 133 | */ |
126 | if (phys_addr >= 0xA0000 && last_addr < 0x100000) | 134 | if (phys_addr >= 0xA0000 && last_addr < 0x100000) |
127 | return phys_to_virt(phys_addr); | 135 | return (void __iomem *)phys_to_virt(phys_addr); |
128 | 136 | ||
129 | /* | 137 | /* |
130 | * Don't allow anybody to remap normal RAM that we're using.. | 138 | * Don't allow anybody to remap normal RAM that we're using.. |
@@ -146,16 +154,71 @@ void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long fla | |||
146 | if (!area) | 154 | if (!area) |
147 | return NULL; | 155 | return NULL; |
148 | area->phys_addr = phys_addr; | 156 | area->phys_addr = phys_addr; |
149 | addr = area->addr; | 157 | orig_addr = addr = (unsigned long)area->addr; |
150 | if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { | 158 | |
151 | vunmap(addr); | 159 | #ifdef CONFIG_32BIT |
152 | return NULL; | 160 | /* |
161 | * First try to remap through the PMB once a valid VMA has been | ||
162 | * established. Smaller allocations (or the rest of the size | ||
163 | * remaining after a PMB mapping due to the size not being | ||
164 | * perfectly aligned on a PMB size boundary) are then mapped | ||
165 | * through the UTLB using conventional page tables. | ||
166 | * | ||
167 | * PMB entries are all pre-faulted. | ||
168 | */ | ||
169 | if (unlikely(size >= 0x1000000)) { | ||
170 | unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); | ||
171 | |||
172 | if (likely(mapped)) { | ||
173 | addr += mapped; | ||
174 | phys_addr += mapped; | ||
175 | size -= mapped; | ||
176 | } | ||
153 | } | 177 | } |
154 | return (void *) (offset + (char *)addr); | 178 | #endif |
179 | |||
180 | if (likely(size)) | ||
181 | if (remap_area_pages(addr, phys_addr, size, flags)) { | ||
182 | vunmap((void *)orig_addr); | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
186 | return (void __iomem *)(offset + (char *)orig_addr); | ||
155 | } | 187 | } |
188 | EXPORT_SYMBOL(__ioremap); | ||
156 | 189 | ||
157 | void p3_iounmap(void *addr) | 190 | void __iounmap(void __iomem *addr) |
158 | { | 191 | { |
159 | if (addr > high_memory) | 192 | unsigned long vaddr = (unsigned long __force)addr; |
160 | vfree((void *)(PAGE_MASK & (unsigned long)addr)); | 193 | struct vm_struct *p; |
194 | |||
195 | if (PXSEG(vaddr) < P3SEG) | ||
196 | return; | ||
197 | |||
198 | #ifdef CONFIG_32BIT | ||
199 | /* | ||
200 | * Purge any PMB entries that may have been established for this | ||
201 | * mapping, then proceed with conventional VMA teardown. | ||
202 | * | ||
203 | * XXX: Note that due to the way that remove_vm_area() does | ||
204 | * matching of the resultant VMA, we aren't able to fast-forward | ||
205 | * the address past the PMB space until the end of the VMA where | ||
206 | * the page tables reside. As such, unmap_vm_area() will be | ||
207 | * forced to linearly scan over the area until it finds the page | ||
208 | * tables where PTEs that need to be unmapped actually reside, | ||
209 | * which is far from optimal. Perhaps we need to use a separate | ||
210 | * VMA for the PMB mappings? | ||
211 | * -- PFM. | ||
212 | */ | ||
213 | pmb_unmap(vaddr); | ||
214 | #endif | ||
215 | |||
216 | p = remove_vm_area((void *)(vaddr & PAGE_MASK)); | ||
217 | if (!p) { | ||
218 | printk(KERN_ERR "%s: bad address %p\n", __FUNCTION__, addr); | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | kfree(p); | ||
161 | } | 223 | } |
224 | EXPORT_SYMBOL(__iounmap); | ||
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 0693fbd1f956..182fe9092577 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types | |||
@@ -10,10 +10,7 @@ SE SH_SOLUTION_ENGINE | |||
10 | 7300SE SH_7300_SOLUTION_ENGINE | 10 | 7300SE SH_7300_SOLUTION_ENGINE |
11 | 73180SE SH_73180_SOLUTION_ENGINE | 11 | 73180SE SH_73180_SOLUTION_ENGINE |
12 | 7751SYSTEMH SH_7751_SYSTEMH | 12 | 7751SYSTEMH SH_7751_SYSTEMH |
13 | HP600 SH_HP600 | 13 | HP6XX SH_HP6XX |
14 | HP620 SH_HP620 | ||
15 | HP680 SH_HP680 | ||
16 | HP690 SH_HP690 | ||
17 | HD64461 HD64461 | 14 | HD64461 HD64461 |
18 | HD64465 HD64465 | 15 | HD64465 HD64465 |
19 | SH2000 SH_SH2000 | 16 | SH2000 SH_SH2000 |