diff options
Diffstat (limited to 'arch/m68k/q40')
-rw-r--r-- | arch/m68k/q40/config.c | 265 |
1 files changed, 134 insertions, 131 deletions
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 92f873cc7060..4c5b9e4e98bc 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c | |||
@@ -35,35 +35,35 @@ | |||
35 | #include <asm/machdep.h> | 35 | #include <asm/machdep.h> |
36 | #include <asm/q40_master.h> | 36 | #include <asm/q40_master.h> |
37 | 37 | ||
38 | extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); | 38 | extern irqreturn_t q40_process_int(int level, struct pt_regs *regs); |
39 | extern void q40_init_IRQ (void); | 39 | extern void q40_init_IRQ(void); |
40 | static void q40_get_model(char *model); | 40 | static void q40_get_model(char *model); |
41 | static int q40_get_hardware_list(char *buffer); | 41 | static int q40_get_hardware_list(char *buffer); |
42 | extern void q40_sched_init(irq_handler_t handler); | 42 | extern void q40_sched_init(irq_handler_t handler); |
43 | 43 | ||
44 | extern unsigned long q40_gettimeoffset (void); | 44 | extern unsigned long q40_gettimeoffset(void); |
45 | extern int q40_hwclk (int, struct rtc_time *); | 45 | extern int q40_hwclk(int, struct rtc_time *); |
46 | extern unsigned int q40_get_ss (void); | 46 | extern unsigned int q40_get_ss(void); |
47 | extern int q40_set_clock_mmss (unsigned long); | 47 | extern int q40_set_clock_mmss(unsigned long); |
48 | static int q40_get_rtc_pll(struct rtc_pll_info *pll); | 48 | static int q40_get_rtc_pll(struct rtc_pll_info *pll); |
49 | static int q40_set_rtc_pll(struct rtc_pll_info *pll); | 49 | static int q40_set_rtc_pll(struct rtc_pll_info *pll); |
50 | extern void q40_reset (void); | 50 | extern void q40_reset(void); |
51 | void q40_halt(void); | 51 | void q40_halt(void); |
52 | extern void q40_waitbut(void); | 52 | extern void q40_waitbut(void); |
53 | void q40_set_vectors (void); | 53 | void q40_set_vectors(void); |
54 | 54 | ||
55 | extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ ); | 55 | extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/); |
56 | 56 | ||
57 | extern char m68k_debug_device[]; | 57 | extern char m68k_debug_device[]; |
58 | static void q40_mem_console_write(struct console *co, const char *b, | 58 | static void q40_mem_console_write(struct console *co, const char *b, |
59 | unsigned int count); | 59 | unsigned int count); |
60 | 60 | ||
61 | extern int ql_ticks; | 61 | extern int ql_ticks; |
62 | 62 | ||
63 | static struct console q40_console_driver = { | 63 | static struct console q40_console_driver = { |
64 | .name = "debug", | 64 | .name = "debug", |
65 | .flags = CON_PRINTBUFFER, | 65 | .flags = CON_PRINTBUFFER, |
66 | .index = -1, | 66 | .index = -1, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | 69 | ||
@@ -74,150 +74,157 @@ static int _cpleft; | |||
74 | static void q40_mem_console_write(struct console *co, const char *s, | 74 | static void q40_mem_console_write(struct console *co, const char *s, |
75 | unsigned int count) | 75 | unsigned int count) |
76 | { | 76 | { |
77 | char *p=(char *)s; | 77 | const char *p = s; |
78 | 78 | ||
79 | if (count<_cpleft) | 79 | if (count < _cpleft) { |
80 | while (count-- >0){ | 80 | while (count-- > 0) { |
81 | *q40_mem_cptr=*p++; | 81 | *q40_mem_cptr = *p++; |
82 | q40_mem_cptr+=4; | 82 | q40_mem_cptr += 4; |
83 | _cpleft--; | 83 | _cpleft--; |
84 | } | 84 | } |
85 | } | ||
85 | } | 86 | } |
87 | |||
86 | #if 0 | 88 | #if 0 |
87 | void printq40(char *str) | 89 | void printq40(char *str) |
88 | { | 90 | { |
89 | int l=strlen(str); | 91 | int l = strlen(str); |
90 | char *p=q40_mem_cptr; | 92 | char *p = q40_mem_cptr; |
91 | 93 | ||
92 | while (l-- >0 && _cpleft-- >0) | 94 | while (l-- > 0 && _cpleft-- > 0) { |
93 | { | 95 | *p = *str++; |
94 | *p=*str++; | 96 | p += 4; |
95 | p+=4; | 97 | } |
96 | } | 98 | q40_mem_cptr = p; |
97 | q40_mem_cptr=p; | ||
98 | } | 99 | } |
99 | #endif | 100 | #endif |
100 | 101 | ||
101 | static int halted=0; | 102 | static int halted; |
102 | 103 | ||
103 | #ifdef CONFIG_HEARTBEAT | 104 | #ifdef CONFIG_HEARTBEAT |
104 | static void q40_heartbeat(int on) | 105 | static void q40_heartbeat(int on) |
105 | { | 106 | { |
106 | if (halted) return; | 107 | if (halted) |
108 | return; | ||
107 | 109 | ||
108 | if (on) | 110 | if (on) |
109 | Q40_LED_ON(); | 111 | Q40_LED_ON(); |
110 | else | 112 | else |
111 | Q40_LED_OFF(); | 113 | Q40_LED_OFF(); |
112 | } | 114 | } |
113 | #endif | 115 | #endif |
114 | 116 | ||
115 | void q40_reset(void) | 117 | void q40_reset(void) |
116 | { | 118 | { |
117 | halted=1; | 119 | halted = 1; |
118 | printk ("\n\n*******************************************\n" | 120 | printk("\n\n*******************************************\n" |
119 | "Called q40_reset : press the RESET button!! \n" | 121 | "Called q40_reset : press the RESET button!! \n" |
120 | "*******************************************\n"); | 122 | "*******************************************\n"); |
121 | Q40_LED_ON(); | 123 | Q40_LED_ON(); |
122 | while(1) ; | 124 | while (1) |
125 | ; | ||
123 | } | 126 | } |
124 | void q40_halt(void) | 127 | void q40_halt(void) |
125 | { | 128 | { |
126 | halted=1; | 129 | halted = 1; |
127 | printk ("\n\n*******************\n" | 130 | printk("\n\n*******************\n" |
128 | " Called q40_halt\n" | 131 | " Called q40_halt\n" |
129 | "*******************\n"); | 132 | "*******************\n"); |
130 | Q40_LED_ON(); | 133 | Q40_LED_ON(); |
131 | while(1) ; | 134 | while (1) |
135 | ; | ||
132 | } | 136 | } |
133 | 137 | ||
134 | static void q40_get_model(char *model) | 138 | static void q40_get_model(char *model) |
135 | { | 139 | { |
136 | sprintf(model, "Q40"); | 140 | sprintf(model, "Q40"); |
137 | } | 141 | } |
138 | 142 | ||
139 | /* No hardware options on Q40? */ | 143 | /* No hardware options on Q40? */ |
140 | 144 | ||
141 | static int q40_get_hardware_list(char *buffer) | 145 | static int q40_get_hardware_list(char *buffer) |
142 | { | 146 | { |
143 | *buffer = '\0'; | 147 | *buffer = '\0'; |
144 | return 0; | 148 | return 0; |
145 | } | 149 | } |
146 | 150 | ||
147 | static unsigned int serports[]={0x3f8,0x2f8,0x3e8,0x2e8,0}; | 151 | static unsigned int serports[] = |
152 | { | ||
153 | 0x3f8,0x2f8,0x3e8,0x2e8,0 | ||
154 | }; | ||
148 | void q40_disable_irqs(void) | 155 | void q40_disable_irqs(void) |
149 | { | 156 | { |
150 | unsigned i,j; | 157 | unsigned i, j; |
151 | 158 | ||
152 | j=0; | 159 | j = 0; |
153 | while((i=serports[j++])) outb(0,i+UART_IER); | 160 | while ((i = serports[j++])) |
154 | master_outb(0,EXT_ENABLE_REG); | 161 | outb(0, i + UART_IER); |
155 | master_outb(0,KEY_IRQ_ENABLE_REG); | 162 | master_outb(0, EXT_ENABLE_REG); |
163 | master_outb(0, KEY_IRQ_ENABLE_REG); | ||
156 | } | 164 | } |
157 | 165 | ||
158 | void __init config_q40(void) | 166 | void __init config_q40(void) |
159 | { | 167 | { |
160 | mach_sched_init = q40_sched_init; | 168 | mach_sched_init = q40_sched_init; |
161 | 169 | ||
162 | mach_init_IRQ = q40_init_IRQ; | 170 | mach_init_IRQ = q40_init_IRQ; |
163 | mach_gettimeoffset = q40_gettimeoffset; | 171 | mach_gettimeoffset = q40_gettimeoffset; |
164 | mach_hwclk = q40_hwclk; | 172 | mach_hwclk = q40_hwclk; |
165 | mach_get_ss = q40_get_ss; | 173 | mach_get_ss = q40_get_ss; |
166 | mach_get_rtc_pll = q40_get_rtc_pll; | 174 | mach_get_rtc_pll = q40_get_rtc_pll; |
167 | mach_set_rtc_pll = q40_set_rtc_pll; | 175 | mach_set_rtc_pll = q40_set_rtc_pll; |
168 | mach_set_clock_mmss = q40_set_clock_mmss; | 176 | mach_set_clock_mmss = q40_set_clock_mmss; |
169 | 177 | ||
170 | mach_reset = q40_reset; | 178 | mach_reset = q40_reset; |
171 | mach_get_model = q40_get_model; | 179 | mach_get_model = q40_get_model; |
172 | mach_get_hardware_list = q40_get_hardware_list; | 180 | mach_get_hardware_list = q40_get_hardware_list; |
173 | 181 | ||
174 | #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) | 182 | #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) |
175 | mach_beep = q40_mksound; | 183 | mach_beep = q40_mksound; |
176 | #endif | 184 | #endif |
177 | #ifdef CONFIG_HEARTBEAT | 185 | #ifdef CONFIG_HEARTBEAT |
178 | mach_heartbeat = q40_heartbeat; | 186 | mach_heartbeat = q40_heartbeat; |
179 | #endif | 187 | #endif |
180 | mach_halt = q40_halt; | 188 | mach_halt = q40_halt; |
181 | 189 | ||
182 | /* disable a few things that SMSQ might have left enabled */ | 190 | /* disable a few things that SMSQ might have left enabled */ |
183 | q40_disable_irqs(); | 191 | q40_disable_irqs(); |
184 | 192 | ||
185 | /* no DMA at all, but ide-scsi requires it.. make sure | 193 | /* no DMA at all, but ide-scsi requires it.. make sure |
186 | * all physical RAM fits into the boundary - otherwise | 194 | * all physical RAM fits into the boundary - otherwise |
187 | * allocator may play costly and useless tricks */ | 195 | * allocator may play costly and useless tricks */ |
188 | mach_max_dma_address = 1024*1024*1024; | 196 | mach_max_dma_address = 1024*1024*1024; |
189 | 197 | ||
190 | /* useful for early debugging stages - writes kernel messages into SRAM */ | 198 | /* useful for early debugging stages - writes kernel messages into SRAM */ |
191 | if (!strncmp( m68k_debug_device,"mem",3 )) | 199 | if (!strncmp( m68k_debug_device,"mem", 3)) { |
192 | { | 200 | /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ |
193 | /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ | 201 | _cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4; |
194 | _cpleft=2000-((long)q40_mem_cptr-0xff020000)/4; | 202 | q40_console_driver.write = q40_mem_console_write; |
195 | q40_console_driver.write = q40_mem_console_write; | 203 | register_console(&q40_console_driver); |
196 | register_console(&q40_console_driver); | 204 | } |
197 | } | ||
198 | } | 205 | } |
199 | 206 | ||
200 | 207 | ||
201 | int q40_parse_bootinfo(const struct bi_record *rec) | 208 | int q40_parse_bootinfo(const struct bi_record *rec) |
202 | { | 209 | { |
203 | return 1; | 210 | return 1; |
204 | } | 211 | } |
205 | 212 | ||
206 | 213 | ||
207 | static inline unsigned char bcd2bin (unsigned char b) | 214 | static inline unsigned char bcd2bin(unsigned char b) |
208 | { | 215 | { |
209 | return ((b>>4)*10 + (b&15)); | 216 | return (b >> 4) * 10 + (b & 15); |
210 | } | 217 | } |
211 | 218 | ||
212 | static inline unsigned char bin2bcd (unsigned char b) | 219 | static inline unsigned char bin2bcd(unsigned char b) |
213 | { | 220 | { |
214 | return (((b/10)*16) + (b%10)); | 221 | return (b / 10) * 16 + (b % 10); |
215 | } | 222 | } |
216 | 223 | ||
217 | 224 | ||
218 | unsigned long q40_gettimeoffset (void) | 225 | unsigned long q40_gettimeoffset(void) |
219 | { | 226 | { |
220 | return 5000*(ql_ticks!=0); | 227 | return 5000 * (ql_ticks != 0); |
221 | } | 228 | } |
222 | 229 | ||
223 | 230 | ||
@@ -238,9 +245,9 @@ unsigned long q40_gettimeoffset (void) | |||
238 | 245 | ||
239 | int q40_hwclk(int op, struct rtc_time *t) | 246 | int q40_hwclk(int op, struct rtc_time *t) |
240 | { | 247 | { |
241 | if (op) | 248 | if (op) { |
242 | { /* Write.... */ | 249 | /* Write.... */ |
243 | Q40_RTC_CTRL |= Q40_RTC_WRITE; | 250 | Q40_RTC_CTRL |= Q40_RTC_WRITE; |
244 | 251 | ||
245 | Q40_RTC_SECS = bin2bcd(t->tm_sec); | 252 | Q40_RTC_SECS = bin2bcd(t->tm_sec); |
246 | Q40_RTC_MINS = bin2bcd(t->tm_min); | 253 | Q40_RTC_MINS = bin2bcd(t->tm_min); |
@@ -251,25 +258,23 @@ int q40_hwclk(int op, struct rtc_time *t) | |||
251 | if (t->tm_wday >= 0) | 258 | if (t->tm_wday >= 0) |
252 | Q40_RTC_DOW = bin2bcd(t->tm_wday+1); | 259 | Q40_RTC_DOW = bin2bcd(t->tm_wday+1); |
253 | 260 | ||
254 | Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); | 261 | Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); |
255 | } | 262 | } else { |
256 | else | 263 | /* Read.... */ |
257 | { /* Read.... */ | 264 | Q40_RTC_CTRL |= Q40_RTC_READ; |
258 | Q40_RTC_CTRL |= Q40_RTC_READ; | 265 | |
259 | 266 | t->tm_year = bcd2bin (Q40_RTC_YEAR); | |
260 | t->tm_year = bcd2bin (Q40_RTC_YEAR); | 267 | t->tm_mon = bcd2bin (Q40_RTC_MNTH)-1; |
261 | t->tm_mon = bcd2bin (Q40_RTC_MNTH)-1; | 268 | t->tm_mday = bcd2bin (Q40_RTC_DATE); |
262 | t->tm_mday = bcd2bin (Q40_RTC_DATE); | 269 | t->tm_hour = bcd2bin (Q40_RTC_HOUR); |
263 | t->tm_hour = bcd2bin (Q40_RTC_HOUR); | 270 | t->tm_min = bcd2bin (Q40_RTC_MINS); |
264 | t->tm_min = bcd2bin (Q40_RTC_MINS); | 271 | t->tm_sec = bcd2bin (Q40_RTC_SECS); |
265 | t->tm_sec = bcd2bin (Q40_RTC_SECS); | 272 | |
266 | 273 | Q40_RTC_CTRL &= ~(Q40_RTC_READ); | |
267 | Q40_RTC_CTRL &= ~(Q40_RTC_READ); | 274 | |
268 | 275 | if (t->tm_year < 70) | |
269 | if (t->tm_year < 70) | 276 | t->tm_year += 100; |
270 | t->tm_year += 100; | 277 | t->tm_wday = bcd2bin(Q40_RTC_DOW)-1; |
271 | t->tm_wday = bcd2bin(Q40_RTC_DOW)-1; | ||
272 | |||
273 | } | 278 | } |
274 | 279 | ||
275 | return 0; | 280 | return 0; |
@@ -285,29 +290,25 @@ unsigned int q40_get_ss(void) | |||
285 | * clock is out by > 30 minutes. Logic lifted from atari code. | 290 | * clock is out by > 30 minutes. Logic lifted from atari code. |
286 | */ | 291 | */ |
287 | 292 | ||
288 | int q40_set_clock_mmss (unsigned long nowtime) | 293 | int q40_set_clock_mmss(unsigned long nowtime) |
289 | { | 294 | { |
290 | int retval = 0; | 295 | int retval = 0; |
291 | short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; | 296 | short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; |
292 | 297 | ||
293 | int rtc_minutes; | 298 | int rtc_minutes; |
294 | 299 | ||
300 | rtc_minutes = bcd2bin(Q40_RTC_MINS); | ||
295 | 301 | ||
296 | rtc_minutes = bcd2bin (Q40_RTC_MINS); | 302 | if ((rtc_minutes < real_minutes ? |
297 | 303 | real_minutes - rtc_minutes : | |
298 | if ((rtc_minutes < real_minutes | 304 | rtc_minutes - real_minutes) < 30) { |
299 | ? real_minutes - rtc_minutes | 305 | Q40_RTC_CTRL |= Q40_RTC_WRITE; |
300 | : rtc_minutes - real_minutes) < 30) | ||
301 | { | ||
302 | Q40_RTC_CTRL |= Q40_RTC_WRITE; | ||
303 | Q40_RTC_MINS = bin2bcd(real_minutes); | 306 | Q40_RTC_MINS = bin2bcd(real_minutes); |
304 | Q40_RTC_SECS = bin2bcd(real_seconds); | 307 | Q40_RTC_SECS = bin2bcd(real_seconds); |
305 | Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); | 308 | Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); |
306 | } | 309 | } else |
307 | else | ||
308 | retval = -1; | 310 | retval = -1; |
309 | 311 | ||
310 | |||
311 | return retval; | 312 | return retval; |
312 | } | 313 | } |
313 | 314 | ||
@@ -318,21 +319,23 @@ int q40_set_clock_mmss (unsigned long nowtime) | |||
318 | 319 | ||
319 | static int q40_get_rtc_pll(struct rtc_pll_info *pll) | 320 | static int q40_get_rtc_pll(struct rtc_pll_info *pll) |
320 | { | 321 | { |
321 | int tmp=Q40_RTC_CTRL; | 322 | int tmp = Q40_RTC_CTRL; |
323 | |||
322 | pll->pll_value = tmp & Q40_RTC_PLL_MASK; | 324 | pll->pll_value = tmp & Q40_RTC_PLL_MASK; |
323 | if (tmp & Q40_RTC_PLL_SIGN) | 325 | if (tmp & Q40_RTC_PLL_SIGN) |
324 | pll->pll_value = -pll->pll_value; | 326 | pll->pll_value = -pll->pll_value; |
325 | pll->pll_max=31; | 327 | pll->pll_max = 31; |
326 | pll->pll_min=-31; | 328 | pll->pll_min = -31; |
327 | pll->pll_posmult=512; | 329 | pll->pll_posmult = 512; |
328 | pll->pll_negmult=256; | 330 | pll->pll_negmult = 256; |
329 | pll->pll_clock=125829120; | 331 | pll->pll_clock = 125829120; |
332 | |||
330 | return 0; | 333 | return 0; |
331 | } | 334 | } |
332 | 335 | ||
333 | static int q40_set_rtc_pll(struct rtc_pll_info *pll) | 336 | static int q40_set_rtc_pll(struct rtc_pll_info *pll) |
334 | { | 337 | { |
335 | if (!pll->pll_ctrl){ | 338 | if (!pll->pll_ctrl) { |
336 | /* the docs are a bit unclear so I am doublesetting */ | 339 | /* the docs are a bit unclear so I am doublesetting */ |
337 | /* RTC_WRITE here ... */ | 340 | /* RTC_WRITE here ... */ |
338 | int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) | | 341 | int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) | |