cleaning up olpc patch 1
[librecmc/librecmc.git] / target / linux / olpc / files / arch / i386 / kernel / olpc-pm.c
1 /* olpc-pm.c
2  * © 2006 Red Hat, Inc.
3  * Portions also copyright 2006 Advanced Micro Devices, Inc.
4  * GPLv2
5  */
6
7 #include <linux/kernel.h>
8 #include <linux/interrupt.h>
9 #include <linux/module.h>
10 #include <linux/delay.h>
11 #include <linux/input.h>
12 #include <linux/suspend.h>
13 #include <linux/bootmem.h>
14 #include <linux/platform_device.h>
15 #include <linux/rtc.h>
16 #include <linux/mc146818rtc.h>
17 #include <asm/io.h>
18
19 #include <asm/olpc.h>
20
21 /* A few words about accessing the ACPI and PM registers.  Long story short,
22    byte and word accesses of the ACPI and PM registers is broken.  The only
23    way to do it really correctly is to use dword accesses, which we do
24    throughout this code.  For more details, please consult Eratta 17 and 18
25    here:
26
27    http://www.amd.com/files/connectivitysolutions/geode/geode_gx/34472D_CS5536_B1_specupdate.pdf
28 */
29
30 #define PM_IRQ 3
31
32 #define CS5536_PM_PWRBTN (1 << 8)
33 #define CS5536_PM_RTC    (1 << 10)
34
35 #define GPIO_WAKEUP_EC (1 << 31)
36 #define GPIO_WAKEUP_LID (1 << 30)
37
38 #define PM_MODE_NORMAL 0
39 #define PM_MODE_TEST   1
40 #define PM_MODE_MAX    2
41
42 /* These, and the battery EC commands, should be in an olpc.h. */
43 #define EC_WRITE_SCI_MASK 0x1b
44 #define EC_READ_SCI_MASK  0x1c
45
46 extern void do_olpc_suspend_lowlevel(void);
47
48 static struct {
49         unsigned long address;
50         unsigned short segment;
51 } ofw_bios_entry = { 0, __KERNEL_CS };
52
53 static int olpc_pm_mode = PM_MODE_NORMAL;
54 static unsigned long acpi_base;
55 static unsigned long pms_base;
56 static int sci_irq;
57 static int olpc_lid_flag;
58
59 static struct input_dev *pm_inputdev;
60 static struct input_dev *lid_inputdev;
61 static struct input_dev *ebook_inputdev;
62 static struct pm_ops olpc_pm_ops;
63
64 static int gpio_wake_events = 0;
65 static int ebook_state = -1;
66 static u16 olpc_wakeup_mask = 0;
67
68 struct platform_device olpc_powerbutton_dev = {
69         .name = "powerbutton",
70         .id = -1,
71 };
72
73 struct platform_device olpc_lid_dev = {
74         .name = "lid",
75         .id = -1,
76 };
77
78 static void __init init_ebook_state(void)
79 {
80         if (olpc_ec_cmd(0x2a, NULL, 0, (unsigned char *) &ebook_state, 1)) {
81                 printk(KERN_WARNING "olpc-pm:  failed to get EBOOK state!\n");
82                 ebook_state = 0;
83         }
84         ebook_state &= 1;
85
86         /* the input layer needs to know what value to default to as well */
87         input_report_switch(ebook_inputdev, SW_TABLET_MODE, ebook_state);
88         input_sync(ebook_inputdev);
89 }
90
91 static void (*battery_callback)(unsigned long);
92 static DEFINE_SPINLOCK(battery_callback_lock);
93
94 /* propagate_events is non-NULL if run from workqueue,
95    NULL when called at init time to flush SCI queue */
96 static void process_sci_queue(struct work_struct *propagate_events)
97 {
98         unsigned char data = 0;
99         unsigned char battery_events = 0;
100         int ret;
101
102         do {
103                 ret = olpc_ec_cmd(0x84, NULL, 0, &data, 1);
104                 if (!ret) {
105                         printk(KERN_DEBUG "olpc-pm:  SCI 0x%x received\n",
106                                         data);
107
108                         switch (data) {
109                         case EC_SCI_SRC_EMPTY:
110                         case EC_SCI_SRC_GAME:
111                         case EC_SCI_SRC_WLAN:
112                                 /* we ignore these for now */
113                                 break;
114                         case EC_SCI_SRC_BATERR:
115                                 printk(KERN_ERR "olpc-pm:  Battery Management System detected an error!  Remove turnip from battery slot.\n");
116                         case EC_SCI_SRC_BATSOC:
117                         case EC_SCI_SRC_BATTERY:
118                         case EC_SCI_SRC_ACPWR:
119                                 battery_events |= data;
120                                 break;
121                         case EC_SCI_SRC_EBOOK:
122                                 ebook_state = !ebook_state;
123                                 if (propagate_events) {
124                                         input_report_switch(ebook_inputdev,
125                                                 SW_TABLET_MODE, ebook_state);
126                                         input_sync(ebook_inputdev);
127                                 }
128                                 break;
129                         default:
130                                 printk(KERN_ERR "olpc-pm:  Unknown SCI event 0x%x occurred!\n", data);
131                         }
132                 }
133         } while (data && !ret);
134
135         if (battery_events && battery_callback && propagate_events) {
136                 void (*cbk)(unsigned long);
137                 
138                 /* Older EC versions didn't distinguish between AC and battery
139                    events */
140                 if (olpc_platform_info.ecver < 0x45)
141                         battery_events = EC_SCI_SRC_BATTERY | EC_SCI_SRC_ACPWR;
142
143                 spin_lock(&battery_callback_lock);
144                 cbk = battery_callback;
145                 spin_unlock(&battery_callback_lock);
146
147                 cbk(battery_events);
148         }
149
150         if (ret)
151                 printk(KERN_WARNING "Failed to clear SCI queue!\n");
152 }
153
154 static DECLARE_WORK(sci_work, process_sci_queue);
155
156 void olpc_register_battery_callback(void (*f)(unsigned long))
157 {
158         spin_lock(&battery_callback_lock);
159         battery_callback = f;
160         spin_unlock(&battery_callback_lock);
161 }
162 EXPORT_SYMBOL_GPL(olpc_register_battery_callback);
163
164 void olpc_deregister_battery_callback(void)
165 {
166         spin_lock(&battery_callback_lock);
167         battery_callback = NULL;
168         spin_unlock(&battery_callback_lock);
169         cancel_work_sync(&sci_work);
170 }
171 EXPORT_SYMBOL_GPL(olpc_deregister_battery_callback);
172
173
174 static int olpc_pm_interrupt(int irq, void *id)
175 {
176         uint32_t sts, gpe = 0;
177
178         sts = inl(acpi_base + PM1_STS);
179         outl(sts | 0xFFFF, acpi_base + PM1_STS);
180
181         if (olpc_get_rev() >= OLPC_REV_B2) {
182                 gpe = inl(acpi_base + PM_GPE0_STS);
183                 outl(0xFFFFFFFF, acpi_base + PM_GPE0_STS);
184         }
185
186         if (sts & CS5536_PM_PWRBTN) {
187                 input_report_key(pm_inputdev, KEY_POWER, 1);
188                 input_sync(pm_inputdev);
189                 printk(KERN_DEBUG "olpm-pm:  PM_PWRBTN event received\n");
190                 /* Do we need to delay this (and hence schedule_work)? */
191                 input_report_key(pm_inputdev, KEY_POWER, 0);
192                 input_sync(pm_inputdev);
193         }
194
195         if (gpe & GPIO_WAKEUP_EC) {
196                 geode_gpio_clear(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
197                 schedule_work(&sci_work);
198         }
199
200         if (gpe & GPIO_WAKEUP_LID) {
201                 /* Disable events */
202                 geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
203                         
204                 /* Clear the edge */
205                         
206                 if (olpc_lid_flag)
207                         geode_gpio_clear(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
208                 else
209                         geode_gpio_clear(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
210
211                 /* Clear the status too */
212                 geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
213                 geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
214
215                 /* The line is high when the LID is open, but SW_LID
216                  * should be high when the LID is closed, so we pass the old
217                  * value of olpc_lid_flag
218                  */
219
220                 input_report_switch(lid_inputdev, SW_LID, olpc_lid_flag);
221                 input_sync(lid_inputdev);
222
223                 /* Swap the status */
224                 olpc_lid_flag = !olpc_lid_flag;
225
226                 if (olpc_lid_flag)
227                         geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
228                 else
229                         geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
230
231                 /* re-enable the event */
232                 geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
233         }
234
235         return IRQ_HANDLED;
236 }
237
238 /*
239  * For now, only support STR.  We also don't support suspending on
240  * B1s, due to difficulties with the cafe FPGA.
241  */
242 static int olpc_pm_state_valid(suspend_state_t pm_state)
243 {
244         if (pm_state == PM_SUSPEND_MEM && olpc_rev_after(OLPC_REV_B1))
245                 return 1;
246
247         return 0;
248 }
249
250 /* This is a catchall function for operations that just don't belong
251  * anywhere else.  Later we will evaluate if these belong in the
252  * individual device drivers or the firmware.
253  * If you add something to this function, please explain yourself with
254  * a comment.
255  */
256
257 extern void gxfb_flatpanel_control(int state);
258
259 static u32 gpio_wakeup[2];
260 static u64 irq_sources[4];
261 static u64 mfgpt_irq_msr, mfgpt_nr_msr;
262
263 void olpc_fixup_wakeup(void)
264 {
265         u32 base = geode_gpio_base();
266         int i;
267
268         /* This clears any pending events from the status register -
269          * the firmware also does this, but its possible that it tries
270          * it too early before the key has a chance to debounce
271          */
272
273         outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
274
275         /* Enable the flatpanel sequencing as early as possible, because
276            it takes ~64ms to resume.  This probably belongs in the firmware */
277
278         //gxfb_flatpanel_control(1);
279
280         /* Restore the interrupt sources */
281         wrmsrl(MSR_PIC_YSEL_LOW, irq_sources[0]);
282         wrmsrl(MSR_PIC_ZSEL_LOW, irq_sources[1]);
283         wrmsrl(MSR_PIC_YSEL_HIGH, irq_sources[2]);
284         wrmsrl(MSR_PIC_ZSEL_HIGH, irq_sources[3]);
285
286         /* Restore the X and Y sources for GPIO */
287         outl(gpio_wakeup[0], base + GPIO_MAP_X);
288         outl(gpio_wakeup[1], base + GPIO_MAP_Y);
289
290         /* Resture the MFGPT MSRs */
291         wrmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
292         wrmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
293         
294         for (i=0;i<2;i++) {
295                 /* tell the wireless module to restart USB communication */
296                 olpc_ec_cmd(0x24, NULL, 0, NULL, 0);
297         }
298 }
299
300 void olpc_fixup_sleep(void)
301 {
302         u32 base = geode_gpio_base();
303         int i;
304
305         /* Save the X and Y sources for GPIO */
306         gpio_wakeup[0] = inl(base + GPIO_MAP_X);
307         gpio_wakeup[1] = inl(base + GPIO_MAP_Y);
308
309         /* Save the Y and Z  unrestricted sources */
310
311         rdmsrl(MSR_PIC_YSEL_LOW, irq_sources[0]);
312         rdmsrl(MSR_PIC_ZSEL_LOW, irq_sources[1]);
313         rdmsrl(MSR_PIC_YSEL_HIGH, irq_sources[2]);
314         rdmsrl(MSR_PIC_ZSEL_HIGH, irq_sources[3]);
315
316         /* Turn off the MFGPT timers on the way down */
317
318         for(i = 0; i < 8; i++) {
319                 u32 val = geode_mfgpt_read(i, MFGPT_REG_SETUP);
320
321                 if (val & MFGPT_SETUP_SETUP) {
322                         val &= ~MFGPT_SETUP_CNTEN;
323                         geode_mfgpt_write(i, MFGPT_REG_SETUP, val);
324                 }
325         }
326
327         /* Save the MFGPT MSRs */
328         rdmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
329         rdmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
330
331         if (device_may_wakeup(&olpc_powerbutton_dev.dev))
332                 olpc_wakeup_mask |= CS5536_PM_PWRBTN;
333         else
334                 olpc_wakeup_mask &= ~(CS5536_PM_PWRBTN);
335
336         if (device_may_wakeup(&olpc_lid_dev.dev)) {
337                 geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
338                 gpio_wake_events |= GPIO_WAKEUP_LID;
339         } else {
340                 geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
341                 gpio_wake_events &= ~(GPIO_WAKEUP_LID);
342         }
343 }
344
345 static int olpc_pm_enter(suspend_state_t pm_state)
346 {
347         /* Only STR is supported */
348         if (pm_state != PM_SUSPEND_MEM)
349                 return -EINVAL;
350
351         olpc_fixup_sleep();
352
353         /* Set the GPIO wakeup bits */
354         outl(gpio_wake_events, acpi_base + PM_GPE0_EN);
355         outl(0xFFFFFFFF, acpi_base + PM_GPE0_STS);
356
357         /* Save CPU state */
358         do_olpc_suspend_lowlevel();
359
360         olpc_fixup_wakeup();
361
362         /* Restore the SCI wakeup events */
363         outl(gpio_wake_events, acpi_base + PM_GPE0_EN);
364
365         return 0;
366 }
367
368 int asmlinkage olpc_do_sleep(u8 sleep_state)
369 {
370         void *pgd_addr = __va(read_cr3());
371         printk(KERN_ERR "olpc_do_sleep!\n"); /* this needs to remain here so
372                                               * that gcc doesn't optimize
373                                               * away our __va! */
374         /* FIXME: Set the SCI bits we want to wake up on here */
375
376         /* FIXME:  Set any other SCI events that we might want here */
377
378         outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
379
380         /* If we are in test mode, then just return (simulate a successful
381            suspend/resume).  Otherwise, if we are doing the real thing,
382            then go for the gusto */
383
384         if (olpc_pm_mode != PM_MODE_TEST) {
385                 __asm__ __volatile__("movl %0,%%eax" : : "r" (pgd_addr));
386                 __asm__("call *(%%edi); cld"
387                         : : "D" (&ofw_bios_entry));
388         }
389
390         return 0;
391 }
392
393 /* This code will slowly disappear as we fixup the issues in the BIOS */
394
395 static void __init olpc_fixup_bios(void)
396 {
397         unsigned long hi, lo;
398
399         if (olpc_has_vsa()) {
400                 /* The VSA aggressively sets up the ACPI and PM register for
401                  * trapping - its not enough to force these values in the BIOS -
402                  * they seem to be changed during PCI init as well.
403                  */
404
405                 /* Change the PM registers to decode to the DD */
406
407                 rdmsr(0x510100e2, lo, hi);
408                 hi |= 0x80000000;
409                 wrmsr(0x510100e2, lo, hi);
410
411                 /* Change the ACPI registers to decode to the DD */
412
413                 rdmsr(0x510100e3, lo, hi);
414                 hi |= 0x80000000;
415                 wrmsr(0x510100e3, lo, hi);
416         }
417
418         /* GPIO24 controls WORK_AUX */
419
420         geode_gpio_set(OLPC_GPIO_WORKAUX, GPIO_OUTPUT_ENABLE);
421         geode_gpio_set(OLPC_GPIO_WORKAUX, GPIO_OUTPUT_AUX1);
422
423         if (olpc_get_rev() >= OLPC_REV_B2) {
424                 /* GPIO10 is connected to the thermal alarm */
425                 geode_gpio_set(OLPC_GPIO_THRM_ALRM, GPIO_INPUT_ENABLE);
426                 geode_gpio_set(OLPC_GPIO_THRM_ALRM, GPIO_INPUT_AUX1);
427
428                 /* Set up to get LID events */
429                 geode_gpio_set(OLPC_GPIO_LID, GPIO_INPUT_ENABLE);
430
431                 /* Clear edge detection and event enable for now */
432                 geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
433                 geode_gpio_clear(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
434                 geode_gpio_clear(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
435
436                 geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
437                 geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
438
439                 /* Set the LID to cause an PME event on group 6 */
440                 geode_gpio_event_pme(OLPC_GPIO_LID, 6);
441
442                 /* Set PME group 6 to fire the SCI interrupt */
443                 geode_gpio_set_irq(6, sci_irq);
444         }
445
446         geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_INPUT_ENABLE);
447
448         /* Clear pending events */
449
450         geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
451         geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_POSITIVE_EDGE_STS);
452
453         //geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_EN);
454         geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_EVENTS_ENABLE);
455
456         /* Set the SCI to cause a PME event on group 7 */
457         geode_gpio_event_pme(OLPC_GPIO_ECSCI, 7);
458
459         /* And have group 6 also fire the SCI interrupt */
460         geode_gpio_set_irq(7, sci_irq);
461 }
462
463 /* This provides a control file for setting up testing of the
464    power management system.  For now, there is just one setting:
465    "test" which means that we don't actually enter the power
466    off routine.
467 */
468
469 static const char * const pm_states[] = {
470         [PM_MODE_NORMAL]  = "normal",
471         [PM_MODE_TEST]    = "test",
472 };
473
474 extern struct mutex pm_mutex;
475 extern struct kset power_subsys;
476
477 static ssize_t control_show(struct kset *s, char *buf)
478 {
479         return sprintf(buf, "%s\n", pm_states[olpc_pm_mode]);
480 }
481
482 static ssize_t control_store(struct kset *s, const char *buf, size_t n)
483 {
484         int i, len;
485         char *p;
486
487         p = memchr(buf, '\n', n);
488         len = p ? p - buf : n;
489
490         /* Grab the mutex */
491         mutex_lock(&pm_mutex);
492         
493         for(i = 0; i < PM_MODE_MAX; i++) {
494                 if (!strncmp(buf, pm_states[i], len)) {
495                         olpc_pm_mode = i;
496                         break;
497                 }
498         }
499
500         mutex_unlock(&pm_mutex);
501
502         return (i == PM_MODE_MAX) ? -EINVAL : n;
503 }
504        
505 static struct subsys_attribute control_attr = {
506         .attr = {
507                 .name = "olpc-pm",
508                 .mode = 0644,
509         },
510         .show = control_show,
511         .store = control_store,
512 };
513
514 static struct attribute * olpc_attributes[] = {
515         &control_attr.attr,
516         NULL
517 };
518
519 static struct attribute_group olpc_attrs = {
520         .attrs = olpc_attributes,
521 };
522
523 static int __init alloc_inputdevs(void)
524 {
525         int ret = -ENOMEM;
526
527         pm_inputdev = input_allocate_device();
528         if (!pm_inputdev)
529                 goto err;
530
531         pm_inputdev->name = "OLPC PM";
532         pm_inputdev->phys = "olpc_pm/input0";
533         set_bit(EV_KEY, pm_inputdev->evbit);
534         set_bit(KEY_POWER, pm_inputdev->keybit);
535
536         ret = input_register_device(pm_inputdev);
537         if (ret) {
538                 printk(KERN_ERR "olpc-pm:  failed to register PM input device: %d\n", ret);
539                 goto err;
540         }
541
542         lid_inputdev = input_allocate_device();
543         if (!lid_inputdev)
544                 goto err;
545
546         lid_inputdev->name = "OLPC lid switch";
547         lid_inputdev->phys = "olpc_pm/input1";
548         set_bit(EV_SW, lid_inputdev->evbit);
549         set_bit(SW_LID, lid_inputdev->swbit);
550
551         ret = input_register_device(lid_inputdev);
552         if (ret) {
553                 printk(KERN_ERR "olpc-pm:  failed to register lid input device: %d\n", ret);
554                 goto err;
555         }
556
557         ebook_inputdev = input_allocate_device();
558         if (!ebook_inputdev)
559                 goto err;
560
561         ebook_inputdev->name = "OLPC ebook switch";
562         ebook_inputdev->phys = "olpc_pm/input2";
563         set_bit(EV_SW, ebook_inputdev->evbit);
564         set_bit(SW_TABLET_MODE, ebook_inputdev->swbit);
565
566         ret = input_register_device(ebook_inputdev);
567         if (ret) {
568                 printk(KERN_ERR "olpc-pm:  failed to register ebook input device: %d\n", ret);
569                 goto err;
570         }
571
572         return ret;
573 err:
574         if (ebook_inputdev) {
575                 input_unregister_device(ebook_inputdev);
576                 ebook_inputdev = NULL;
577         }
578         if (lid_inputdev) {
579                 input_unregister_device(lid_inputdev);
580                 lid_inputdev = NULL;
581         }
582         if (pm_inputdev) {
583                 input_unregister_device(pm_inputdev);
584                 pm_inputdev = NULL;
585         }
586
587         return ret;
588 }
589
590 static int __init olpc_pm_init(void)
591 {
592         uint32_t lo, hi;
593         int ret;
594         uint8_t ec_byte;
595
596         if (!machine_is_olpc())
597                 return -ENODEV;
598
599         acpi_base = geode_acpi_base();
600         pms_base = geode_pms_base();
601
602         if (!acpi_base || !pms_base)
603           return -ENODEV;
604
605         ret = alloc_inputdevs();
606         if (ret)
607                 return ret;
608
609         rdmsr(0x51400020, lo, hi);
610         sci_irq = (lo >> 20) & 15;
611
612         if (sci_irq) {
613                 printk(KERN_INFO "SCI is mapped to IRQ %d\n", sci_irq);
614         } else {
615                 /* Zero doesn't mean zero -- it means masked */
616                 printk(KERN_INFO "SCI unmapped. Mapping to IRQ 3\n");
617                 sci_irq = 3;
618                 lo |= 0x00300000;
619                 wrmsrl(0x51400020, lo);
620         }
621
622         olpc_fixup_bios();
623
624         lo = inl(pms_base + PM_FSD);
625
626         /* Lock, enable failsafe, 4 seconds */
627         outl(0xc001f400, pms_base + PM_FSD);
628
629         /* Here we set up the SCI events we're interested in during
630          * real-time.  We have no sleep button, and the RTC doesn't make
631          * sense, so set up the power button
632          */
633
634         outl(inl(acpi_base) | ((CS5536_PM_PWRBTN) << 16), acpi_base);
635
636         if (olpc_get_rev() >= OLPC_REV_B2) {
637                 gpio_wake_events |= GPIO_WAKEUP_LID;
638
639                 /* Get the current value of the GPIO, and set up the edges */
640                 olpc_lid_flag = geode_gpio_isset(OLPC_GPIO_LID, GPIO_READ_BACK);
641
642                 /* Watch for the opposite edge */
643
644                 if (olpc_lid_flag)
645                         geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
646                 else
647                         geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
648
649                 /* Enable the event */
650                 geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
651         }
652
653         /* Set up the mask for wakeups the EC will generate SCIs on */
654
655         ret = olpc_ec_cmd(EC_READ_SCI_MASK, NULL, 0, &ec_byte, 1);
656         if (ret) 
657                 printk(KERN_ERR "Error getting the EC SCI mask: %d\n", ret);
658         
659         /* Disable battery 1% charge wakeups */
660         ec_byte &= ~EC_SCI_SRC_BATSOC;
661
662         ret = olpc_ec_cmd(EC_WRITE_SCI_MASK, &ec_byte, 1, NULL, 0);
663         if (ret)
664                 printk(KERN_ERR "Error setting the EC SCI mask: %d\n", ret);
665
666         /* Set up the EC SCI */
667
668         gpio_wake_events |= GPIO_WAKEUP_EC;
669
670         outl(gpio_wake_events, acpi_base + PM_GPE0_EN);
671         outl(0xFFFFFFFF, acpi_base + PM_GPE0_STS);
672
673         /* Select level triggered in PIC */
674
675         if (sci_irq < 8) {
676                 lo = inb(0x4d0);
677                 lo |= 1 << sci_irq;
678                 outb(lo, 0x4d0);
679         } else {
680                 lo = inb(0x4d1);
681                 lo |= 1 << (sci_irq - 8);
682                 outb(lo, 0x4d1);
683         }
684         /* Clear pending interrupt */
685         outl(inl(acpi_base) | 0xFFFF, acpi_base);
686         process_sci_queue(0);   /* we just want to flush the queue here */
687         init_ebook_state();
688
689         /* Enable the interrupt */
690
691         ret = request_irq(sci_irq, &olpc_pm_interrupt, 0, "SCI", &acpi_base);
692
693         if (ret) {
694                 printk(KERN_ERR "Error registering SCI: %d\n", ret);
695                 return ret;
696         }
697
698         ofw_bios_entry.address = 0xF0000 + PAGE_OFFSET;
699         pm_set_ops(&olpc_pm_ops);
700
701         sysfs_create_group(&power_subsys.kobj, &olpc_attrs);
702
703         return 0;
704 }
705
706
707 #if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
708 struct resource rtc_platform_resource[2] = {
709         {
710                 .flags          = IORESOURCE_IO,
711                 .start          = RTC_PORT(0),
712                 .end            = RTC_PORT(0) + RTC_IO_EXTENT
713         },
714         {
715                 .flags = IORESOURCE_IRQ,
716                 .start = 8,
717                 .end = 8,
718         },
719 };
720
721
722 static void rtc_wake_on(struct device *dev)
723 {
724         olpc_wakeup_mask |= CS5536_PM_RTC;
725 }
726
727 static void rtc_wake_off(struct device *dev)
728 {
729         olpc_wakeup_mask &= ~(CS5536_PM_RTC);
730 }
731
732 static struct cmos_rtc_board_info rtc_info = {
733         .rtc_day_alarm = 0,
734         .rtc_mon_alarm = 0,
735         .rtc_century = 0,
736         .wake_on = rtc_wake_on,
737         .wake_off = rtc_wake_off,
738 };
739
740 struct platform_device olpc_rtc_device = {
741         .name = "rtc_cmos",
742         .id = -1,
743         .num_resources = ARRAY_SIZE(rtc_platform_resource),
744         .dev.platform_data = &rtc_info,
745         .resource = rtc_platform_resource,
746 };
747
748 static int __init olpc_platform_init(void)
749 {
750         (void)platform_device_register(&olpc_rtc_device);
751         device_init_wakeup(&olpc_rtc_device.dev, 1);
752
753         (void)platform_device_register(&olpc_powerbutton_dev);
754         device_init_wakeup(&olpc_powerbutton_dev.dev, 1);
755
756         (void)platform_device_register(&olpc_lid_dev);
757         device_init_wakeup(&olpc_lid_dev.dev, 1);
758
759         return 0;
760 }
761 arch_initcall(olpc_platform_init);
762 #endif /* CONFIG_RTC_DRV_CMOS */
763
764 static void olpc_pm_exit(void)
765 {
766         /* Clear any pending events, and disable them */
767         outl(0xFFFF, acpi_base+2);
768
769         free_irq(sci_irq, &acpi_base);
770         input_unregister_device(pm_inputdev);
771         input_unregister_device(lid_inputdev);
772         input_unregister_device(ebook_inputdev);
773 }
774
775 static struct pm_ops olpc_pm_ops = {
776         .valid = olpc_pm_state_valid,
777         .enter = olpc_pm_enter,
778 };
779
780 module_init(olpc_pm_init);
781 module_exit(olpc_pm_exit);
782
783 MODULE_LICENSE("GPL");
784 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
785 MODULE_DESCRIPTION("AMD Geode power management for OLPC CL1");