Merge branch 'upstream-davem' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6] / arch / x86 / kernel / acpi / realmode / wakemain.c
1 #include "wakeup.h"
2 #include "boot.h"
3
4 static void udelay(int loops)
5 {
6         while (loops--)
7                 io_delay();     /* Approximately 1 us */
8 }
9
10 static void beep(unsigned int hz)
11 {
12         u8 enable;
13
14         if (!hz) {
15                 enable = 0x00;          /* Turn off speaker */
16         } else {
17                 u16 div = 1193181/hz;
18
19                 outb(0xb6, 0x43);       /* Ctr 2, squarewave, load, binary */
20                 io_delay();
21                 outb(div, 0x42);        /* LSB of counter */
22                 io_delay();
23                 outb(div >> 8, 0x42);   /* MSB of counter */
24                 io_delay();
25
26                 enable = 0x03;          /* Turn on speaker */
27         }
28         inb(0x61);              /* Dummy read of System Control Port B */
29         io_delay();
30         outb(enable, 0x61);     /* Enable timer 2 output to speaker */
31         io_delay();
32 }
33
34 #define DOT_HZ          880
35 #define DASH_HZ         587
36 #define US_PER_DOT      125000
37
38 /* Okay, this is totally silly, but it's kind of fun. */
39 static void send_morse(const char *pattern)
40 {
41         char s;
42
43         while ((s = *pattern++)) {
44                 switch (s) {
45                 case '.':
46                         beep(DOT_HZ);
47                         udelay(US_PER_DOT);
48                         beep(0);
49                         udelay(US_PER_DOT);
50                         break;
51                 case '-':
52                         beep(DASH_HZ);
53                         udelay(US_PER_DOT * 3);
54                         beep(0);
55                         udelay(US_PER_DOT);
56                         break;
57                 default:        /* Assume it's a space */
58                         udelay(US_PER_DOT * 3);
59                         break;
60                 }
61         }
62 }
63
64 void main(void)
65 {
66         /* Kill machine if structures are wrong */
67         if (wakeup_header.real_magic != 0x12345678)
68                 while (1);
69
70         if (wakeup_header.realmode_flags & 4)
71                 send_morse("...-");
72
73         if (wakeup_header.realmode_flags & 1)
74                 asm volatile("lcallw   $0xc000,$3");
75
76         if (wakeup_header.realmode_flags & 2) {
77                 /* Need to call BIOS */
78                 probe_cards(0);
79                 set_mode(wakeup_header.video_mode);
80         }
81 }