Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
config.c
Go to the documentation of this file.
1 /*
2  * arch/m68k/mvme147/config.c
3  *
4  * Copyright (C) 1996 Dave Frascone [[email protected]]
5  * Cloned from Richard Hirst [[email protected]]
6  *
7  * Based on:
8  *
9  * Copyright (C) 1993 Hamish Macdonald
10  *
11  * This file is subject to the terms and conditions of the GNU General Public
12  * License. See the file README.legal in the main directory of this archive
13  * for more details.
14  */
15 
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/mm.h>
19 #include <linux/tty.h>
20 #include <linux/console.h>
21 #include <linux/linkage.h>
22 #include <linux/init.h>
23 #include <linux/major.h>
24 #include <linux/genhd.h>
25 #include <linux/rtc.h>
26 #include <linux/interrupt.h>
27 
28 #include <asm/bootinfo.h>
29 #include <asm/pgtable.h>
30 #include <asm/setup.h>
31 #include <asm/irq.h>
32 #include <asm/traps.h>
33 #include <asm/rtc.h>
34 #include <asm/machdep.h>
35 #include <asm/mvme147hw.h>
36 
37 
38 static void mvme147_get_model(char *model);
39 extern void mvme147_sched_init(irq_handler_t handler);
40 extern unsigned long mvme147_gettimeoffset (void);
41 extern int mvme147_hwclk (int, struct rtc_time *);
42 extern int mvme147_set_clock_mmss (unsigned long);
43 extern void mvme147_reset (void);
44 
45 
46 static int bcd2int (unsigned char b);
47 
48 /* Save tick handler routine pointer, will point to xtime_update() in
49  * kernel/time/timekeeping.c, called via mvme147_process_int() */
50 
52 
53 
55 {
56  if (bi->tag == BI_VME_TYPE || bi->tag == BI_VME_BRDINFO)
57  return 0;
58  else
59  return 1;
60 }
61 
62 void mvme147_reset(void)
63 {
64  printk ("\r\n\nCalled mvme147_reset\r\n");
65  m147_pcc->watchdog = 0x0a; /* Clear timer */
66  m147_pcc->watchdog = 0xa5; /* Enable watchdog - 100ms to reset */
67  while (1)
68  ;
69 }
70 
71 static void mvme147_get_model(char *model)
72 {
73  sprintf(model, "Motorola MVME147");
74 }
75 
76 /*
77  * This function is called during kernel startup to initialize
78  * the mvme147 IRQ handling routines.
79  */
80 
82 {
84 }
85 
87 {
88  mach_max_dma_address = 0x01000000;
95  mach_get_model = mvme147_get_model;
96 
97  /* Board type is only set by newer versions of vmelilo/tftplilo */
98  if (!vme_brdtype)
99  vme_brdtype = VME_TYPE_MVME147;
100 }
101 
102 
103 /* Using pcc tick timer 1 */
104 
105 static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
106 {
107  m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR;
108  m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
109  return tick_handler(irq, dev_id);
110 }
111 
112 
113 void mvme147_sched_init (irq_handler_t timer_routine)
114 {
115  tick_handler = timer_routine;
116  if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1", NULL))
117  pr_err("Couldn't register timer interrupt\n");
118 
119  /* Init the clock with a value */
120  /* our clock goes off every 6.25us */
121  m147_pcc->t1_preload = PCC_TIMER_PRELOAD;
122  m147_pcc->t1_cntrl = 0x0; /* clear timer */
123  m147_pcc->t1_cntrl = 0x3; /* start timer */
124  m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR; /* clear pending ints */
125  m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
126 }
127 
128 /* This is always executed with interrupts disabled. */
129 /* XXX There are race hazards in this code XXX */
130 unsigned long mvme147_gettimeoffset (void)
131 {
132  volatile unsigned short *cp = (volatile unsigned short *)0xfffe1012;
133  unsigned short n;
134 
135  n = *cp;
136  while (n != *cp)
137  n = *cp;
138 
139  n -= PCC_TIMER_PRELOAD;
140  return (unsigned long)n * 25 / 4;
141 }
142 
143 static int bcd2int (unsigned char b)
144 {
145  return ((b>>4)*10 + (b&15));
146 }
147 
148 int mvme147_hwclk(int op, struct rtc_time *t)
149 {
150 #warning check me!
151  if (!op) {
152  m147_rtc->ctrl = RTC_READ;
153  t->tm_year = bcd2int (m147_rtc->bcd_year);
154  t->tm_mon = bcd2int (m147_rtc->bcd_mth);
155  t->tm_mday = bcd2int (m147_rtc->bcd_dom);
156  t->tm_hour = bcd2int (m147_rtc->bcd_hr);
157  t->tm_min = bcd2int (m147_rtc->bcd_min);
158  t->tm_sec = bcd2int (m147_rtc->bcd_sec);
159  m147_rtc->ctrl = 0;
160  }
161  return 0;
162 }
163 
164 int mvme147_set_clock_mmss (unsigned long nowtime)
165 {
166  return 0;
167 }
168 
169 /*------------------- Serial console stuff ------------------------*/
170 
171 static void scc_delay (void)
172 {
173  int n;
174  volatile int trash;
175 
176  for (n = 0; n < 20; n++)
177  trash = n;
178 }
179 
180 static void scc_write (char ch)
181 {
182  volatile char *p = (volatile char *)M147_SCC_A_ADDR;
183 
184  do {
185  scc_delay();
186  }
187  while (!(*p & 4));
188  scc_delay();
189  *p = 8;
190  scc_delay();
191  *p = ch;
192 }
193 
194 
195 void m147_scc_write (struct console *co, const char *str, unsigned count)
196 {
197  unsigned long flags;
198 
199  local_irq_save(flags);
200 
201  while (count--)
202  {
203  if (*str == '\n')
204  scc_write ('\r');
205  scc_write (*str++);
206  }
207  local_irq_restore(flags);
208 }
209 
211 {
212  co->write = m147_scc_write;
213 }