diff options
| -rw-r--r-- | arch/arm/mach-s3c64xx/irq-eint.c | 37 | ||||
| -rw-r--r-- | arch/arm/mach-s5pv310/irq-eint.c | 2 | ||||
| -rw-r--r-- | arch/arm/plat-s3c24xx/irq.c | 2 | ||||
| -rw-r--r-- | arch/arm/plat-s5p/irq-eint.c | 4 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/Kconfig | 8 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/Makefile | 4 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/include/plat/pd.h | 30 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/include/plat/pm.h | 4 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/irq-uart.c | 36 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/irq-vic-timer.c | 22 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/pd.c | 95 | ||||
| -rw-r--r-- | arch/arm/plat-samsung/pm.c | 6 |
12 files changed, 197 insertions, 53 deletions
diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c index 5682d6a7f4af..2ead8189da74 100644 --- a/arch/arm/mach-s3c64xx/irq-eint.c +++ b/arch/arm/mach-s3c64xx/irq-eint.c | |||
| @@ -30,41 +30,41 @@ | |||
| 30 | #include <plat/pm.h> | 30 | #include <plat/pm.h> |
| 31 | 31 | ||
| 32 | #define eint_offset(irq) ((irq) - IRQ_EINT(0)) | 32 | #define eint_offset(irq) ((irq) - IRQ_EINT(0)) |
| 33 | #define eint_irq_to_bit(irq) (1 << eint_offset(irq)) | 33 | #define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq))) |
| 34 | 34 | ||
| 35 | static inline void s3c_irq_eint_mask(unsigned int irq) | 35 | static inline void s3c_irq_eint_mask(struct irq_data *data) |
| 36 | { | 36 | { |
| 37 | u32 mask; | 37 | u32 mask; |
| 38 | 38 | ||
| 39 | mask = __raw_readl(S3C64XX_EINT0MASK); | 39 | mask = __raw_readl(S3C64XX_EINT0MASK); |
| 40 | mask |= eint_irq_to_bit(irq); | 40 | mask |= (u32)data->chip_data; |
| 41 | __raw_writel(mask, S3C64XX_EINT0MASK); | 41 | __raw_writel(mask, S3C64XX_EINT0MASK); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | static void s3c_irq_eint_unmask(unsigned int irq) | 44 | static void s3c_irq_eint_unmask(struct irq_data *data) |
| 45 | { | 45 | { |
| 46 | u32 mask; | 46 | u32 mask; |
| 47 | 47 | ||
| 48 | mask = __raw_readl(S3C64XX_EINT0MASK); | 48 | mask = __raw_readl(S3C64XX_EINT0MASK); |
| 49 | mask &= ~eint_irq_to_bit(irq); | 49 | mask &= ~((u32)data->chip_data); |
| 50 | __raw_writel(mask, S3C64XX_EINT0MASK); | 50 | __raw_writel(mask, S3C64XX_EINT0MASK); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | static inline void s3c_irq_eint_ack(unsigned int irq) | 53 | static inline void s3c_irq_eint_ack(struct irq_data *data) |
| 54 | { | 54 | { |
| 55 | __raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND); | 55 | __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static void s3c_irq_eint_maskack(unsigned int irq) | 58 | static void s3c_irq_eint_maskack(struct irq_data *data) |
| 59 | { | 59 | { |
| 60 | /* compiler should in-line these */ | 60 | /* compiler should in-line these */ |
| 61 | s3c_irq_eint_mask(irq); | 61 | s3c_irq_eint_mask(data); |
| 62 | s3c_irq_eint_ack(irq); | 62 | s3c_irq_eint_ack(data); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) | 65 | static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type) |
| 66 | { | 66 | { |
| 67 | int offs = eint_offset(irq); | 67 | int offs = eint_offset(data->irq); |
| 68 | int pin, pin_val; | 68 | int pin, pin_val; |
| 69 | int shift; | 69 | int shift; |
| 70 | u32 ctrl, mask; | 70 | u32 ctrl, mask; |
| @@ -140,12 +140,12 @@ static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) | |||
| 140 | 140 | ||
| 141 | static struct irq_chip s3c_irq_eint = { | 141 | static struct irq_chip s3c_irq_eint = { |
| 142 | .name = "s3c-eint", | 142 | .name = "s3c-eint", |
| 143 | .mask = s3c_irq_eint_mask, | 143 | .irq_mask = s3c_irq_eint_mask, |
| 144 | .unmask = s3c_irq_eint_unmask, | 144 | .irq_unmask = s3c_irq_eint_unmask, |
| 145 | .mask_ack = s3c_irq_eint_maskack, | 145 | .irq_mask_ack = s3c_irq_eint_maskack, |
| 146 | .ack = s3c_irq_eint_ack, | 146 | .irq_ack = s3c_irq_eint_ack, |
| 147 | .set_type = s3c_irq_eint_set_type, | 147 | .irq_set_type = s3c_irq_eint_set_type, |
| 148 | .set_wake = s3c_irqext_wake, | 148 | .irq_set_wake = s3c_irqext_wake, |
| 149 | }; | 149 | }; |
| 150 | 150 | ||
| 151 | /* s3c_irq_demux_eint | 151 | /* s3c_irq_demux_eint |
| @@ -198,6 +198,7 @@ static int __init s3c64xx_init_irq_eint(void) | |||
| 198 | 198 | ||
| 199 | for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { | 199 | for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { |
| 200 | set_irq_chip(irq, &s3c_irq_eint); | 200 | set_irq_chip(irq, &s3c_irq_eint); |
| 201 | set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq)); | ||
| 201 | set_irq_handler(irq, handle_level_irq); | 202 | set_irq_handler(irq, handle_level_irq); |
| 202 | set_irq_flags(irq, IRQF_VALID); | 203 | set_irq_flags(irq, IRQF_VALID); |
| 203 | } | 204 | } |
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c index 5877503e92c3..f5a415edc0b6 100644 --- a/arch/arm/mach-s5pv310/irq-eint.c +++ b/arch/arm/mach-s5pv310/irq-eint.c | |||
| @@ -152,7 +152,7 @@ static struct irq_chip s5pv310_irq_eint = { | |||
| 152 | .ack = s5pv310_irq_eint_ack, | 152 | .ack = s5pv310_irq_eint_ack, |
| 153 | .set_type = s5pv310_irq_eint_set_type, | 153 | .set_type = s5pv310_irq_eint_set_type, |
| 154 | #ifdef CONFIG_PM | 154 | #ifdef CONFIG_PM |
| 155 | .set_wake = s3c_irqext_wake, | 155 | .irq_set_wake = s3c_irqext_wake, |
| 156 | #endif | 156 | #endif |
| 157 | }; | 157 | }; |
| 158 | 158 | ||
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index ad0d44ef1f93..91ce38393ba6 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c | |||
| @@ -238,7 +238,7 @@ static struct irq_chip s3c_irqext_chip = { | |||
| 238 | .unmask = s3c_irqext_unmask, | 238 | .unmask = s3c_irqext_unmask, |
| 239 | .ack = s3c_irqext_ack, | 239 | .ack = s3c_irqext_ack, |
| 240 | .set_type = s3c_irqext_type, | 240 | .set_type = s3c_irqext_type, |
| 241 | .set_wake = s3c_irqext_wake | 241 | .irq_set_wake = s3c_irqext_wake |
| 242 | }; | 242 | }; |
| 243 | 243 | ||
| 244 | static struct irq_chip s3c_irq_eint0t4 = { | 244 | static struct irq_chip s3c_irq_eint0t4 = { |
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index 752f1a645f9d..f2f2e1ccd0e6 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c | |||
| @@ -125,7 +125,7 @@ static struct irq_chip s5p_irq_eint = { | |||
| 125 | .ack = s5p_irq_eint_ack, | 125 | .ack = s5p_irq_eint_ack, |
| 126 | .set_type = s5p_irq_eint_set_type, | 126 | .set_type = s5p_irq_eint_set_type, |
| 127 | #ifdef CONFIG_PM | 127 | #ifdef CONFIG_PM |
| 128 | .set_wake = s3c_irqext_wake, | 128 | .irq_set_wake = s3c_irqext_wake, |
| 129 | #endif | 129 | #endif |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| @@ -194,7 +194,7 @@ static struct irq_chip s5p_irq_vic_eint = { | |||
| 194 | .ack = s5p_irq_vic_eint_ack, | 194 | .ack = s5p_irq_vic_eint_ack, |
| 195 | .set_type = s5p_irq_eint_set_type, | 195 | .set_type = s5p_irq_eint_set_type, |
| 196 | #ifdef CONFIG_PM | 196 | #ifdef CONFIG_PM |
| 197 | .set_wake = s3c_irqext_wake, | 197 | .irq_set_wake = s3c_irqext_wake, |
| 198 | #endif | 198 | #endif |
| 199 | }; | 199 | }; |
| 200 | 200 | ||
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index dcd6eff4ee53..2ebf4157d93a 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig | |||
| @@ -333,4 +333,12 @@ config SAMSUNG_WAKEMASK | |||
| 333 | and above. This code allows a set of interrupt to wakeup-mask | 333 | and above. This code allows a set of interrupt to wakeup-mask |
| 334 | mappings. See <plat/wakeup-mask.h> | 334 | mappings. See <plat/wakeup-mask.h> |
| 335 | 335 | ||
| 336 | comment "Power Domain" | ||
| 337 | |||
| 338 | config SAMSUNG_PD | ||
| 339 | bool "Samsung Power Domain" | ||
| 340 | depends on PM_RUNTIME | ||
| 341 | help | ||
| 342 | Say Y here if you want to control Power Domain by Runtime PM. | ||
| 343 | |||
| 336 | endif | 344 | endif |
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index afcce474af8e..09dbd78b56f5 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile | |||
| @@ -73,6 +73,10 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o | |||
| 73 | 73 | ||
| 74 | obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o | 74 | obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o |
| 75 | 75 | ||
| 76 | # PD support | ||
| 77 | |||
| 78 | obj-$(CONFIG_SAMSUNG_PD) += pd.o | ||
| 79 | |||
| 76 | # PWM support | 80 | # PWM support |
| 77 | 81 | ||
| 78 | obj-$(CONFIG_HAVE_PWM) += pwm.o | 82 | obj-$(CONFIG_HAVE_PWM) += pwm.o |
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h new file mode 100644 index 000000000000..5f0ad85783db --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pd.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/include/plat/pd.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __ASM_PLAT_SAMSUNG_PD_H | ||
| 12 | #define __ASM_PLAT_SAMSUNG_PD_H __FILE__ | ||
| 13 | |||
| 14 | struct samsung_pd_info { | ||
| 15 | int (*enable)(struct device *dev); | ||
| 16 | int (*disable)(struct device *dev); | ||
| 17 | void __iomem *base; | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum s5pv310_pd_block { | ||
| 21 | PD_MFC, | ||
| 22 | PD_G3D, | ||
| 23 | PD_LCD0, | ||
| 24 | PD_LCD1, | ||
| 25 | PD_TV, | ||
| 26 | PD_CAM, | ||
| 27 | PD_GPS | ||
| 28 | }; | ||
| 29 | |||
| 30 | #endif /* __ASM_PLAT_SAMSUNG_PD_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index 245836d91931..d9025e377675 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | * management | 15 | * management |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/irq.h> | ||
| 19 | |||
| 18 | #ifdef CONFIG_PM | 20 | #ifdef CONFIG_PM |
| 19 | 21 | ||
| 20 | extern __init int s3c_pm_init(void); | 22 | extern __init int s3c_pm_init(void); |
| @@ -100,7 +102,7 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count); | |||
| 100 | extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); | 102 | extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); |
| 101 | 103 | ||
| 102 | #ifdef CONFIG_PM | 104 | #ifdef CONFIG_PM |
| 103 | extern int s3c_irqext_wake(unsigned int irqno, unsigned int state); | 105 | extern int s3c_irqext_wake(struct irq_data *data, unsigned int state); |
| 104 | extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); | 106 | extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); |
| 105 | extern int s3c24xx_irq_resume(struct sys_device *dev); | 107 | extern int s3c24xx_irq_resume(struct sys_device *dev); |
| 106 | #else | 108 | #else |
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c index 4f8c102674ae..da31d785cbd1 100644 --- a/arch/arm/plat-samsung/irq-uart.c +++ b/arch/arm/plat-samsung/irq-uart.c | |||
| @@ -28,9 +28,9 @@ | |||
| 28 | * are consecutive when looking up the interrupt in the demux routines. | 28 | * are consecutive when looking up the interrupt in the demux routines. |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | static inline void __iomem *s3c_irq_uart_base(unsigned int irq) | 31 | static inline void __iomem *s3c_irq_uart_base(struct irq_data *data) |
| 32 | { | 32 | { |
| 33 | struct s3c_uart_irq *uirq = get_irq_chip_data(irq); | 33 | struct s3c_uart_irq *uirq = data->chip_data; |
| 34 | return uirq->regs; | 34 | return uirq->regs; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| @@ -39,10 +39,10 @@ static inline unsigned int s3c_irq_uart_bit(unsigned int irq) | |||
| 39 | return irq & 3; | 39 | return irq & 3; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static void s3c_irq_uart_mask(unsigned int irq) | 42 | static void s3c_irq_uart_mask(struct irq_data *data) |
| 43 | { | 43 | { |
| 44 | void __iomem *regs = s3c_irq_uart_base(irq); | 44 | void __iomem *regs = s3c_irq_uart_base(data); |
| 45 | unsigned int bit = s3c_irq_uart_bit(irq); | 45 | unsigned int bit = s3c_irq_uart_bit(data->irq); |
| 46 | u32 reg; | 46 | u32 reg; |
| 47 | 47 | ||
| 48 | reg = __raw_readl(regs + S3C64XX_UINTM); | 48 | reg = __raw_readl(regs + S3C64XX_UINTM); |
| @@ -50,10 +50,10 @@ static void s3c_irq_uart_mask(unsigned int irq) | |||
| 50 | __raw_writel(reg, regs + S3C64XX_UINTM); | 50 | __raw_writel(reg, regs + S3C64XX_UINTM); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | static void s3c_irq_uart_maskack(unsigned int irq) | 53 | static void s3c_irq_uart_maskack(struct irq_data *data) |
| 54 | { | 54 | { |
| 55 | void __iomem *regs = s3c_irq_uart_base(irq); | 55 | void __iomem *regs = s3c_irq_uart_base(data); |
| 56 | unsigned int bit = s3c_irq_uart_bit(irq); | 56 | unsigned int bit = s3c_irq_uart_bit(data->irq); |
| 57 | u32 reg; | 57 | u32 reg; |
| 58 | 58 | ||
| 59 | reg = __raw_readl(regs + S3C64XX_UINTM); | 59 | reg = __raw_readl(regs + S3C64XX_UINTM); |
| @@ -62,10 +62,10 @@ static void s3c_irq_uart_maskack(unsigned int irq) | |||
| 62 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); | 62 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static void s3c_irq_uart_unmask(unsigned int irq) | 65 | static void s3c_irq_uart_unmask(struct irq_data *data) |
| 66 | { | 66 | { |
| 67 | void __iomem *regs = s3c_irq_uart_base(irq); | 67 | void __iomem *regs = s3c_irq_uart_base(data); |
| 68 | unsigned int bit = s3c_irq_uart_bit(irq); | 68 | unsigned int bit = s3c_irq_uart_bit(data->irq); |
| 69 | u32 reg; | 69 | u32 reg; |
| 70 | 70 | ||
| 71 | reg = __raw_readl(regs + S3C64XX_UINTM); | 71 | reg = __raw_readl(regs + S3C64XX_UINTM); |
| @@ -73,10 +73,10 @@ static void s3c_irq_uart_unmask(unsigned int irq) | |||
| 73 | __raw_writel(reg, regs + S3C64XX_UINTM); | 73 | __raw_writel(reg, regs + S3C64XX_UINTM); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static void s3c_irq_uart_ack(unsigned int irq) | 76 | static void s3c_irq_uart_ack(struct irq_data *data) |
| 77 | { | 77 | { |
| 78 | void __iomem *regs = s3c_irq_uart_base(irq); | 78 | void __iomem *regs = s3c_irq_uart_base(data); |
| 79 | unsigned int bit = s3c_irq_uart_bit(irq); | 79 | unsigned int bit = s3c_irq_uart_bit(data->irq); |
| 80 | 80 | ||
| 81 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); | 81 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); |
| 82 | } | 82 | } |
| @@ -99,10 +99,10 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) | |||
| 99 | 99 | ||
| 100 | static struct irq_chip s3c_irq_uart = { | 100 | static struct irq_chip s3c_irq_uart = { |
| 101 | .name = "s3c-uart", | 101 | .name = "s3c-uart", |
| 102 | .mask = s3c_irq_uart_mask, | 102 | .irq_mask = s3c_irq_uart_mask, |
| 103 | .unmask = s3c_irq_uart_unmask, | 103 | .irq_unmask = s3c_irq_uart_unmask, |
| 104 | .mask_ack = s3c_irq_uart_maskack, | 104 | .irq_mask_ack = s3c_irq_uart_maskack, |
| 105 | .ack = s3c_irq_uart_ack, | 105 | .irq_ack = s3c_irq_uart_ack, |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) | 108 | static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) |
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index 0270519fcabc..7ce77ddb729d 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c | |||
| @@ -29,38 +29,41 @@ static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) | |||
| 29 | 29 | ||
| 30 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ | 30 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ |
| 31 | 31 | ||
| 32 | static void s3c_irq_timer_mask(unsigned int irq) | 32 | static void s3c_irq_timer_mask(struct irq_data *data) |
| 33 | { | 33 | { |
| 34 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | 34 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); |
| 35 | u32 mask = (u32)data->chip_data; | ||
| 35 | 36 | ||
| 36 | reg &= 0x1f; /* mask out pending interrupts */ | 37 | reg &= 0x1f; /* mask out pending interrupts */ |
| 37 | reg &= ~(1 << (irq - IRQ_TIMER0)); | 38 | reg &= ~mask; |
| 38 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | 39 | __raw_writel(reg, S3C64XX_TINT_CSTAT); |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | static void s3c_irq_timer_unmask(unsigned int irq) | 42 | static void s3c_irq_timer_unmask(struct irq_data *data) |
| 42 | { | 43 | { |
| 43 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | 44 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); |
| 45 | u32 mask = (u32)data->chip_data; | ||
| 44 | 46 | ||
| 45 | reg &= 0x1f; /* mask out pending interrupts */ | 47 | reg &= 0x1f; /* mask out pending interrupts */ |
| 46 | reg |= 1 << (irq - IRQ_TIMER0); | 48 | reg |= mask; |
| 47 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | 49 | __raw_writel(reg, S3C64XX_TINT_CSTAT); |
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | static void s3c_irq_timer_ack(unsigned int irq) | 52 | static void s3c_irq_timer_ack(struct irq_data *data) |
| 51 | { | 53 | { |
| 52 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | 54 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); |
| 55 | u32 mask = (u32)data->chip_data; | ||
| 53 | 56 | ||
| 54 | reg &= 0x1f; | 57 | reg &= 0x1f; |
| 55 | reg |= (1 << 5) << (irq - IRQ_TIMER0); | 58 | reg |= mask << 5; |
| 56 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | 59 | __raw_writel(reg, S3C64XX_TINT_CSTAT); |
| 57 | } | 60 | } |
| 58 | 61 | ||
| 59 | static struct irq_chip s3c_irq_timer = { | 62 | static struct irq_chip s3c_irq_timer = { |
| 60 | .name = "s3c-timer", | 63 | .name = "s3c-timer", |
| 61 | .mask = s3c_irq_timer_mask, | 64 | .irq_mask = s3c_irq_timer_mask, |
| 62 | .unmask = s3c_irq_timer_unmask, | 65 | .irq_unmask = s3c_irq_timer_unmask, |
| 63 | .ack = s3c_irq_timer_ack, | 66 | .irq_ack = s3c_irq_timer_ack, |
| 64 | }; | 67 | }; |
| 65 | 68 | ||
| 66 | /** | 69 | /** |
| @@ -79,6 +82,7 @@ void __init s3c_init_vic_timer_irq(unsigned int parent_irq, | |||
| 79 | set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); | 82 | set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); |
| 80 | 83 | ||
| 81 | set_irq_chip(timer_irq, &s3c_irq_timer); | 84 | set_irq_chip(timer_irq, &s3c_irq_timer); |
| 85 | set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); | ||
| 82 | set_irq_handler(timer_irq, handle_level_irq); | 86 | set_irq_handler(timer_irq, handle_level_irq); |
| 83 | set_irq_flags(timer_irq, IRQF_VALID); | 87 | set_irq_flags(timer_irq, IRQF_VALID); |
| 84 | 88 | ||
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c new file mode 100644 index 000000000000..efe1d564473e --- /dev/null +++ b/arch/arm/plat-samsung/pd.c | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /* linux/arch/arm/plat-samsung/pd.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
| 4 | * http://www.samsung.com | ||
| 5 | * | ||
| 6 | * Samsung Power domain support | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/pm_runtime.h> | ||
| 18 | |||
| 19 | #include <plat/pd.h> | ||
| 20 | |||
| 21 | static int samsung_pd_probe(struct platform_device *pdev) | ||
| 22 | { | ||
| 23 | struct samsung_pd_info *pdata = pdev->dev.platform_data; | ||
| 24 | struct device *dev = &pdev->dev; | ||
| 25 | |||
| 26 | if (!pdata) { | ||
| 27 | dev_err(dev, "no device data specified\n"); | ||
| 28 | return -ENOENT; | ||
| 29 | } | ||
| 30 | |||
| 31 | pm_runtime_set_active(dev); | ||
| 32 | pm_runtime_enable(dev); | ||
| 33 | |||
| 34 | dev_info(dev, "power domain registered\n"); | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | |||
| 38 | static int __devexit samsung_pd_remove(struct platform_device *pdev) | ||
| 39 | { | ||
| 40 | struct device *dev = &pdev->dev; | ||
| 41 | |||
| 42 | pm_runtime_disable(dev); | ||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | static int samsung_pd_runtime_suspend(struct device *dev) | ||
| 47 | { | ||
| 48 | struct samsung_pd_info *pdata = dev->platform_data; | ||
| 49 | int ret = 0; | ||
| 50 | |||
| 51 | if (pdata->disable) | ||
| 52 | ret = pdata->disable(dev); | ||
| 53 | |||
| 54 | dev_dbg(dev, "suspended\n"); | ||
| 55 | return ret; | ||
| 56 | } | ||
| 57 | |||
| 58 | static int samsung_pd_runtime_resume(struct device *dev) | ||
| 59 | { | ||
| 60 | struct samsung_pd_info *pdata = dev->platform_data; | ||
| 61 | int ret = 0; | ||
| 62 | |||
| 63 | if (pdata->enable) | ||
| 64 | ret = pdata->enable(dev); | ||
| 65 | |||
| 66 | dev_dbg(dev, "resumed\n"); | ||
| 67 | return ret; | ||
| 68 | } | ||
| 69 | |||
| 70 | static const struct dev_pm_ops samsung_pd_pm_ops = { | ||
| 71 | .runtime_suspend = samsung_pd_runtime_suspend, | ||
| 72 | .runtime_resume = samsung_pd_runtime_resume, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct platform_driver samsung_pd_driver = { | ||
| 76 | .driver = { | ||
| 77 | .name = "samsung-pd", | ||
| 78 | .owner = THIS_MODULE, | ||
| 79 | .pm = &samsung_pd_pm_ops, | ||
| 80 | }, | ||
| 81 | .probe = samsung_pd_probe, | ||
| 82 | .remove = __devexit_p(samsung_pd_remove), | ||
| 83 | }; | ||
| 84 | |||
| 85 | static int __init samsung_pd_init(void) | ||
| 86 | { | ||
| 87 | int ret; | ||
| 88 | |||
| 89 | ret = platform_driver_register(&samsung_pd_driver); | ||
| 90 | if (ret) | ||
| 91 | printk(KERN_ERR "%s: failed to add PD driver\n", __func__); | ||
| 92 | |||
| 93 | return ret; | ||
| 94 | } | ||
| 95 | arch_initcall(samsung_pd_init); | ||
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 27cfca597699..eaa57dc969ae 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c | |||
| @@ -136,15 +136,15 @@ static void s3c_pm_restore_uarts(void) { } | |||
| 136 | unsigned long s3c_irqwake_intmask = 0xffffffffL; | 136 | unsigned long s3c_irqwake_intmask = 0xffffffffL; |
| 137 | unsigned long s3c_irqwake_eintmask = 0xffffffffL; | 137 | unsigned long s3c_irqwake_eintmask = 0xffffffffL; |
| 138 | 138 | ||
| 139 | int s3c_irqext_wake(unsigned int irqno, unsigned int state) | 139 | int s3c_irqext_wake(struct irq_data *data, unsigned int state) |
| 140 | { | 140 | { |
| 141 | unsigned long bit = 1L << IRQ_EINT_BIT(irqno); | 141 | unsigned long bit = 1L << IRQ_EINT_BIT(data->irq); |
| 142 | 142 | ||
| 143 | if (!(s3c_irqwake_eintallow & bit)) | 143 | if (!(s3c_irqwake_eintallow & bit)) |
| 144 | return -ENOENT; | 144 | return -ENOENT; |
| 145 | 145 | ||
| 146 | printk(KERN_INFO "wake %s for irq %d\n", | 146 | printk(KERN_INFO "wake %s for irq %d\n", |
| 147 | state ? "enabled" : "disabled", irqno); | 147 | state ? "enabled" : "disabled", data->irq); |
| 148 | 148 | ||
| 149 | if (!state) | 149 | if (!state) |
| 150 | s3c_irqwake_eintmask |= bit; | 150 | s3c_irqwake_eintmask |= bit; |
