diff options
Diffstat (limited to 'arch/arm/common/locomo.c')
-rw-r--r-- | arch/arm/common/locomo.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 51f430cc2fbf..2786f7c34b3f 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c | |||
@@ -541,6 +541,103 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info) | |||
541 | return ret; | 541 | return ret; |
542 | } | 542 | } |
543 | 543 | ||
544 | #ifdef CONFIG_PM | ||
545 | |||
546 | struct locomo_save_data { | ||
547 | u16 LCM_GPO; | ||
548 | u16 LCM_SPICT; | ||
549 | u16 LCM_GPE; | ||
550 | u16 LCM_ASD; | ||
551 | u16 LCM_SPIMD; | ||
552 | }; | ||
553 | |||
554 | static int locomo_suspend(struct device *dev, u32 pm_message_t, u32 level) | ||
555 | { | ||
556 | struct locomo *lchip = dev_get_drvdata(dev); | ||
557 | struct locomo_save_data *save; | ||
558 | unsigned long flags; | ||
559 | |||
560 | if (level != SUSPEND_DISABLE) | ||
561 | return 0; | ||
562 | |||
563 | save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL); | ||
564 | if (!save) | ||
565 | return -ENOMEM; | ||
566 | |||
567 | dev->power.saved_state = (void *) save; | ||
568 | |||
569 | spin_lock_irqsave(&lchip->lock, flags); | ||
570 | |||
571 | save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */ | ||
572 | locomo_writel(0x00, lchip->base + LOCOMO_GPO); | ||
573 | save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPICT); /* SPI */ | ||
574 | locomo_writel(0x40, lchip->base + LOCOMO_SPICT); | ||
575 | save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */ | ||
576 | locomo_writel(0x00, lchip->base + LOCOMO_GPE); | ||
577 | save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */ | ||
578 | locomo_writel(0x00, lchip->base + LOCOMO_ASD); | ||
579 | save->LCM_SPIMD = locomo_readl(lchip->base + LOCOMO_SPIMD); /* SPI */ | ||
580 | locomo_writel(0x3C14, lchip->base + LOCOMO_SPIMD); | ||
581 | |||
582 | locomo_writel(0x00, lchip->base + LOCOMO_PAIF); | ||
583 | locomo_writel(0x00, lchip->base + LOCOMO_DAC); | ||
584 | locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC); | ||
585 | |||
586 | if ( (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88) ) | ||
587 | locomo_writel(0x00, lchip->base + LOCOMO_C32K); /* CLK32 off */ | ||
588 | else | ||
589 | /* 18MHz already enabled, so no wait */ | ||
590 | locomo_writel(0xc1, lchip->base + LOCOMO_C32K); /* CLK32 on */ | ||
591 | |||
592 | locomo_writel(0x00, lchip->base + LOCOMO_TADC); /* 18MHz clock off*/ | ||
593 | locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC); /* 22MHz/24MHz clock off */ | ||
594 | locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); /* FL */ | ||
595 | |||
596 | spin_unlock_irqrestore(&lchip->lock, flags); | ||
597 | |||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static int locomo_resume(struct device *dev, u32 level) | ||
602 | { | ||
603 | struct locomo *lchip = dev_get_drvdata(dev); | ||
604 | struct locomo_save_data *save; | ||
605 | unsigned long r; | ||
606 | unsigned long flags; | ||
607 | |||
608 | if (level != RESUME_ENABLE) | ||
609 | return 0; | ||
610 | |||
611 | save = (struct locomo_save_data *) dev->power.saved_state; | ||
612 | if (!save) | ||
613 | return 0; | ||
614 | |||
615 | spin_lock_irqsave(&lchip->lock, flags); | ||
616 | |||
617 | locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO); | ||
618 | locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPICT); | ||
619 | locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE); | ||
620 | locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD); | ||
621 | locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPIMD); | ||
622 | |||
623 | locomo_writel(0x00, lchip->base + LOCOMO_C32K); | ||
624 | locomo_writel(0x90, lchip->base + LOCOMO_TADC); | ||
625 | |||
626 | locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC); | ||
627 | r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
628 | r &= 0xFEFF; | ||
629 | locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
630 | locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD); | ||
631 | |||
632 | spin_unlock_irqrestore(&lchip->lock, flags); | ||
633 | |||
634 | dev->power.saved_state = NULL; | ||
635 | kfree(save); | ||
636 | |||
637 | return 0; | ||
638 | } | ||
639 | #endif | ||
640 | |||
544 | /** | 641 | /** |
545 | * locomo_probe - probe for a single LoCoMo chip. | 642 | * locomo_probe - probe for a single LoCoMo chip. |
546 | * @phys_addr: physical address of device. | 643 | * @phys_addr: physical address of device. |
@@ -707,6 +804,10 @@ static struct device_driver locomo_device_driver = { | |||
707 | .bus = &platform_bus_type, | 804 | .bus = &platform_bus_type, |
708 | .probe = locomo_probe, | 805 | .probe = locomo_probe, |
709 | .remove = locomo_remove, | 806 | .remove = locomo_remove, |
807 | #ifdef CONFIG_PM | ||
808 | .suspend = locomo_suspend, | ||
809 | .resume = locomo_resume, | ||
810 | #endif | ||
710 | }; | 811 | }; |
711 | 812 | ||
712 | /* | 813 | /* |