add broadcom b44 driver support
[openwrt.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");
This page took 0.078763 seconds and 5 git commands to generate.