config.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/m68k/q40/config.c
  3.  *
  4.  *  Copyright (C) 1999 Richard Zidlicky
  5.  *
  6.  * originally based on:
  7.  *
  8.  *  linux/bvme/config.c
  9.  *
  10.  * This file is subject to the terms and conditions of the GNU General Public
  11.  * License.  See the file README.legal in the main directory of this archive
  12.  * for more details.
  13.  */
  14. #include <linux/config.h>
  15. #include <linux/types.h>
  16. #include <linux/kernel.h>
  17. #include <linux/mm.h>
  18. #include <linux/tty.h>
  19. #include <linux/console.h>
  20. #include <linux/linkage.h>
  21. #include <linux/init.h>
  22. #include <linux/major.h>
  23. #include <linux/serial_reg.h>
  24. #include <linux/rtc.h>
  25. #include <linux/vt_kern.h>
  26. #include <asm/io.h>
  27. #include <asm/rtc.h>
  28. #include <asm/bootinfo.h>
  29. #include <asm/system.h>
  30. #include <asm/pgtable.h>
  31. #include <asm/setup.h>
  32. #include <asm/irq.h>
  33. #include <asm/traps.h>
  34. #include <asm/rtc.h>
  35. #include <asm/machdep.h>
  36. #include <asm/q40_master.h>
  37. #include <asm/keyboard.h>
  38. extern void floppy_setup(char *str, int *ints);
  39. extern int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
  40.     char raw_mode);
  41. extern void q40_process_int (int level, struct pt_regs *regs);
  42. extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *);  /* added just for debugging */
  43. extern void q40_init_IRQ (void);
  44. extern void q40_free_irq (unsigned int, void *);
  45. extern int  q40_get_irq_list (char *);
  46. extern void q40_enable_irq (unsigned int);
  47. extern void q40_disable_irq (unsigned int);
  48. static void q40_get_model(char *model);
  49. static int  q40_get_hardware_list(char *buffer);
  50. extern int  q40_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
  51. extern void q40_sched_init(void (*handler)(int, void *, struct pt_regs *));
  52. extern unsigned long q40_gettimeoffset (void);
  53. extern void q40_gettod (int *year, int *mon, int *day, int *hour,
  54.                            int *min, int *sec);
  55. extern int q40_hwclk (int, struct rtc_time *);
  56. extern int q40_set_clock_mmss (unsigned long);
  57. extern void q40_reset (void);
  58. void q40_halt(void);
  59. extern void q40_waitbut(void);
  60. void q40_set_vectors (void);
  61. void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );
  62. extern char *saved_command_line;
  63. extern char m68k_debug_device[];
  64. static void q40_mem_console_write(struct console *co, const char *b,
  65.     unsigned int count);
  66. extern int ql_ticks;
  67. static struct console q40_console_driver = {
  68. name: "debug",
  69. flags: CON_PRINTBUFFER,
  70. index: -1,
  71. };
  72. /* early debugging function:*/
  73. extern char *q40_mem_cptr; /*=(char *)0xff020000;*/
  74. static int _cpleft;
  75. #if 0
  76. int q40_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
  77. {
  78.         *keycodep = keycode;
  79.         return 1;
  80. }
  81. #endif
  82. static void q40_mem_console_write(struct console *co, const char *s,
  83.   unsigned int count)
  84. {
  85.   char *p=(char *)s;
  86.   if (count<_cpleft)
  87.     while (count-- >0){
  88.       *q40_mem_cptr=*p++;
  89.       q40_mem_cptr+=4;
  90.       _cpleft--;
  91.     }
  92. }
  93. #if 0
  94. void printq40(char *str)
  95. {
  96.   int l=strlen(str);
  97.   char *p=q40_mem_cptr;
  98.   while (l-- >0 && _cpleft-- >0)
  99.     {
  100.       *p=*str++;
  101.       p+=4;
  102.     }
  103.   q40_mem_cptr=p;
  104. }
  105. #endif
  106. #if 0
  107. int q40_kbdrate (struct kbd_repeat *k)
  108. {
  109. return 0;
  110. }
  111. #endif
  112. static int halted=0;
  113. #ifdef CONFIG_HEARTBEAT
  114. static void q40_heartbeat(int on)
  115. {
  116.   if (halted) return;
  117.   if (on)
  118.     Q40_LED_ON();
  119.   else
  120.     Q40_LED_OFF();
  121. }
  122. #endif
  123. void q40_reset()
  124. {
  125.         halted=1;
  126.         printk ("nn*******************************************n"
  127. "Called q40_reset : press the RESET button!! n"
  128. "*******************************************n");
  129. Q40_LED_ON();
  130. while(1) ;
  131. }
  132. void q40_halt()
  133. {
  134.         halted=1;
  135.         printk ("nn*******************n"
  136.     "  Called q40_haltn"
  137.     "*******************n");
  138. Q40_LED_ON();
  139. while(1) ;
  140. }
  141. static void q40_get_model(char *model)
  142. {
  143.     sprintf(model, "Q40");
  144. }
  145. /* No hardware options on Q40? */
  146. static int q40_get_hardware_list(char *buffer)
  147. {
  148.     *buffer = '';
  149.     return 0;
  150. }
  151. static unsigned int serports[]={0x3f8,0x2f8,0x3e8,0x2e8,0};
  152. void q40_disable_irqs(void)
  153. {
  154.   unsigned i,j;
  155.   
  156.   j=0;
  157.   while((i=serports[j++])) outb(0,i+UART_IER);
  158.   master_outb(0,EXT_ENABLE_REG);
  159.   master_outb(0,KEY_IRQ_ENABLE_REG);
  160. }
  161. void __init config_q40(void)
  162. {
  163.     mach_sched_init      = q40_sched_init;
  164. #ifdef CONFIG_VT
  165.     mach_keyb_init       = q40kbd_init_hw;
  166.     mach_kbd_translate   = q40kbd_translate;
  167.     kd_mksound             = q40_mksound;
  168. #endif
  169.     mach_init_IRQ        = q40_init_IRQ;   
  170.     mach_gettimeoffset   = q40_gettimeoffset; 
  171.     mach_gettod    = q40_gettod;
  172.     mach_hwclk           = q40_hwclk; 
  173.     mach_set_clock_mmss  = q40_set_clock_mmss;
  174.     mach_reset  = q40_reset;
  175.     mach_free_irq  = q40_free_irq; 
  176.     mach_process_int  = q40_process_int;
  177.     mach_get_irq_list  = q40_get_irq_list;
  178.     mach_request_irq  = q40_request_irq;
  179.     enable_irq  = q40_enable_irq;
  180.     disable_irq          = q40_disable_irq;
  181.     mach_default_handler = &q40_sys_default_handler;
  182.     mach_get_model       = q40_get_model;
  183.     mach_get_hardware_list = q40_get_hardware_list;
  184. #ifdef CONFIG_MAGIC_SYSRQ
  185.     mach_sysrq_key       = 0x54;
  186. #endif
  187. #ifdef CONFIG_HEARTBEAT
  188.     mach_heartbeat = q40_heartbeat;
  189. #endif
  190.     mach_halt = q40_halt;
  191. #ifdef CONFIG_DUMMY_CONSOLE
  192.     conswitchp = &dummy_con;
  193. #endif
  194.     /* disable a few things that SMSQ might have left enabled */
  195.     q40_disable_irqs();
  196.     /* no DMA at all, but ide-scsi requires it.. make sure
  197.      * all physical RAM fits into the boundary - otherwise 
  198.      * allocator may play costly and useless tricks */
  199.     mach_max_dma_address = 1024*1024*1024;   
  200.     /* useful for early debugging stages - writes kernel messages into SRAM */
  201.     if (!strncmp( m68k_debug_device,"mem",3 ))
  202.       {
  203. /*printk("using NVRAM debug, q40_mem_cptr=%pn",q40_mem_cptr);*/
  204. _cpleft=2000-((long)q40_mem_cptr-0xff020000)/4;
  205. q40_console_driver.write = q40_mem_console_write;
  206. register_console(&q40_console_driver);
  207.       }
  208. }
  209. int q40_parse_bootinfo(const struct bi_record *rec)
  210. {
  211.   return 1;
  212. }
  213. static inline unsigned char bcd2bin (unsigned char b)
  214. {
  215. return ((b>>4)*10 + (b&15));
  216. }
  217. static inline unsigned char bin2bcd (unsigned char b)
  218. {
  219. return (((b/10)*16) + (b%10));
  220. }
  221. unsigned long q40_gettimeoffset (void)
  222. {
  223.     return 5000*(ql_ticks!=0);
  224. }
  225. extern void q40_gettod (int *year, int *mon, int *day, int *hour,
  226.                            int *min, int *sec)
  227. {
  228. Q40_RTC_CTRL |= Q40_RTC_READ;
  229. *year = bcd2bin (Q40_RTC_YEAR);
  230. *mon = bcd2bin (Q40_RTC_MNTH);
  231. *day = bcd2bin (Q40_RTC_DATE);
  232. *hour = bcd2bin (Q40_RTC_HOUR);
  233. *min = bcd2bin (Q40_RTC_MINS);
  234. *sec = bcd2bin (Q40_RTC_SECS);
  235. Q40_RTC_CTRL &= ~(Q40_RTC_READ);
  236. }
  237. /*
  238.  * Looks like op is non-zero for setting the clock, and zero for
  239.  * reading the clock.
  240.  *
  241.  *  struct hwclk_time {
  242.  *         unsigned        sec;       0..59
  243.  *         unsigned        min;       0..59
  244.  *         unsigned        hour;      0..23
  245.  *         unsigned        day;       1..31
  246.  *         unsigned        mon;       0..11
  247.  *         unsigned        year;      00...
  248.  *         int             wday;      0..6, 0 is Sunday, -1 means unknown/don't set
  249.  * };
  250.  */
  251. int q40_hwclk(int op, struct rtc_time *t)
  252. {
  253.         if (op)
  254. { /* Write.... */
  255.         Q40_RTC_CTRL |= Q40_RTC_WRITE;
  256. Q40_RTC_SECS = bin2bcd(t->tm_sec);
  257. Q40_RTC_MINS = bin2bcd(t->tm_min);
  258. Q40_RTC_HOUR = bin2bcd(t->tm_hour);
  259. Q40_RTC_DATE = bin2bcd(t->tm_mday);
  260. Q40_RTC_MNTH = bin2bcd(t->tm_mon + 1);
  261. Q40_RTC_YEAR = bin2bcd(t->tm_year%100);
  262. if (t->tm_wday >= 0)
  263. Q40_RTC_DOW = bin2bcd(t->tm_wday+1);
  264.         Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
  265. }
  266. else
  267. { /* Read....  */
  268.   Q40_RTC_CTRL |= Q40_RTC_READ;
  269.   t->tm_year = bcd2bin (Q40_RTC_YEAR);
  270.   t->tm_mon  = bcd2bin (Q40_RTC_MNTH)-1;
  271.   t->tm_mday = bcd2bin (Q40_RTC_DATE);
  272.   t->tm_hour = bcd2bin (Q40_RTC_HOUR);
  273.   t->tm_min  = bcd2bin (Q40_RTC_MINS);
  274.   t->tm_sec  = bcd2bin (Q40_RTC_SECS);
  275.   Q40_RTC_CTRL &= ~(Q40_RTC_READ);
  276.   
  277.   if (t->tm_year < 70)
  278.     t->tm_year += 100;
  279.   t->tm_wday = bcd2bin(Q40_RTC_DOW)-1;
  280. }
  281. return 0;
  282. }
  283. /*
  284.  * Set the minutes and seconds from seconds value 'nowtime'.  Fail if
  285.  * clock is out by > 30 minutes.  Logic lifted from atari code.
  286.  */
  287. int q40_set_clock_mmss (unsigned long nowtime)
  288. {
  289. int retval = 0;
  290. short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
  291. int rtc_minutes;
  292. rtc_minutes = bcd2bin (Q40_RTC_MINS);
  293. if ((rtc_minutes < real_minutes
  294. ? real_minutes - rtc_minutes
  295. : rtc_minutes - real_minutes) < 30)
  296. {    
  297.         Q40_RTC_CTRL |= Q40_RTC_WRITE;
  298. Q40_RTC_MINS = bin2bcd(real_minutes);
  299. Q40_RTC_SECS = bin2bcd(real_seconds);
  300. Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
  301. }
  302. else
  303. retval = -1;
  304. return retval;
  305. }