diff options
| -rw-r--r-- | arch/arm/plat-s3c24xx/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/plat-s3c24xx/include/plat/irq.h | 8 | ||||
| -rw-r--r-- | arch/arm/plat-s3c24xx/irq-pm.c | 116 | ||||
| -rw-r--r-- | arch/arm/plat-s3c24xx/irq.c | 118 |
4 files changed, 125 insertions, 118 deletions
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 1e0767b266b8..636cb12711df 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile | |||
| @@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o | |||
| 27 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o | 27 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o |
| 28 | obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o | 28 | obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o |
| 29 | obj-$(CONFIG_PM) += pm.o | 29 | obj-$(CONFIG_PM) += pm.o |
| 30 | obj-$(CONFIG_PM) += irq-pm.o | ||
| 30 | obj-$(CONFIG_PM) += sleep.o | 31 | obj-$(CONFIG_PM) += sleep.o |
| 31 | obj-$(CONFIG_HAVE_PWM) += pwm.o | 32 | obj-$(CONFIG_HAVE_PWM) += pwm.o |
| 32 | obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o | 33 | obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o |
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h index 45746a995343..97b6884ea0dc 100644 --- a/arch/arm/plat-s3c24xx/include/plat/irq.h +++ b/arch/arm/plat-s3c24xx/include/plat/irq.h | |||
| @@ -10,6 +10,12 @@ | |||
| 10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/io.h> | ||
| 14 | |||
| 15 | #include <mach/hardware.h> | ||
| 16 | #include <mach/regs-irq.h> | ||
| 17 | #include <mach/regs-gpio.h> | ||
| 18 | |||
| 13 | #define irqdbf(x...) | 19 | #define irqdbf(x...) |
| 14 | #define irqdbf2(x...) | 20 | #define irqdbf2(x...) |
| 15 | 21 | ||
| @@ -102,7 +108,9 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group) | |||
| 102 | 108 | ||
| 103 | #ifdef CONFIG_PM | 109 | #ifdef CONFIG_PM |
| 104 | extern int s3c_irq_wake(unsigned int irqno, unsigned int state); | 110 | extern int s3c_irq_wake(unsigned int irqno, unsigned int state); |
| 111 | extern int s3c_irqext_wake(unsigned int irqno, unsigned int state); | ||
| 105 | #else | 112 | #else |
| 113 | #define s3c_irqext_wake NULL | ||
| 106 | #define s3c_irq_wake NULL | 114 | #define s3c_irq_wake NULL |
| 107 | #endif | 115 | #endif |
| 108 | 116 | ||
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/plat-s3c24xx/irq-pm.c new file mode 100644 index 000000000000..86c68804f098 --- /dev/null +++ b/arch/arm/plat-s3c24xx/irq-pm.c | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/irq-om.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2003,2004 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C24XX - IRQ PM code | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/sysdev.h> | ||
| 18 | |||
| 19 | #include <plat/cpu.h> | ||
| 20 | #include <plat/pm.h> | ||
| 21 | #include <plat/irq.h> | ||
| 22 | |||
| 23 | /* state for IRQs over sleep */ | ||
| 24 | |||
| 25 | /* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources | ||
| 26 | * | ||
| 27 | * set bit to 1 in allow bitfield to enable the wakeup settings on it | ||
| 28 | */ | ||
| 29 | |||
| 30 | unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; | ||
| 31 | unsigned long s3c_irqwake_intmask = 0xffffffffL; | ||
| 32 | unsigned long s3c_irqwake_eintallow = 0x0000fff0L; | ||
| 33 | unsigned long s3c_irqwake_eintmask = 0xffffffffL; | ||
| 34 | |||
| 35 | int | ||
| 36 | s3c_irq_wake(unsigned int irqno, unsigned int state) | ||
| 37 | { | ||
| 38 | unsigned long irqbit = 1 << (irqno - IRQ_EINT0); | ||
| 39 | |||
| 40 | if (!(s3c_irqwake_intallow & irqbit)) | ||
| 41 | return -ENOENT; | ||
| 42 | |||
| 43 | printk(KERN_INFO "wake %s for irq %d\n", | ||
| 44 | state ? "enabled" : "disabled", irqno); | ||
| 45 | |||
| 46 | if (!state) | ||
| 47 | s3c_irqwake_intmask |= irqbit; | ||
| 48 | else | ||
| 49 | s3c_irqwake_intmask &= ~irqbit; | ||
| 50 | |||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | int s3c_irqext_wake(unsigned int irqno, unsigned int state) | ||
| 55 | { | ||
| 56 | unsigned long bit = 1L << (irqno - EXTINT_OFF); | ||
| 57 | |||
| 58 | if (!(s3c_irqwake_eintallow & bit)) | ||
| 59 | return -ENOENT; | ||
| 60 | |||
| 61 | printk(KERN_INFO "wake %s for irq %d\n", | ||
| 62 | state ? "enabled" : "disabled", irqno); | ||
| 63 | |||
| 64 | if (!state) | ||
| 65 | s3c_irqwake_eintmask |= bit; | ||
| 66 | else | ||
| 67 | s3c_irqwake_eintmask &= ~bit; | ||
| 68 | |||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static struct sleep_save irq_save[] = { | ||
| 73 | SAVE_ITEM(S3C2410_INTMSK), | ||
| 74 | SAVE_ITEM(S3C2410_INTSUBMSK), | ||
| 75 | }; | ||
| 76 | |||
| 77 | /* the extint values move between the s3c2410/s3c2440 and the s3c2412 | ||
| 78 | * so we use an array to hold them, and to calculate the address of | ||
| 79 | * the register at run-time | ||
| 80 | */ | ||
| 81 | |||
| 82 | static unsigned long save_extint[3]; | ||
| 83 | static unsigned long save_eintflt[4]; | ||
| 84 | static unsigned long save_eintmask; | ||
| 85 | |||
| 86 | int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state) | ||
| 87 | { | ||
| 88 | unsigned int i; | ||
| 89 | |||
| 90 | for (i = 0; i < ARRAY_SIZE(save_extint); i++) | ||
| 91 | save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); | ||
| 92 | |||
| 93 | for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) | ||
| 94 | save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); | ||
| 95 | |||
| 96 | s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); | ||
| 97 | save_eintmask = __raw_readl(S3C24XX_EINTMASK); | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | int s3c24xx_irq_resume(struct sys_device *dev) | ||
| 103 | { | ||
| 104 | unsigned int i; | ||
| 105 | |||
| 106 | for (i = 0; i < ARRAY_SIZE(save_extint); i++) | ||
| 107 | __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); | ||
| 108 | |||
| 109 | for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) | ||
| 110 | __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); | ||
| 111 | |||
| 112 | s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); | ||
| 113 | __raw_writel(save_eintmask, S3C24XX_EINTMASK); | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | } | ||
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index 2fa8c9f4b354..33fde662ce6d 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c | |||
| @@ -55,81 +55,16 @@ | |||
| 55 | #include <linux/interrupt.h> | 55 | #include <linux/interrupt.h> |
| 56 | #include <linux/ioport.h> | 56 | #include <linux/ioport.h> |
| 57 | #include <linux/sysdev.h> | 57 | #include <linux/sysdev.h> |
| 58 | #include <linux/io.h> | ||
| 59 | 58 | ||
| 60 | #include <mach/hardware.h> | ||
| 61 | #include <asm/irq.h> | 59 | #include <asm/irq.h> |
| 62 | |||
| 63 | #include <asm/mach/irq.h> | 60 | #include <asm/mach/irq.h> |
| 64 | 61 | ||
| 65 | #include <plat/regs-irqtype.h> | 62 | #include <plat/regs-irqtype.h> |
| 66 | #include <mach/regs-irq.h> | ||
| 67 | #include <mach/regs-gpio.h> | ||
| 68 | 63 | ||
| 69 | #include <plat/cpu.h> | 64 | #include <plat/cpu.h> |
| 70 | #include <plat/pm.h> | 65 | #include <plat/pm.h> |
| 71 | #include <plat/irq.h> | 66 | #include <plat/irq.h> |
| 72 | 67 | ||
| 73 | /* wakeup irq control */ | ||
| 74 | |||
| 75 | #ifdef CONFIG_PM | ||
| 76 | |||
| 77 | /* state for IRQs over sleep */ | ||
| 78 | |||
| 79 | /* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources | ||
| 80 | * | ||
| 81 | * set bit to 1 in allow bitfield to enable the wakeup settings on it | ||
| 82 | */ | ||
| 83 | |||
| 84 | unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; | ||
| 85 | unsigned long s3c_irqwake_intmask = 0xffffffffL; | ||
| 86 | unsigned long s3c_irqwake_eintallow = 0x0000fff0L; | ||
| 87 | unsigned long s3c_irqwake_eintmask = 0xffffffffL; | ||
| 88 | |||
| 89 | int | ||
| 90 | s3c_irq_wake(unsigned int irqno, unsigned int state) | ||
| 91 | { | ||
| 92 | unsigned long irqbit = 1 << (irqno - IRQ_EINT0); | ||
| 93 | |||
| 94 | if (!(s3c_irqwake_intallow & irqbit)) | ||
| 95 | return -ENOENT; | ||
| 96 | |||
| 97 | printk(KERN_INFO "wake %s for irq %d\n", | ||
| 98 | state ? "enabled" : "disabled", irqno); | ||
| 99 | |||
| 100 | if (!state) | ||
| 101 | s3c_irqwake_intmask |= irqbit; | ||
| 102 | else | ||
| 103 | s3c_irqwake_intmask &= ~irqbit; | ||
| 104 | |||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int | ||
| 109 | s3c_irqext_wake(unsigned int irqno, unsigned int state) | ||
| 110 | { | ||
| 111 | unsigned long bit = 1L << (irqno - EXTINT_OFF); | ||
| 112 | |||
| 113 | if (!(s3c_irqwake_eintallow & bit)) | ||
| 114 | return -ENOENT; | ||
| 115 | |||
| 116 | printk(KERN_INFO "wake %s for irq %d\n", | ||
| 117 | state ? "enabled" : "disabled", irqno); | ||
| 118 | |||
| 119 | if (!state) | ||
| 120 | s3c_irqwake_eintmask |= bit; | ||
| 121 | else | ||
| 122 | s3c_irqwake_eintmask &= ~bit; | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | #else | ||
| 128 | #define s3c_irqext_wake NULL | ||
| 129 | #define s3c_irq_wake NULL | ||
| 130 | #endif | ||
| 131 | |||
| 132 | |||
| 133 | static void | 68 | static void |
| 134 | s3c_irq_mask(unsigned int irqno) | 69 | s3c_irq_mask(unsigned int irqno) |
| 135 | { | 70 | { |
| @@ -590,59 +525,6 @@ s3c_irq_demux_extint4t7(unsigned int irq, | |||
| 590 | } | 525 | } |
| 591 | } | 526 | } |
| 592 | 527 | ||
| 593 | #ifdef CONFIG_PM | ||
| 594 | |||
| 595 | static struct sleep_save irq_save[] = { | ||
| 596 | SAVE_ITEM(S3C2410_INTMSK), | ||
| 597 | SAVE_ITEM(S3C2410_INTSUBMSK), | ||
| 598 | }; | ||
| 599 | |||
| 600 | /* the extint values move between the s3c2410/s3c2440 and the s3c2412 | ||
| 601 | * so we use an array to hold them, and to calculate the address of | ||
| 602 | * the register at run-time | ||
| 603 | */ | ||
| 604 | |||
| 605 | static unsigned long save_extint[3]; | ||
| 606 | static unsigned long save_eintflt[4]; | ||
| 607 | static unsigned long save_eintmask; | ||
| 608 | |||
| 609 | int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state) | ||
| 610 | { | ||
| 611 | unsigned int i; | ||
| 612 | |||
| 613 | for (i = 0; i < ARRAY_SIZE(save_extint); i++) | ||
| 614 | save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); | ||
| 615 | |||
| 616 | for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) | ||
| 617 | save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); | ||
| 618 | |||
| 619 | s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); | ||
| 620 | save_eintmask = __raw_readl(S3C24XX_EINTMASK); | ||
| 621 | |||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | |||
| 625 | int s3c24xx_irq_resume(struct sys_device *dev) | ||
| 626 | { | ||
| 627 | unsigned int i; | ||
| 628 | |||
| 629 | for (i = 0; i < ARRAY_SIZE(save_extint); i++) | ||
| 630 | __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); | ||
| 631 | |||
| 632 | for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) | ||
| 633 | __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); | ||
| 634 | |||
| 635 | s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); | ||
| 636 | __raw_writel(save_eintmask, S3C24XX_EINTMASK); | ||
| 637 | |||
| 638 | return 0; | ||
| 639 | } | ||
| 640 | |||
| 641 | #else | ||
| 642 | #define s3c24xx_irq_suspend NULL | ||
| 643 | #define s3c24xx_irq_resume NULL | ||
| 644 | #endif | ||
| 645 | |||
| 646 | /* s3c24xx_init_irq | 528 | /* s3c24xx_init_irq |
| 647 | * | 529 | * |
| 648 | * Initialise S3C2410 IRQ system | 530 | * Initialise S3C2410 IRQ system |
