3 * Portions also copyright 2006 Advanced Micro Devices, Inc.
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>
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
27 http://www.amd.com/files/connectivitysolutions/geode/geode_gx/34472D_CS5536_B1_specupdate.pdf
32 #define CS5536_PM_PWRBTN (1 << 8)
33 #define CS5536_PM_RTC (1 << 10)
35 #define GPIO_WAKEUP_EC (1 << 31)
36 #define GPIO_WAKEUP_LID (1 << 30)
38 #define PM_MODE_NORMAL 0
39 #define PM_MODE_TEST 1
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
46 extern void do_olpc_suspend_lowlevel(void);
49 unsigned long address
;
50 unsigned short segment
;
51 } ofw_bios_entry
= { 0, __KERNEL_CS
};
53 static int olpc_pm_mode
= PM_MODE_NORMAL
;
54 static unsigned long acpi_base
;
55 static unsigned long pms_base
;
57 static int olpc_lid_flag
;
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
;
64 static int gpio_wake_events
= 0;
65 static int ebook_state
= -1;
66 static u16 olpc_wakeup_mask
= 0;
68 struct platform_device olpc_powerbutton_dev
= {
69 .name
= "powerbutton",
73 struct platform_device olpc_lid_dev
= {
78 static void __init
init_ebook_state(void)
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");
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
);
91 static void (*battery_callback
)(unsigned long);
92 static DEFINE_SPINLOCK(battery_callback_lock
);
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
)
98 unsigned char data
= 0;
99 unsigned char battery_events
= 0;
103 ret
= olpc_ec_cmd(0x84, NULL
, 0, &data
, 1);
105 printk(KERN_DEBUG
"olpc-pm: SCI 0x%x received\n",
109 case EC_SCI_SRC_EMPTY
:
110 case EC_SCI_SRC_GAME
:
111 case EC_SCI_SRC_WLAN
:
112 /* we ignore these for now */
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
;
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
);
130 printk(KERN_ERR
"olpc-pm: Unknown SCI event 0x%x occurred!\n", data
);
133 } while (data
&& !ret
);
135 if (battery_events
&& battery_callback
&& propagate_events
) {
136 void (*cbk
)(unsigned long);
138 /* Older EC versions didn't distinguish between AC and battery
140 if (olpc_platform_info
.ecver
< 0x45)
141 battery_events
= EC_SCI_SRC_BATTERY
| EC_SCI_SRC_ACPWR
;
143 spin_lock(&battery_callback_lock
);
144 cbk
= battery_callback
;
145 spin_unlock(&battery_callback_lock
);
151 printk(KERN_WARNING
"Failed to clear SCI queue!\n");
154 static DECLARE_WORK(sci_work
, process_sci_queue
);
156 void olpc_register_battery_callback(void (*f
)(unsigned long))
158 spin_lock(&battery_callback_lock
);
159 battery_callback
= f
;
160 spin_unlock(&battery_callback_lock
);
162 EXPORT_SYMBOL_GPL(olpc_register_battery_callback
);
164 void olpc_deregister_battery_callback(void)
166 spin_lock(&battery_callback_lock
);
167 battery_callback
= NULL
;
168 spin_unlock(&battery_callback_lock
);
169 cancel_work_sync(&sci_work
);
171 EXPORT_SYMBOL_GPL(olpc_deregister_battery_callback
);
174 static int olpc_pm_interrupt(int irq
, void *id
)
176 uint32_t sts
, gpe
= 0;
178 sts
= inl(acpi_base
+ PM1_STS
);
179 outl(sts
| 0xFFFF, acpi_base
+ PM1_STS
);
181 if (olpc_get_rev() >= OLPC_REV_B2
) {
182 gpe
= inl(acpi_base
+ PM_GPE0_STS
);
183 outl(0xFFFFFFFF, acpi_base
+ PM_GPE0_STS
);
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
);
195 if (gpe
& GPIO_WAKEUP_EC
) {
196 geode_gpio_clear(OLPC_GPIO_ECSCI
, GPIO_NEGATIVE_EDGE_STS
);
197 schedule_work(&sci_work
);
200 if (gpe
& GPIO_WAKEUP_LID
) {
202 geode_gpio_clear(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
207 geode_gpio_clear(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_EN
);
209 geode_gpio_clear(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_EN
);
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
);
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
220 input_report_switch(lid_inputdev
, SW_LID
, olpc_lid_flag
);
221 input_sync(lid_inputdev
);
223 /* Swap the status */
224 olpc_lid_flag
= !olpc_lid_flag
;
227 geode_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_EN
);
229 geode_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_EN
);
231 /* re-enable the event */
232 geode_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
239 * For now, only support STR. We also don't support suspending on
240 * B1s, due to difficulties with the cafe FPGA.
242 static int olpc_pm_state_valid(suspend_state_t pm_state
)
244 if (pm_state
== PM_SUSPEND_MEM
&& olpc_rev_after(OLPC_REV_B1
))
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
257 extern void gxfb_flatpanel_control(int state
);
259 static u32 gpio_wakeup
[2];
260 static u64 irq_sources
[4];
261 static u64 mfgpt_irq_msr
, mfgpt_nr_msr
;
263 void olpc_fixup_wakeup(void)
265 u32 base
= geode_gpio_base();
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
273 outl((CS5536_PM_PWRBTN
<< 16) | 0xFFFF, acpi_base
+ PM1_STS
);
275 /* Enable the flatpanel sequencing as early as possible, because
276 it takes ~64ms to resume. This probably belongs in the firmware */
278 //gxfb_flatpanel_control(1);
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]);
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
);
290 /* Resture the MFGPT MSRs */
291 wrmsrl(MFGPT_IRQ_MSR
, mfgpt_irq_msr
);
292 wrmsrl(MFGPT_NR_MSR
, mfgpt_nr_msr
);
295 /* tell the wireless module to restart USB communication */
296 olpc_ec_cmd(0x24, NULL
, 0, NULL
, 0);
300 void olpc_fixup_sleep(void)
302 u32 base
= geode_gpio_base();
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
);
309 /* Save the Y and Z unrestricted sources */
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]);
316 /* Turn off the MFGPT timers on the way down */
318 for(i
= 0; i
< 8; i
++) {
319 u32 val
= geode_mfgpt_read(i
, MFGPT_REG_SETUP
);
321 if (val
& MFGPT_SETUP_SETUP
) {
322 val
&= ~MFGPT_SETUP_CNTEN
;
323 geode_mfgpt_write(i
, MFGPT_REG_SETUP
, val
);
327 /* Save the MFGPT MSRs */
328 rdmsrl(MFGPT_IRQ_MSR
, mfgpt_irq_msr
);
329 rdmsrl(MFGPT_NR_MSR
, mfgpt_nr_msr
);
331 if (device_may_wakeup(&olpc_powerbutton_dev
.dev
))
332 olpc_wakeup_mask
|= CS5536_PM_PWRBTN
;
334 olpc_wakeup_mask
&= ~(CS5536_PM_PWRBTN
);
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
;
340 geode_gpio_clear(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
341 gpio_wake_events
&= ~(GPIO_WAKEUP_LID
);
345 static int olpc_pm_enter(suspend_state_t pm_state
)
347 /* Only STR is supported */
348 if (pm_state
!= PM_SUSPEND_MEM
)
353 /* Set the GPIO wakeup bits */
354 outl(gpio_wake_events
, acpi_base
+ PM_GPE0_EN
);
355 outl(0xFFFFFFFF, acpi_base
+ PM_GPE0_STS
);
358 do_olpc_suspend_lowlevel();
362 /* Restore the SCI wakeup events */
363 outl(gpio_wake_events
, acpi_base
+ PM_GPE0_EN
);
368 int asmlinkage
olpc_do_sleep(u8 sleep_state
)
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
374 /* FIXME: Set the SCI bits we want to wake up on here */
376 /* FIXME: Set any other SCI events that we might want here */
378 outl((olpc_wakeup_mask
<< 16) | 0xFFFF, acpi_base
+ PM1_STS
);
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 */
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
));
393 /* This code will slowly disappear as we fixup the issues in the BIOS */
395 static void __init
olpc_fixup_bios(void)
397 unsigned long hi
, lo
;
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.
405 /* Change the PM registers to decode to the DD */
407 rdmsr(0x510100e2, lo
, hi
);
409 wrmsr(0x510100e2, lo
, hi
);
411 /* Change the ACPI registers to decode to the DD */
413 rdmsr(0x510100e3, lo
, hi
);
415 wrmsr(0x510100e3, lo
, hi
);
418 /* GPIO24 controls WORK_AUX */
420 geode_gpio_set(OLPC_GPIO_WORKAUX
, GPIO_OUTPUT_ENABLE
);
421 geode_gpio_set(OLPC_GPIO_WORKAUX
, GPIO_OUTPUT_AUX1
);
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
);
428 /* Set up to get LID events */
429 geode_gpio_set(OLPC_GPIO_LID
, GPIO_INPUT_ENABLE
);
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
);
436 geode_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_STS
);
437 geode_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_STS
);
439 /* Set the LID to cause an PME event on group 6 */
440 geode_gpio_event_pme(OLPC_GPIO_LID
, 6);
442 /* Set PME group 6 to fire the SCI interrupt */
443 geode_gpio_set_irq(6, sci_irq
);
446 geode_gpio_set(OLPC_GPIO_ECSCI
, GPIO_INPUT_ENABLE
);
448 /* Clear pending events */
450 geode_gpio_set(OLPC_GPIO_ECSCI
, GPIO_NEGATIVE_EDGE_STS
);
451 geode_gpio_set(OLPC_GPIO_ECSCI
, GPIO_POSITIVE_EDGE_STS
);
453 //geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_EN);
454 geode_gpio_set(OLPC_GPIO_ECSCI
, GPIO_EVENTS_ENABLE
);
456 /* Set the SCI to cause a PME event on group 7 */
457 geode_gpio_event_pme(OLPC_GPIO_ECSCI
, 7);
459 /* And have group 6 also fire the SCI interrupt */
460 geode_gpio_set_irq(7, sci_irq
);
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
469 static const char * const pm_states
[] = {
470 [PM_MODE_NORMAL
] = "normal",
471 [PM_MODE_TEST
] = "test",
474 extern struct mutex pm_mutex
;
475 extern struct kset power_subsys
;
477 static ssize_t
control_show(struct kset
*s
, char *buf
)
479 return sprintf(buf
, "%s\n", pm_states
[olpc_pm_mode
]);
482 static ssize_t
control_store(struct kset
*s
, const char *buf
, size_t n
)
487 p
= memchr(buf
, '\n', n
);
488 len
= p
? p
- buf
: n
;
491 mutex_lock(&pm_mutex
);
493 for(i
= 0; i
< PM_MODE_MAX
; i
++) {
494 if (!strncmp(buf
, pm_states
[i
], len
)) {
500 mutex_unlock(&pm_mutex
);
502 return (i
== PM_MODE_MAX
) ? -EINVAL
: n
;
505 static struct subsys_attribute control_attr
= {
510 .show
= control_show
,
511 .store
= control_store
,
514 static struct attribute
* olpc_attributes
[] = {
519 static struct attribute_group olpc_attrs
= {
520 .attrs
= olpc_attributes
,
523 static int __init
alloc_inputdevs(void)
527 pm_inputdev
= input_allocate_device();
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
);
536 ret
= input_register_device(pm_inputdev
);
538 printk(KERN_ERR
"olpc-pm: failed to register PM input device: %d\n", ret
);
542 lid_inputdev
= input_allocate_device();
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
);
551 ret
= input_register_device(lid_inputdev
);
553 printk(KERN_ERR
"olpc-pm: failed to register lid input device: %d\n", ret
);
557 ebook_inputdev
= input_allocate_device();
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
);
566 ret
= input_register_device(ebook_inputdev
);
568 printk(KERN_ERR
"olpc-pm: failed to register ebook input device: %d\n", ret
);
574 if (ebook_inputdev
) {
575 input_unregister_device(ebook_inputdev
);
576 ebook_inputdev
= NULL
;
579 input_unregister_device(lid_inputdev
);
583 input_unregister_device(pm_inputdev
);
590 static int __init
olpc_pm_init(void)
596 if (!machine_is_olpc())
599 acpi_base
= geode_acpi_base();
600 pms_base
= geode_pms_base();
602 if (!acpi_base
|| !pms_base
)
605 ret
= alloc_inputdevs();
609 rdmsr(0x51400020, lo
, hi
);
610 sci_irq
= (lo
>> 20) & 15;
613 printk(KERN_INFO
"SCI is mapped to IRQ %d\n", sci_irq
);
615 /* Zero doesn't mean zero -- it means masked */
616 printk(KERN_INFO
"SCI unmapped. Mapping to IRQ 3\n");
619 wrmsrl(0x51400020, lo
);
624 lo
= inl(pms_base
+ PM_FSD
);
626 /* Lock, enable failsafe, 4 seconds */
627 outl(0xc001f400, pms_base
+ PM_FSD
);
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
634 outl(inl(acpi_base
) | ((CS5536_PM_PWRBTN
) << 16), acpi_base
);
636 if (olpc_get_rev() >= OLPC_REV_B2
) {
637 gpio_wake_events
|= GPIO_WAKEUP_LID
;
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
);
642 /* Watch for the opposite edge */
645 geode_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_EN
);
647 geode_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_EN
);
649 /* Enable the event */
650 geode_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
653 /* Set up the mask for wakeups the EC will generate SCIs on */
655 ret
= olpc_ec_cmd(EC_READ_SCI_MASK
, NULL
, 0, &ec_byte
, 1);
657 printk(KERN_ERR
"Error getting the EC SCI mask: %d\n", ret
);
659 /* Disable battery 1% charge wakeups */
660 ec_byte
&= ~EC_SCI_SRC_BATSOC
;
662 ret
= olpc_ec_cmd(EC_WRITE_SCI_MASK
, &ec_byte
, 1, NULL
, 0);
664 printk(KERN_ERR
"Error setting the EC SCI mask: %d\n", ret
);
666 /* Set up the EC SCI */
668 gpio_wake_events
|= GPIO_WAKEUP_EC
;
670 outl(gpio_wake_events
, acpi_base
+ PM_GPE0_EN
);
671 outl(0xFFFFFFFF, acpi_base
+ PM_GPE0_STS
);
673 /* Select level triggered in PIC */
681 lo
|= 1 << (sci_irq
- 8);
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 */
689 /* Enable the interrupt */
691 ret
= request_irq(sci_irq
, &olpc_pm_interrupt
, 0, "SCI", &acpi_base
);
694 printk(KERN_ERR
"Error registering SCI: %d\n", ret
);
698 ofw_bios_entry
.address
= 0xF0000 + PAGE_OFFSET
;
699 pm_set_ops(&olpc_pm_ops
);
701 sysfs_create_group(&power_subsys
.kobj
, &olpc_attrs
);
707 #if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
708 struct resource rtc_platform_resource
[2] = {
710 .flags
= IORESOURCE_IO
,
711 .start
= RTC_PORT(0),
712 .end
= RTC_PORT(0) + RTC_IO_EXTENT
715 .flags
= IORESOURCE_IRQ
,
722 static void rtc_wake_on(struct device
*dev
)
724 olpc_wakeup_mask
|= CS5536_PM_RTC
;
727 static void rtc_wake_off(struct device
*dev
)
729 olpc_wakeup_mask
&= ~(CS5536_PM_RTC
);
732 static struct cmos_rtc_board_info rtc_info
= {
736 .wake_on
= rtc_wake_on
,
737 .wake_off
= rtc_wake_off
,
740 struct platform_device olpc_rtc_device
= {
743 .num_resources
= ARRAY_SIZE(rtc_platform_resource
),
744 .dev
.platform_data
= &rtc_info
,
745 .resource
= rtc_platform_resource
,
748 static int __init
olpc_platform_init(void)
750 (void)platform_device_register(&olpc_rtc_device
);
751 device_init_wakeup(&olpc_rtc_device
.dev
, 1);
753 (void)platform_device_register(&olpc_powerbutton_dev
);
754 device_init_wakeup(&olpc_powerbutton_dev
.dev
, 1);
756 (void)platform_device_register(&olpc_lid_dev
);
757 device_init_wakeup(&olpc_lid_dev
.dev
, 1);
761 arch_initcall(olpc_platform_init
);
762 #endif /* CONFIG_RTC_DRV_CMOS */
764 static void olpc_pm_exit(void)
766 /* Clear any pending events, and disable them */
767 outl(0xFFFF, acpi_base
+2);
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
);
775 static struct pm_ops olpc_pm_ops
= {
776 .valid
= olpc_pm_state_valid
,
777 .enter
= olpc_pm_enter
,
780 module_init(olpc_pm_init
);
781 module_exit(olpc_pm_exit
);
783 MODULE_LICENSE("GPL");
784 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
785 MODULE_DESCRIPTION("AMD Geode power management for OLPC CL1");