aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common/locomo.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/common/locomo.c')
-rw-r--r--arch/arm/common/locomo.c125
1 files changed, 113 insertions, 12 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 41f12658c8b4..2786f7c34b3f 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -177,7 +177,7 @@ static void locomo_handler(unsigned int irq, struct irqdesc *desc,
177 d = irq_desc + irq; 177 d = irq_desc + irq;
178 for (i = 0; i <= 3; i++, d++, irq++) { 178 for (i = 0; i <= 3; i++, d++, irq++) {
179 if (req & (0x0100 << i)) { 179 if (req & (0x0100 << i)) {
180 d->handle(irq, d, regs); 180 desc_handle_irq(irq, d, regs);
181 } 181 }
182 182
183 } 183 }
@@ -220,7 +220,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc,
220 220
221 if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { 221 if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
222 d = irq_desc + LOCOMO_IRQ_KEY_START; 222 d = irq_desc + LOCOMO_IRQ_KEY_START;
223 d->handle(LOCOMO_IRQ_KEY_START, d, regs); 223 desc_handle_irq(LOCOMO_IRQ_KEY_START, d, regs);
224 } 224 }
225} 225}
226 226
@@ -273,7 +273,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc,
273 d = irq_desc + LOCOMO_IRQ_GPIO_START; 273 d = irq_desc + LOCOMO_IRQ_GPIO_START;
274 for (i = 0; i <= 15; i++, irq++, d++) { 274 for (i = 0; i <= 15; i++, irq++, d++) {
275 if (req & (0x0001 << i)) { 275 if (req & (0x0001 << i)) {
276 d->handle(irq, d, regs); 276 desc_handle_irq(irq, d, regs);
277 } 277 }
278 } 278 }
279 } 279 }
@@ -328,7 +328,7 @@ static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc,
328 328
329 if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) { 329 if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
330 d = irq_desc + LOCOMO_IRQ_LT_START; 330 d = irq_desc + LOCOMO_IRQ_LT_START;
331 d->handle(LOCOMO_IRQ_LT_START, d, regs); 331 desc_handle_irq(LOCOMO_IRQ_LT_START, d, regs);
332 } 332 }
333} 333}
334 334
@@ -379,7 +379,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,
379 379
380 for (i = 0; i <= 3; i++, irq++, d++) { 380 for (i = 0; i <= 3; i++, irq++, d++) {
381 if (req & (0x0001 << i)) { 381 if (req & (0x0001 << i)) {
382 d->handle(irq, d, regs); 382 desc_handle_irq(irq, d, regs);
383 } 383 }
384 } 384 }
385 } 385 }
@@ -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
546struct 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
554static 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
601static 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.
@@ -651,15 +748,15 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
651 return ret; 748 return ret;
652} 749}
653 750
654static void __locomo_remove(struct locomo *lchip) 751static int locomo_remove_child(struct device *dev, void *data)
655{ 752{
656 struct list_head *l, *n; 753 device_unregister(dev);
657 754 return 0;
658 list_for_each_safe(l, n, &lchip->dev->children) { 755}
659 struct device *d = list_to_dev(l);
660 756
661 device_unregister(d); 757static void __locomo_remove(struct locomo *lchip)
662 } 758{
759 device_for_each_child(lchip->dev, NULL, locomo_remove_child);
663 760
664 if (lchip->irq != NO_IRQ) { 761 if (lchip->irq != NO_IRQ) {
665 set_irq_chained_handler(lchip->irq, NULL); 762 set_irq_chained_handler(lchip->irq, NULL);
@@ -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/*