Commit 68ae89984710d2e9f3cf2005539c8f91bcce9d40
1 parent
bf46aaeacf
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ARM: SAMSUNG: move interrupt part for common s5p into plat-samsung
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Showing 10 changed files with 487 additions and 485 deletions Inline Diff
- arch/arm/plat-s5p/Kconfig
- arch/arm/plat-s5p/Makefile
- arch/arm/plat-s5p/irq-eint.c
- arch/arm/plat-s5p/irq-gpioint.c
- arch/arm/plat-s5p/irq.c
- arch/arm/plat-samsung/Kconfig
- arch/arm/plat-samsung/Makefile
- arch/arm/plat-samsung/s5p-irq-eint.c
- arch/arm/plat-samsung/s5p-irq-gpioint.c
- arch/arm/plat-samsung/s5p-irq.c
arch/arm/plat-s5p/Kconfig
1 | # arch/arm/plat-s5p/Kconfig | 1 | # arch/arm/plat-s5p/Kconfig |
2 | # | 2 | # |
3 | # Copyright (c) 2009 Samsung Electronics Co., Ltd. | 3 | # Copyright (c) 2009 Samsung Electronics Co., Ltd. |
4 | # http://www.samsung.com/ | 4 | # http://www.samsung.com/ |
5 | # | 5 | # |
6 | # Licensed under GPLv2 | 6 | # Licensed under GPLv2 |
7 | 7 | ||
8 | config PLAT_S5P | 8 | config PLAT_S5P |
9 | bool | 9 | bool |
10 | depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) | 10 | depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) |
11 | default y | 11 | default y |
12 | select ARM_VIC if !ARCH_EXYNOS | 12 | select ARM_VIC if !ARCH_EXYNOS |
13 | select ARM_GIC if ARCH_EXYNOS | 13 | select ARM_GIC if ARCH_EXYNOS |
14 | select GIC_NON_BANKED if ARCH_EXYNOS4 | 14 | select GIC_NON_BANKED if ARCH_EXYNOS4 |
15 | select NO_IOPORT | 15 | select NO_IOPORT |
16 | select ARCH_REQUIRE_GPIOLIB | 16 | select ARCH_REQUIRE_GPIOLIB |
17 | select S3C_GPIO_TRACK | 17 | select S3C_GPIO_TRACK |
18 | select S5P_GPIO_DRVSTR | 18 | select S5P_GPIO_DRVSTR |
19 | select SAMSUNG_GPIOLIB_4BIT | 19 | select SAMSUNG_GPIOLIB_4BIT |
20 | select PLAT_SAMSUNG | 20 | select PLAT_SAMSUNG |
21 | select SAMSUNG_CLKSRC | 21 | select SAMSUNG_CLKSRC |
22 | select SAMSUNG_IRQ_VIC_TIMER | 22 | select SAMSUNG_IRQ_VIC_TIMER |
23 | help | 23 | help |
24 | Base platform code for Samsung's S5P series SoC. | 24 | Base platform code for Samsung's S5P series SoC. |
25 | 25 | ||
26 | config S5P_EXT_INT | ||
27 | bool | ||
28 | help | ||
29 | Use the external interrupts (other than GPIO interrupts.) | ||
30 | Note: Do not choose this for S5P6440 and S5P6450. | ||
31 | |||
32 | config S5P_GPIO_INT | ||
33 | bool | ||
34 | help | ||
35 | Common code for the GPIO interrupts (other than external interrupts.) | ||
36 | |||
37 | config S5P_HRT | 26 | config S5P_HRT |
38 | bool | 27 | bool |
39 | select SAMSUNG_DEV_PWM | 28 | select SAMSUNG_DEV_PWM |
40 | help | 29 | help |
41 | Use the High Resolution timer support | 30 | Use the High Resolution timer support |
42 | 31 | ||
43 | config S5P_DEV_UART | 32 | config S5P_DEV_UART |
44 | def_bool y | 33 | def_bool y |
45 | depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) | 34 | depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) |
46 | 35 | ||
47 | config S5P_PM | 36 | config S5P_PM |
48 | bool | 37 | bool |
49 | help | 38 | help |
50 | Common code for power management support on S5P and newer SoCs | 39 | Common code for power management support on S5P and newer SoCs |
51 | Note: Do not select this for S5P6440 and S5P6450. | 40 | Note: Do not select this for S5P6440 and S5P6450. |
52 | 41 | ||
53 | config S5P_SLEEP | 42 | config S5P_SLEEP |
54 | bool | 43 | bool |
55 | help | 44 | help |
56 | Internal config node to apply common S5P sleep management code. | 45 | Internal config node to apply common S5P sleep management code. |
57 | Can be selected by S5P and newer SoCs with similar sleep procedure. | 46 | Can be selected by S5P and newer SoCs with similar sleep procedure. |
58 | 47 | ||
59 | config S5P_DEV_FIMC0 | 48 | config S5P_DEV_FIMC0 |
60 | bool | 49 | bool |
61 | help | 50 | help |
62 | Compile in platform device definitions for FIMC controller 0 | 51 | Compile in platform device definitions for FIMC controller 0 |
63 | 52 | ||
64 | config S5P_DEV_FIMC1 | 53 | config S5P_DEV_FIMC1 |
65 | bool | 54 | bool |
66 | help | 55 | help |
67 | Compile in platform device definitions for FIMC controller 1 | 56 | Compile in platform device definitions for FIMC controller 1 |
68 | 57 | ||
69 | config S5P_DEV_FIMC2 | 58 | config S5P_DEV_FIMC2 |
70 | bool | 59 | bool |
71 | help | 60 | help |
72 | Compile in platform device definitions for FIMC controller 2 | 61 | Compile in platform device definitions for FIMC controller 2 |
73 | 62 | ||
74 | config S5P_DEV_FIMC3 | 63 | config S5P_DEV_FIMC3 |
75 | bool | 64 | bool |
76 | help | 65 | help |
77 | Compile in platform device definitions for FIMC controller 3 | 66 | Compile in platform device definitions for FIMC controller 3 |
78 | 67 | ||
79 | config S5P_DEV_JPEG | 68 | config S5P_DEV_JPEG |
80 | bool | 69 | bool |
81 | help | 70 | help |
82 | Compile in platform device definitions for JPEG codec | 71 | Compile in platform device definitions for JPEG codec |
83 | 72 | ||
84 | config S5P_DEV_G2D | 73 | config S5P_DEV_G2D |
85 | bool | 74 | bool |
86 | help | 75 | help |
87 | Compile in platform device definitions for G2D device | 76 | Compile in platform device definitions for G2D device |
88 | 77 | ||
89 | config S5P_DEV_FIMD0 | 78 | config S5P_DEV_FIMD0 |
90 | bool | 79 | bool |
91 | help | 80 | help |
92 | Compile in platform device definitions for FIMD controller 0 | 81 | Compile in platform device definitions for FIMD controller 0 |
93 | 82 | ||
94 | config S5P_DEV_I2C_HDMIPHY | 83 | config S5P_DEV_I2C_HDMIPHY |
95 | bool | 84 | bool |
96 | help | 85 | help |
97 | Compile in platform device definitions for I2C HDMIPHY controller | 86 | Compile in platform device definitions for I2C HDMIPHY controller |
98 | 87 | ||
99 | config S5P_DEV_MFC | 88 | config S5P_DEV_MFC |
100 | bool | 89 | bool |
101 | help | 90 | help |
102 | Compile in platform device definitions for MFC | 91 | Compile in platform device definitions for MFC |
103 | 92 | ||
104 | config S5P_DEV_ONENAND | 93 | config S5P_DEV_ONENAND |
105 | bool | 94 | bool |
106 | help | 95 | help |
107 | Compile in platform device definition for OneNAND controller | 96 | Compile in platform device definition for OneNAND controller |
108 | 97 | ||
109 | config S5P_DEV_CSIS0 | 98 | config S5P_DEV_CSIS0 |
110 | bool | 99 | bool |
111 | help | 100 | help |
112 | Compile in platform device definitions for MIPI-CSIS channel 0 | 101 | Compile in platform device definitions for MIPI-CSIS channel 0 |
113 | 102 | ||
114 | config S5P_DEV_CSIS1 | 103 | config S5P_DEV_CSIS1 |
115 | bool | 104 | bool |
116 | help | 105 | help |
117 | Compile in platform device definitions for MIPI-CSIS channel 1 | 106 | Compile in platform device definitions for MIPI-CSIS channel 1 |
118 | 107 | ||
119 | config S5P_DEV_TV | 108 | config S5P_DEV_TV |
120 | bool | 109 | bool |
121 | help | 110 | help |
122 | Compile in platform device definition for TV interface | 111 | Compile in platform device definition for TV interface |
123 | 112 | ||
124 | config S5P_DEV_USB_EHCI | 113 | config S5P_DEV_USB_EHCI |
125 | bool | 114 | bool |
126 | help | 115 | help |
127 | Compile in platform device definition for USB EHCI | 116 | Compile in platform device definition for USB EHCI |
128 | 117 | ||
129 | config S5P_SETUP_MIPIPHY | 118 | config S5P_SETUP_MIPIPHY |
130 | bool | 119 | bool |
131 | help | 120 | help |
132 | Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices | 121 | Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices |
133 | 122 |
arch/arm/plat-s5p/Makefile
1 | # arch/arm/plat-s5p/Makefile | 1 | # arch/arm/plat-s5p/Makefile |
2 | # | 2 | # |
3 | # Copyright (c) 2009 Samsung Electronics Co., Ltd. | 3 | # Copyright (c) 2009 Samsung Electronics Co., Ltd. |
4 | # http://www.samsung.com/ | 4 | # http://www.samsung.com/ |
5 | # | 5 | # |
6 | # Licensed under GPLv2 | 6 | # Licensed under GPLv2 |
7 | 7 | ||
8 | obj-y := | 8 | obj-y := |
9 | obj-m := | 9 | obj-m := |
10 | obj-n := dummy.o | 10 | obj-n := dummy.o |
11 | obj- := | 11 | obj- := |
12 | 12 | ||
13 | # Core files | 13 | # Core files |
14 | 14 | ||
15 | obj-y += irq.o | ||
16 | obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o | ||
17 | obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o | ||
18 | obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o | 15 | obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o |
19 | obj-$(CONFIG_S5P_SLEEP) += sleep.o | 16 | obj-$(CONFIG_S5P_SLEEP) += sleep.o |
20 | obj-$(CONFIG_S5P_HRT) += s5p-time.o | 17 | obj-$(CONFIG_S5P_HRT) += s5p-time.o |
21 | 18 | ||
22 | # devices | 19 | # devices |
23 | 20 | ||
24 | obj-$(CONFIG_S5P_DEV_UART) += dev-uart.o | 21 | obj-$(CONFIG_S5P_DEV_UART) += dev-uart.o |
25 | obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o | 22 | obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o |
26 | obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o | 23 | obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o |
27 | 24 |
arch/arm/plat-s5p/irq-eint.c
1 | /* linux/arch/arm/plat-s5p/irq-eint.c | File was deleted | |
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * S5P - IRQ EINT 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/kernel.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/gpio.h> | ||
19 | |||
20 | #include <asm/hardware/vic.h> | ||
21 | |||
22 | #include <plat/regs-irqtype.h> | ||
23 | |||
24 | #include <mach/map.h> | ||
25 | #include <plat/cpu.h> | ||
26 | #include <plat/pm.h> | ||
27 | |||
28 | #include <plat/gpio-cfg.h> | ||
29 | #include <mach/regs-gpio.h> | ||
30 | |||
31 | static inline void s5p_irq_eint_mask(struct irq_data *data) | ||
32 | { | ||
33 | u32 mask; | ||
34 | |||
35 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
36 | mask |= eint_irq_to_bit(data->irq); | ||
37 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
38 | } | ||
39 | |||
40 | static void s5p_irq_eint_unmask(struct irq_data *data) | ||
41 | { | ||
42 | u32 mask; | ||
43 | |||
44 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
45 | mask &= ~(eint_irq_to_bit(data->irq)); | ||
46 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
47 | } | ||
48 | |||
49 | static inline void s5p_irq_eint_ack(struct irq_data *data) | ||
50 | { | ||
51 | __raw_writel(eint_irq_to_bit(data->irq), | ||
52 | S5P_EINT_PEND(EINT_REG_NR(data->irq))); | ||
53 | } | ||
54 | |||
55 | static void s5p_irq_eint_maskack(struct irq_data *data) | ||
56 | { | ||
57 | /* compiler should in-line these */ | ||
58 | s5p_irq_eint_mask(data); | ||
59 | s5p_irq_eint_ack(data); | ||
60 | } | ||
61 | |||
62 | static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) | ||
63 | { | ||
64 | int offs = EINT_OFFSET(data->irq); | ||
65 | int shift; | ||
66 | u32 ctrl, mask; | ||
67 | u32 newvalue = 0; | ||
68 | |||
69 | switch (type) { | ||
70 | case IRQ_TYPE_EDGE_RISING: | ||
71 | newvalue = S5P_IRQ_TYPE_EDGE_RISING; | ||
72 | break; | ||
73 | |||
74 | case IRQ_TYPE_EDGE_FALLING: | ||
75 | newvalue = S5P_IRQ_TYPE_EDGE_FALLING; | ||
76 | break; | ||
77 | |||
78 | case IRQ_TYPE_EDGE_BOTH: | ||
79 | newvalue = S5P_IRQ_TYPE_EDGE_BOTH; | ||
80 | break; | ||
81 | |||
82 | case IRQ_TYPE_LEVEL_LOW: | ||
83 | newvalue = S5P_IRQ_TYPE_LEVEL_LOW; | ||
84 | break; | ||
85 | |||
86 | case IRQ_TYPE_LEVEL_HIGH: | ||
87 | newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; | ||
88 | break; | ||
89 | |||
90 | default: | ||
91 | printk(KERN_ERR "No such irq type %d", type); | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
95 | shift = (offs & 0x7) * 4; | ||
96 | mask = 0x7 << shift; | ||
97 | |||
98 | ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); | ||
99 | ctrl &= ~mask; | ||
100 | ctrl |= newvalue << shift; | ||
101 | __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); | ||
102 | |||
103 | if ((0 <= offs) && (offs < 8)) | ||
104 | s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); | ||
105 | |||
106 | else if ((8 <= offs) && (offs < 16)) | ||
107 | s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); | ||
108 | |||
109 | else if ((16 <= offs) && (offs < 24)) | ||
110 | s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); | ||
111 | |||
112 | else if ((24 <= offs) && (offs < 32)) | ||
113 | s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); | ||
114 | |||
115 | else | ||
116 | printk(KERN_ERR "No such irq number %d", offs); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static struct irq_chip s5p_irq_eint = { | ||
122 | .name = "s5p-eint", | ||
123 | .irq_mask = s5p_irq_eint_mask, | ||
124 | .irq_unmask = s5p_irq_eint_unmask, | ||
125 | .irq_mask_ack = s5p_irq_eint_maskack, | ||
126 | .irq_ack = s5p_irq_eint_ack, | ||
127 | .irq_set_type = s5p_irq_eint_set_type, | ||
128 | #ifdef CONFIG_PM | ||
129 | .irq_set_wake = s3c_irqext_wake, | ||
130 | #endif | ||
131 | }; | ||
132 | |||
133 | /* s5p_irq_demux_eint | ||
134 | * | ||
135 | * This function demuxes the IRQ from the group0 external interrupts, | ||
136 | * from EINTs 16 to 31. It is designed to be inlined into the specific | ||
137 | * handler s5p_irq_demux_eintX_Y. | ||
138 | * | ||
139 | * Each EINT pend/mask registers handle eight of them. | ||
140 | */ | ||
141 | static inline void s5p_irq_demux_eint(unsigned int start) | ||
142 | { | ||
143 | u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); | ||
144 | u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); | ||
145 | unsigned int irq; | ||
146 | |||
147 | status &= ~mask; | ||
148 | status &= 0xff; | ||
149 | |||
150 | while (status) { | ||
151 | irq = fls(status) - 1; | ||
152 | generic_handle_irq(irq + start); | ||
153 | status &= ~(1 << irq); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | ||
158 | { | ||
159 | s5p_irq_demux_eint(IRQ_EINT(16)); | ||
160 | s5p_irq_demux_eint(IRQ_EINT(24)); | ||
161 | } | ||
162 | |||
163 | static inline void s5p_irq_vic_eint_mask(struct irq_data *data) | ||
164 | { | ||
165 | void __iomem *base = irq_data_get_irq_chip_data(data); | ||
166 | |||
167 | s5p_irq_eint_mask(data); | ||
168 | writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR); | ||
169 | } | ||
170 | |||
171 | static void s5p_irq_vic_eint_unmask(struct irq_data *data) | ||
172 | { | ||
173 | void __iomem *base = irq_data_get_irq_chip_data(data); | ||
174 | |||
175 | s5p_irq_eint_unmask(data); | ||
176 | writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE); | ||
177 | } | ||
178 | |||
179 | static inline void s5p_irq_vic_eint_ack(struct irq_data *data) | ||
180 | { | ||
181 | __raw_writel(eint_irq_to_bit(data->irq), | ||
182 | S5P_EINT_PEND(EINT_REG_NR(data->irq))); | ||
183 | } | ||
184 | |||
185 | static void s5p_irq_vic_eint_maskack(struct irq_data *data) | ||
186 | { | ||
187 | s5p_irq_vic_eint_mask(data); | ||
188 | s5p_irq_vic_eint_ack(data); | ||
189 | } | ||
190 | |||
191 | static struct irq_chip s5p_irq_vic_eint = { | ||
192 | .name = "s5p_vic_eint", | ||
193 | .irq_mask = s5p_irq_vic_eint_mask, | ||
194 | .irq_unmask = s5p_irq_vic_eint_unmask, | ||
195 | .irq_mask_ack = s5p_irq_vic_eint_maskack, | ||
196 | .irq_ack = s5p_irq_vic_eint_ack, | ||
197 | .irq_set_type = s5p_irq_eint_set_type, | ||
198 | #ifdef CONFIG_PM | ||
199 | .irq_set_wake = s3c_irqext_wake, | ||
200 | #endif | ||
201 | }; | ||
202 | |||
203 | static int __init s5p_init_irq_eint(void) | ||
204 | { | ||
205 | int irq; | ||
206 | |||
207 | for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++) | ||
208 | irq_set_chip(irq, &s5p_irq_vic_eint); | ||
209 | |||
210 | for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) { | ||
211 | irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq); | ||
212 | set_irq_flags(irq, IRQF_VALID); | ||
213 | } | ||
214 | |||
215 | irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | arch_initcall(s5p_init_irq_eint); | ||
220 | 1 | /* linux/arch/arm/plat-s5p/irq-eint.c |
arch/arm/plat-s5p/irq-gpioint.c
1 | /* linux/arch/arm/plat-s5p/irq-gpioint.c | File was deleted | |
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * Author: Kyungmin Park <kyungmin.park@samsung.com> | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * Author: Marek Szyprowski <m.szyprowski@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/irq.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/gpio.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | #include <mach/map.h> | ||
23 | #include <plat/gpio-core.h> | ||
24 | #include <plat/gpio-cfg.h> | ||
25 | |||
26 | #include <asm/mach/irq.h> | ||
27 | |||
28 | #define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) | ||
29 | |||
30 | #define CON_OFFSET 0x700 | ||
31 | #define MASK_OFFSET 0x900 | ||
32 | #define PEND_OFFSET 0xA00 | ||
33 | #define REG_OFFSET(x) ((x) << 2) | ||
34 | |||
35 | struct s5p_gpioint_bank { | ||
36 | struct list_head list; | ||
37 | int start; | ||
38 | int nr_groups; | ||
39 | int irq; | ||
40 | struct samsung_gpio_chip **chips; | ||
41 | void (*handler)(unsigned int, struct irq_desc *); | ||
42 | }; | ||
43 | |||
44 | static LIST_HEAD(banks); | ||
45 | |||
46 | static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) | ||
47 | { | ||
48 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
49 | struct irq_chip_type *ct = gc->chip_types; | ||
50 | unsigned int shift = (d->irq - gc->irq_base) << 2; | ||
51 | |||
52 | switch (type) { | ||
53 | case IRQ_TYPE_EDGE_RISING: | ||
54 | type = S5P_IRQ_TYPE_EDGE_RISING; | ||
55 | break; | ||
56 | case IRQ_TYPE_EDGE_FALLING: | ||
57 | type = S5P_IRQ_TYPE_EDGE_FALLING; | ||
58 | break; | ||
59 | case IRQ_TYPE_EDGE_BOTH: | ||
60 | type = S5P_IRQ_TYPE_EDGE_BOTH; | ||
61 | break; | ||
62 | case IRQ_TYPE_LEVEL_HIGH: | ||
63 | type = S5P_IRQ_TYPE_LEVEL_HIGH; | ||
64 | break; | ||
65 | case IRQ_TYPE_LEVEL_LOW: | ||
66 | type = S5P_IRQ_TYPE_LEVEL_LOW; | ||
67 | break; | ||
68 | case IRQ_TYPE_NONE: | ||
69 | default: | ||
70 | printk(KERN_WARNING "No irq type\n"); | ||
71 | return -EINVAL; | ||
72 | } | ||
73 | |||
74 | gc->type_cache &= ~(0x7 << shift); | ||
75 | gc->type_cache |= type << shift; | ||
76 | writel(gc->type_cache, gc->reg_base + ct->regs.type); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) | ||
81 | { | ||
82 | struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); | ||
83 | int group, pend_offset, mask_offset; | ||
84 | unsigned int pend, mask; | ||
85 | |||
86 | struct irq_chip *chip = irq_get_chip(irq); | ||
87 | chained_irq_enter(chip, desc); | ||
88 | |||
89 | for (group = 0; group < bank->nr_groups; group++) { | ||
90 | struct samsung_gpio_chip *chip = bank->chips[group]; | ||
91 | if (!chip) | ||
92 | continue; | ||
93 | |||
94 | pend_offset = REG_OFFSET(group); | ||
95 | pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); | ||
96 | if (!pend) | ||
97 | continue; | ||
98 | |||
99 | mask_offset = REG_OFFSET(group); | ||
100 | mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); | ||
101 | pend &= ~mask; | ||
102 | |||
103 | while (pend) { | ||
104 | int offset = fls(pend) - 1; | ||
105 | int real_irq = chip->irq_base + offset; | ||
106 | generic_handle_irq(real_irq); | ||
107 | pend &= ~BIT(offset); | ||
108 | } | ||
109 | } | ||
110 | chained_irq_exit(chip, desc); | ||
111 | } | ||
112 | |||
113 | static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip) | ||
114 | { | ||
115 | static int used_gpioint_groups = 0; | ||
116 | int group = chip->group; | ||
117 | struct s5p_gpioint_bank *b, *bank = NULL; | ||
118 | struct irq_chip_generic *gc; | ||
119 | struct irq_chip_type *ct; | ||
120 | |||
121 | if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) | ||
122 | return -ENOMEM; | ||
123 | |||
124 | list_for_each_entry(b, &banks, list) { | ||
125 | if (group >= b->start && group < b->start + b->nr_groups) { | ||
126 | bank = b; | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | if (!bank) | ||
131 | return -EINVAL; | ||
132 | |||
133 | if (!bank->handler) { | ||
134 | bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) * | ||
135 | bank->nr_groups, GFP_KERNEL); | ||
136 | if (!bank->chips) | ||
137 | return -ENOMEM; | ||
138 | |||
139 | irq_set_chained_handler(bank->irq, s5p_gpioint_handler); | ||
140 | irq_set_handler_data(bank->irq, bank); | ||
141 | bank->handler = s5p_gpioint_handler; | ||
142 | printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n", | ||
143 | bank->irq); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * chained GPIO irq has been successfully registered, allocate new gpio | ||
148 | * int group and assign irq nubmers | ||
149 | */ | ||
150 | chip->irq_base = S5P_GPIOINT_BASE + | ||
151 | used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; | ||
152 | used_gpioint_groups++; | ||
153 | |||
154 | bank->chips[group - bank->start] = chip; | ||
155 | |||
156 | gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, | ||
157 | (void __iomem *)GPIO_BASE(chip), | ||
158 | handle_level_irq); | ||
159 | if (!gc) | ||
160 | return -ENOMEM; | ||
161 | ct = gc->chip_types; | ||
162 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
163 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
164 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
165 | ct->chip.irq_set_type = s5p_gpioint_set_type, | ||
166 | ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start); | ||
167 | ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start); | ||
168 | ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start); | ||
169 | irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), | ||
170 | IRQ_GC_INIT_MASK_CACHE, | ||
171 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | int __init s5p_register_gpio_interrupt(int pin) | ||
176 | { | ||
177 | struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin); | ||
178 | int offset, group; | ||
179 | int ret; | ||
180 | |||
181 | if (!my_chip) | ||
182 | return -EINVAL; | ||
183 | |||
184 | offset = pin - my_chip->chip.base; | ||
185 | group = my_chip->group; | ||
186 | |||
187 | /* check if the group has been already registered */ | ||
188 | if (my_chip->irq_base) | ||
189 | return my_chip->irq_base + offset; | ||
190 | |||
191 | /* register gpio group */ | ||
192 | ret = s5p_gpioint_add(my_chip); | ||
193 | if (ret == 0) { | ||
194 | my_chip->chip.to_irq = samsung_gpiolib_to_irq; | ||
195 | printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", | ||
196 | group); | ||
197 | return my_chip->irq_base + offset; | ||
198 | } | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups) | ||
203 | { | ||
204 | struct s5p_gpioint_bank *bank; | ||
205 | |||
206 | bank = kzalloc(sizeof(*bank), GFP_KERNEL); | ||
207 | if (!bank) | ||
208 | return -ENOMEM; | ||
209 | |||
210 | bank->start = start; | ||
211 | bank->nr_groups = nr_groups; | ||
212 | bank->irq = chain_irq; | ||
213 | |||
214 | list_add_tail(&bank->list, &banks); | ||
215 | return 0; | ||
216 | } | ||
217 | 1 | /* linux/arch/arm/plat-s5p/irq-gpioint.c |
arch/arm/plat-s5p/irq.c
1 | /* arch/arm/plat-s5p/irq.c | File was deleted | |
2 | * | ||
3 | * Copyright (c) 2009 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5P - Interrupt handling | ||
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/kernel.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #include <asm/hardware/vic.h> | ||
19 | |||
20 | #include <mach/map.h> | ||
21 | #include <plat/regs-timer.h> | ||
22 | #include <plat/cpu.h> | ||
23 | #include <plat/irq-vic-timer.h> | ||
24 | |||
25 | void __init s5p_init_irq(u32 *vic, u32 num_vic) | ||
26 | { | ||
27 | #ifdef CONFIG_ARM_VIC | ||
28 | int irq; | ||
29 | |||
30 | /* initialize the VICs */ | ||
31 | for (irq = 0; irq < num_vic; irq++) | ||
32 | vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); | ||
33 | #endif | ||
34 | |||
35 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); | ||
36 | } | ||
37 | 1 | /* arch/arm/plat-s5p/irq.c |
arch/arm/plat-samsung/Kconfig
1 | # arch/arm/plat-samsung/Kconfig | 1 | # arch/arm/plat-samsung/Kconfig |
2 | # | 2 | # |
3 | # Copyright 2009 Simtec Electronics | 3 | # Copyright 2009 Simtec Electronics |
4 | # | 4 | # |
5 | # Licensed under GPLv2 | 5 | # Licensed under GPLv2 |
6 | 6 | ||
7 | config PLAT_SAMSUNG | 7 | config PLAT_SAMSUNG |
8 | bool | 8 | bool |
9 | depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P | 9 | depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P |
10 | select NO_IOPORT | 10 | select NO_IOPORT |
11 | select GENERIC_IRQ_CHIP | 11 | select GENERIC_IRQ_CHIP |
12 | default y | 12 | default y |
13 | help | 13 | help |
14 | Base platform code for all Samsung SoC based systems | 14 | Base platform code for all Samsung SoC based systems |
15 | 15 | ||
16 | if PLAT_SAMSUNG | 16 | if PLAT_SAMSUNG |
17 | 17 | ||
18 | # boot configurations | 18 | # boot configurations |
19 | 19 | ||
20 | comment "Boot options" | 20 | comment "Boot options" |
21 | 21 | ||
22 | config S3C_BOOT_WATCHDOG | 22 | config S3C_BOOT_WATCHDOG |
23 | bool "S3C Initialisation watchdog" | 23 | bool "S3C Initialisation watchdog" |
24 | depends on S3C2410_WATCHDOG | 24 | depends on S3C2410_WATCHDOG |
25 | help | 25 | help |
26 | Say y to enable the watchdog during the kernel decompression | 26 | Say y to enable the watchdog during the kernel decompression |
27 | stage. If the kernel fails to uncompress, then the watchdog | 27 | stage. If the kernel fails to uncompress, then the watchdog |
28 | will trigger a reset and the system should restart. | 28 | will trigger a reset and the system should restart. |
29 | 29 | ||
30 | config S3C_BOOT_ERROR_RESET | 30 | config S3C_BOOT_ERROR_RESET |
31 | bool "S3C Reboot on decompression error" | 31 | bool "S3C Reboot on decompression error" |
32 | help | 32 | help |
33 | Say y here to use the watchdog to reset the system if the | 33 | Say y here to use the watchdog to reset the system if the |
34 | kernel decompressor detects an error during decompression. | 34 | kernel decompressor detects an error during decompression. |
35 | 35 | ||
36 | config S3C_BOOT_UART_FORCE_FIFO | 36 | config S3C_BOOT_UART_FORCE_FIFO |
37 | bool "Force UART FIFO on during boot process" | 37 | bool "Force UART FIFO on during boot process" |
38 | default y | 38 | default y |
39 | help | 39 | help |
40 | Say Y here to force the UART FIFOs on during the kernel | 40 | Say Y here to force the UART FIFOs on during the kernel |
41 | uncompressor | 41 | uncompressor |
42 | 42 | ||
43 | 43 | ||
44 | config S3C_LOWLEVEL_UART_PORT | 44 | config S3C_LOWLEVEL_UART_PORT |
45 | int "S3C UART to use for low-level messages" | 45 | int "S3C UART to use for low-level messages" |
46 | default 0 | 46 | default 0 |
47 | help | 47 | help |
48 | Choice of which UART port to use for the low-level messages, | 48 | Choice of which UART port to use for the low-level messages, |
49 | such as the `Uncompressing...` at start time. The value of | 49 | such as the `Uncompressing...` at start time. The value of |
50 | this configuration should be between zero and two. The port | 50 | this configuration should be between zero and two. The port |
51 | must have been initialised by the boot-loader before use. | 51 | must have been initialised by the boot-loader before use. |
52 | 52 | ||
53 | # clock options | 53 | # clock options |
54 | 54 | ||
55 | config SAMSUNG_CLKSRC | 55 | config SAMSUNG_CLKSRC |
56 | bool | 56 | bool |
57 | help | 57 | help |
58 | Select the clock code for the clksrc implementation | 58 | Select the clock code for the clksrc implementation |
59 | used by newer systems such as the S3C64XX. | 59 | used by newer systems such as the S3C64XX. |
60 | 60 | ||
61 | config S5P_CLOCK | 61 | config S5P_CLOCK |
62 | def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) | 62 | def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) |
63 | help | 63 | help |
64 | Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs | 64 | Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs |
65 | 65 | ||
66 | # options for IRQ support | 66 | # options for IRQ support |
67 | 67 | ||
68 | config SAMSUNG_IRQ_VIC_TIMER | 68 | config SAMSUNG_IRQ_VIC_TIMER |
69 | bool | 69 | bool |
70 | help | 70 | help |
71 | Internal configuration to build the VIC timer interrupt code. | 71 | Internal configuration to build the VIC timer interrupt code. |
72 | 72 | ||
73 | config S5P_IRQ | ||
74 | def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) | ||
75 | help | ||
76 | Support common interrup part for ARCH_S5P and ARCH_EXYNOS SoCs | ||
77 | |||
78 | config S5P_EXT_INT | ||
79 | bool | ||
80 | help | ||
81 | Use the external interrupts (other than GPIO interrupts.) | ||
82 | Note: Do not choose this for S5P6440 and S5P6450. | ||
83 | |||
84 | config S5P_GPIO_INT | ||
85 | bool | ||
86 | help | ||
87 | Common code for the GPIO interrupts (other than external interrupts.) | ||
88 | |||
73 | # options for gpio configuration support | 89 | # options for gpio configuration support |
74 | 90 | ||
75 | config SAMSUNG_GPIOLIB_4BIT | 91 | config SAMSUNG_GPIOLIB_4BIT |
76 | bool | 92 | bool |
77 | help | 93 | help |
78 | GPIOlib file contains the 4 bit modification functions for gpio | 94 | GPIOlib file contains the 4 bit modification functions for gpio |
79 | configuration. GPIOlib shall be compiled only for S3C64XX and S5P | 95 | configuration. GPIOlib shall be compiled only for S3C64XX and S5P |
80 | series of processors. | 96 | series of processors. |
81 | 97 | ||
82 | config S3C_GPIO_CFG_S3C64XX | 98 | config S3C_GPIO_CFG_S3C64XX |
83 | bool | 99 | bool |
84 | help | 100 | help |
85 | Internal configuration to enable S3C64XX style GPIO configuration | 101 | Internal configuration to enable S3C64XX style GPIO configuration |
86 | functions. | 102 | functions. |
87 | 103 | ||
88 | config S5P_GPIO_DRVSTR | 104 | config S5P_GPIO_DRVSTR |
89 | bool | 105 | bool |
90 | help | 106 | help |
91 | Internal configuration to get and set correct GPIO driver strength | 107 | Internal configuration to get and set correct GPIO driver strength |
92 | helper | 108 | helper |
93 | 109 | ||
94 | config SAMSUNG_GPIO_EXTRA | 110 | config SAMSUNG_GPIO_EXTRA |
95 | int "Number of additional GPIO pins" | 111 | int "Number of additional GPIO pins" |
96 | default 128 if SAMSUNG_GPIO_EXTRA128 | 112 | default 128 if SAMSUNG_GPIO_EXTRA128 |
97 | default 64 if SAMSUNG_GPIO_EXTRA64 | 113 | default 64 if SAMSUNG_GPIO_EXTRA64 |
98 | default 0 | 114 | default 0 |
99 | help | 115 | help |
100 | Use additional GPIO space in addition to the GPIO's the SOC | 116 | Use additional GPIO space in addition to the GPIO's the SOC |
101 | provides. This allows expanding the GPIO space for use with | 117 | provides. This allows expanding the GPIO space for use with |
102 | GPIO expanders. | 118 | GPIO expanders. |
103 | 119 | ||
104 | config SAMSUNG_GPIO_EXTRA64 | 120 | config SAMSUNG_GPIO_EXTRA64 |
105 | bool | 121 | bool |
106 | 122 | ||
107 | config SAMSUNG_GPIO_EXTRA128 | 123 | config SAMSUNG_GPIO_EXTRA128 |
108 | bool | 124 | bool |
109 | 125 | ||
110 | config S3C_GPIO_SPACE | 126 | config S3C_GPIO_SPACE |
111 | int "Space between gpio banks" | 127 | int "Space between gpio banks" |
112 | default 0 | 128 | default 0 |
113 | help | 129 | help |
114 | Add a number of spare GPIO entries between each bank for debugging | 130 | Add a number of spare GPIO entries between each bank for debugging |
115 | purposes. This allows any problems where an counter overflows from | 131 | purposes. This allows any problems where an counter overflows from |
116 | one bank to another to be caught, at the expense of using a little | 132 | one bank to another to be caught, at the expense of using a little |
117 | more memory. | 133 | more memory. |
118 | 134 | ||
119 | config S3C_GPIO_TRACK | 135 | config S3C_GPIO_TRACK |
120 | bool | 136 | bool |
121 | help | 137 | help |
122 | Internal configuration option to enable the s3c specific gpio | 138 | Internal configuration option to enable the s3c specific gpio |
123 | chip tracking if the platform requires it. | 139 | chip tracking if the platform requires it. |
124 | 140 | ||
125 | # ADC driver | 141 | # ADC driver |
126 | 142 | ||
127 | config S3C_ADC | 143 | config S3C_ADC |
128 | bool "ADC common driver support" | 144 | bool "ADC common driver support" |
129 | help | 145 | help |
130 | Core support for the ADC block found in the Samsung SoC systems | 146 | Core support for the ADC block found in the Samsung SoC systems |
131 | for drivers such as the touchscreen and hwmon to use to share | 147 | for drivers such as the touchscreen and hwmon to use to share |
132 | this resource. | 148 | this resource. |
133 | 149 | ||
134 | # device definitions to compile in | 150 | # device definitions to compile in |
135 | 151 | ||
136 | config S3C_DEV_HSMMC | 152 | config S3C_DEV_HSMMC |
137 | bool | 153 | bool |
138 | help | 154 | help |
139 | Compile in platform device definitions for HSMMC code | 155 | Compile in platform device definitions for HSMMC code |
140 | 156 | ||
141 | config S3C_DEV_HSMMC1 | 157 | config S3C_DEV_HSMMC1 |
142 | bool | 158 | bool |
143 | help | 159 | help |
144 | Compile in platform device definitions for HSMMC channel 1 | 160 | Compile in platform device definitions for HSMMC channel 1 |
145 | 161 | ||
146 | config S3C_DEV_HSMMC2 | 162 | config S3C_DEV_HSMMC2 |
147 | bool | 163 | bool |
148 | help | 164 | help |
149 | Compile in platform device definitions for HSMMC channel 2 | 165 | Compile in platform device definitions for HSMMC channel 2 |
150 | 166 | ||
151 | config S3C_DEV_HSMMC3 | 167 | config S3C_DEV_HSMMC3 |
152 | bool | 168 | bool |
153 | help | 169 | help |
154 | Compile in platform device definitions for HSMMC channel 3 | 170 | Compile in platform device definitions for HSMMC channel 3 |
155 | 171 | ||
156 | config S3C_DEV_HWMON | 172 | config S3C_DEV_HWMON |
157 | bool | 173 | bool |
158 | help | 174 | help |
159 | Compile in platform device definitions for HWMON | 175 | Compile in platform device definitions for HWMON |
160 | 176 | ||
161 | config S3C_DEV_I2C1 | 177 | config S3C_DEV_I2C1 |
162 | bool | 178 | bool |
163 | help | 179 | help |
164 | Compile in platform device definitions for I2C channel 1 | 180 | Compile in platform device definitions for I2C channel 1 |
165 | 181 | ||
166 | config S3C_DEV_I2C2 | 182 | config S3C_DEV_I2C2 |
167 | bool | 183 | bool |
168 | help | 184 | help |
169 | Compile in platform device definitions for I2C channel 2 | 185 | Compile in platform device definitions for I2C channel 2 |
170 | 186 | ||
171 | config S3C_DEV_I2C3 | 187 | config S3C_DEV_I2C3 |
172 | bool | 188 | bool |
173 | help | 189 | help |
174 | Compile in platform device definition for I2C controller 3 | 190 | Compile in platform device definition for I2C controller 3 |
175 | 191 | ||
176 | config S3C_DEV_I2C4 | 192 | config S3C_DEV_I2C4 |
177 | bool | 193 | bool |
178 | help | 194 | help |
179 | Compile in platform device definition for I2C controller 4 | 195 | Compile in platform device definition for I2C controller 4 |
180 | 196 | ||
181 | config S3C_DEV_I2C5 | 197 | config S3C_DEV_I2C5 |
182 | bool | 198 | bool |
183 | help | 199 | help |
184 | Compile in platform device definition for I2C controller 5 | 200 | Compile in platform device definition for I2C controller 5 |
185 | 201 | ||
186 | config S3C_DEV_I2C6 | 202 | config S3C_DEV_I2C6 |
187 | bool | 203 | bool |
188 | help | 204 | help |
189 | Compile in platform device definition for I2C controller 6 | 205 | Compile in platform device definition for I2C controller 6 |
190 | 206 | ||
191 | config S3C_DEV_I2C7 | 207 | config S3C_DEV_I2C7 |
192 | bool | 208 | bool |
193 | help | 209 | help |
194 | Compile in platform device definition for I2C controller 7 | 210 | Compile in platform device definition for I2C controller 7 |
195 | 211 | ||
196 | config S3C_DEV_FB | 212 | config S3C_DEV_FB |
197 | bool | 213 | bool |
198 | help | 214 | help |
199 | Compile in platform device definition for framebuffer | 215 | Compile in platform device definition for framebuffer |
200 | 216 | ||
201 | config S3C_DEV_USB_HOST | 217 | config S3C_DEV_USB_HOST |
202 | bool | 218 | bool |
203 | help | 219 | help |
204 | Compile in platform device definition for USB host. | 220 | Compile in platform device definition for USB host. |
205 | 221 | ||
206 | config S3C_DEV_USB_HSOTG | 222 | config S3C_DEV_USB_HSOTG |
207 | bool | 223 | bool |
208 | help | 224 | help |
209 | Compile in platform device definition for USB high-speed OtG | 225 | Compile in platform device definition for USB high-speed OtG |
210 | 226 | ||
211 | config S3C_DEV_WDT | 227 | config S3C_DEV_WDT |
212 | bool | 228 | bool |
213 | default y if ARCH_S3C24XX | 229 | default y if ARCH_S3C24XX |
214 | help | 230 | help |
215 | Complie in platform device definition for Watchdog Timer | 231 | Complie in platform device definition for Watchdog Timer |
216 | 232 | ||
217 | config S3C_DEV_NAND | 233 | config S3C_DEV_NAND |
218 | bool | 234 | bool |
219 | help | 235 | help |
220 | Compile in platform device definition for NAND controller | 236 | Compile in platform device definition for NAND controller |
221 | 237 | ||
222 | config S3C_DEV_ONENAND | 238 | config S3C_DEV_ONENAND |
223 | bool | 239 | bool |
224 | help | 240 | help |
225 | Compile in platform device definition for OneNAND controller | 241 | Compile in platform device definition for OneNAND controller |
226 | 242 | ||
227 | config S3C_DEV_RTC | 243 | config S3C_DEV_RTC |
228 | bool | 244 | bool |
229 | help | 245 | help |
230 | Complie in platform device definition for RTC | 246 | Complie in platform device definition for RTC |
231 | 247 | ||
232 | config SAMSUNG_DEV_ADC | 248 | config SAMSUNG_DEV_ADC |
233 | bool | 249 | bool |
234 | help | 250 | help |
235 | Compile in platform device definition for ADC controller | 251 | Compile in platform device definition for ADC controller |
236 | 252 | ||
237 | config SAMSUNG_DEV_IDE | 253 | config SAMSUNG_DEV_IDE |
238 | bool | 254 | bool |
239 | help | 255 | help |
240 | Compile in platform device definitions for IDE | 256 | Compile in platform device definitions for IDE |
241 | 257 | ||
242 | config S3C64XX_DEV_SPI0 | 258 | config S3C64XX_DEV_SPI0 |
243 | bool | 259 | bool |
244 | help | 260 | help |
245 | Compile in platform device definitions for S3C64XX's type | 261 | Compile in platform device definitions for S3C64XX's type |
246 | SPI controller 0 | 262 | SPI controller 0 |
247 | 263 | ||
248 | config S3C64XX_DEV_SPI1 | 264 | config S3C64XX_DEV_SPI1 |
249 | bool | 265 | bool |
250 | help | 266 | help |
251 | Compile in platform device definitions for S3C64XX's type | 267 | Compile in platform device definitions for S3C64XX's type |
252 | SPI controller 1 | 268 | SPI controller 1 |
253 | 269 | ||
254 | config S3C64XX_DEV_SPI2 | 270 | config S3C64XX_DEV_SPI2 |
255 | bool | 271 | bool |
256 | help | 272 | help |
257 | Compile in platform device definitions for S3C64XX's type | 273 | Compile in platform device definitions for S3C64XX's type |
258 | SPI controller 2 | 274 | SPI controller 2 |
259 | 275 | ||
260 | config SAMSUNG_DEV_TS | 276 | config SAMSUNG_DEV_TS |
261 | bool | 277 | bool |
262 | help | 278 | help |
263 | Common in platform device definitions for touchscreen device | 279 | Common in platform device definitions for touchscreen device |
264 | 280 | ||
265 | config SAMSUNG_DEV_KEYPAD | 281 | config SAMSUNG_DEV_KEYPAD |
266 | bool | 282 | bool |
267 | help | 283 | help |
268 | Compile in platform device definitions for keypad | 284 | Compile in platform device definitions for keypad |
269 | 285 | ||
270 | config SAMSUNG_DEV_PWM | 286 | config SAMSUNG_DEV_PWM |
271 | bool | 287 | bool |
272 | default y if ARCH_S3C24XX | 288 | default y if ARCH_S3C24XX |
273 | help | 289 | help |
274 | Compile in platform device definition for PWM Timer | 290 | Compile in platform device definition for PWM Timer |
275 | 291 | ||
276 | config SAMSUNG_DEV_BACKLIGHT | 292 | config SAMSUNG_DEV_BACKLIGHT |
277 | bool | 293 | bool |
278 | depends on SAMSUNG_DEV_PWM | 294 | depends on SAMSUNG_DEV_PWM |
279 | help | 295 | help |
280 | Compile in platform device definition LCD backlight with PWM Timer | 296 | Compile in platform device definition LCD backlight with PWM Timer |
281 | 297 | ||
282 | config S3C24XX_PWM | 298 | config S3C24XX_PWM |
283 | bool "PWM device support" | 299 | bool "PWM device support" |
284 | select HAVE_PWM | 300 | select HAVE_PWM |
285 | help | 301 | help |
286 | Support for exporting the PWM timer blocks via the pwm device | 302 | Support for exporting the PWM timer blocks via the pwm device |
287 | system | 303 | system |
288 | 304 | ||
289 | # DMA | 305 | # DMA |
290 | 306 | ||
291 | config S3C_DMA | 307 | config S3C_DMA |
292 | bool | 308 | bool |
293 | help | 309 | help |
294 | Internal configuration for S3C DMA core | 310 | Internal configuration for S3C DMA core |
295 | 311 | ||
296 | config SAMSUNG_DMADEV | 312 | config SAMSUNG_DMADEV |
297 | bool | 313 | bool |
298 | select DMADEVICES | 314 | select DMADEVICES |
299 | select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \ | 315 | select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \ |
300 | CPU_S5P6450 || CPU_S5P6440) | 316 | CPU_S5P6450 || CPU_S5P6440) |
301 | select ARM_AMBA | 317 | select ARM_AMBA |
302 | help | 318 | help |
303 | Use DMA device engine for PL330 DMAC. | 319 | Use DMA device engine for PL330 DMAC. |
304 | 320 | ||
305 | comment "Power management" | 321 | comment "Power management" |
306 | 322 | ||
307 | config SAMSUNG_PM_DEBUG | 323 | config SAMSUNG_PM_DEBUG |
308 | bool "S3C2410 PM Suspend debug" | 324 | bool "S3C2410 PM Suspend debug" |
309 | depends on PM | 325 | depends on PM |
310 | help | 326 | help |
311 | Say Y here if you want verbose debugging from the PM Suspend and | 327 | Say Y here if you want verbose debugging from the PM Suspend and |
312 | Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | 328 | Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> |
313 | for more information. | 329 | for more information. |
314 | 330 | ||
315 | config S3C_PM_DEBUG_LED_SMDK | 331 | config S3C_PM_DEBUG_LED_SMDK |
316 | bool "SMDK LED suspend/resume debugging" | 332 | bool "SMDK LED suspend/resume debugging" |
317 | depends on PM && (MACH_SMDK6410) | 333 | depends on PM && (MACH_SMDK6410) |
318 | help | 334 | help |
319 | Say Y here to enable the use of the SMDK LEDs on the baseboard | 335 | Say Y here to enable the use of the SMDK LEDs on the baseboard |
320 | for debugging of the state of the suspend and resume process. | 336 | for debugging of the state of the suspend and resume process. |
321 | 337 | ||
322 | Note, this currently only works for S3C64XX based SMDK boards. | 338 | Note, this currently only works for S3C64XX based SMDK boards. |
323 | 339 | ||
324 | config SAMSUNG_PM_CHECK | 340 | config SAMSUNG_PM_CHECK |
325 | bool "S3C2410 PM Suspend Memory CRC" | 341 | bool "S3C2410 PM Suspend Memory CRC" |
326 | depends on PM && CRC32 | 342 | depends on PM && CRC32 |
327 | help | 343 | help |
328 | Enable the PM code's memory area checksum over sleep. This option | 344 | Enable the PM code's memory area checksum over sleep. This option |
329 | will generate CRCs of all blocks of memory, and store them before | 345 | will generate CRCs of all blocks of memory, and store them before |
330 | going to sleep. The blocks are then checked on resume for any | 346 | going to sleep. The blocks are then checked on resume for any |
331 | errors. | 347 | errors. |
332 | 348 | ||
333 | Note, this can take several seconds depending on memory size | 349 | Note, this can take several seconds depending on memory size |
334 | and CPU speed. | 350 | and CPU speed. |
335 | 351 | ||
336 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | 352 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> |
337 | 353 | ||
338 | config SAMSUNG_PM_CHECK_CHUNKSIZE | 354 | config SAMSUNG_PM_CHECK_CHUNKSIZE |
339 | int "S3C2410 PM Suspend CRC Chunksize (KiB)" | 355 | int "S3C2410 PM Suspend CRC Chunksize (KiB)" |
340 | depends on PM && SAMSUNG_PM_CHECK | 356 | depends on PM && SAMSUNG_PM_CHECK |
341 | default 64 | 357 | default 64 |
342 | help | 358 | help |
343 | Set the chunksize in Kilobytes of the CRC for checking memory | 359 | Set the chunksize in Kilobytes of the CRC for checking memory |
344 | corruption over suspend and resume. A smaller value will mean that | 360 | corruption over suspend and resume. A smaller value will mean that |
345 | the CRC data block will take more memory, but wil identify any | 361 | the CRC data block will take more memory, but wil identify any |
346 | faults with better precision. | 362 | faults with better precision. |
347 | 363 | ||
348 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> | 364 | See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> |
349 | 365 | ||
350 | config SAMSUNG_WAKEMASK | 366 | config SAMSUNG_WAKEMASK |
351 | bool | 367 | bool |
352 | depends on PM | 368 | depends on PM |
353 | help | 369 | help |
354 | Compile support for wakeup-mask controls found on the S3C6400 | 370 | Compile support for wakeup-mask controls found on the S3C6400 |
355 | and above. This code allows a set of interrupt to wakeup-mask | 371 | and above. This code allows a set of interrupt to wakeup-mask |
356 | mappings. See <plat/wakeup-mask.h> | 372 | mappings. See <plat/wakeup-mask.h> |
357 | 373 | ||
358 | comment "Power Domain" | 374 | comment "Power Domain" |
359 | 375 | ||
360 | config SAMSUNG_PD | 376 | config SAMSUNG_PD |
361 | bool "Samsung Power Domain" | 377 | bool "Samsung Power Domain" |
362 | depends on PM_RUNTIME | 378 | depends on PM_RUNTIME |
363 | help | 379 | help |
364 | Say Y here if you want to control Power Domain by Runtime PM. | 380 | Say Y here if you want to control Power Domain by Runtime PM. |
365 | 381 | ||
366 | config DEBUG_S3C_UART | 382 | config DEBUG_S3C_UART |
367 | depends on PLAT_SAMSUNG | 383 | depends on PLAT_SAMSUNG |
368 | int | 384 | int |
369 | default "0" if DEBUG_S3C_UART0 | 385 | default "0" if DEBUG_S3C_UART0 |
370 | default "1" if DEBUG_S3C_UART1 | 386 | default "1" if DEBUG_S3C_UART1 |
371 | default "2" if DEBUG_S3C_UART2 | 387 | default "2" if DEBUG_S3C_UART2 |
372 | 388 | ||
373 | endif | 389 | endif |
374 | 390 |
arch/arm/plat-samsung/Makefile
1 | # arch/arm/plat-samsung/Makefile | 1 | # arch/arm/plat-samsung/Makefile |
2 | # | 2 | # |
3 | # Copyright 2009 Simtec Electronics | 3 | # Copyright 2009 Simtec Electronics |
4 | # | 4 | # |
5 | # Licensed under GPLv2 | 5 | # Licensed under GPLv2 |
6 | 6 | ||
7 | obj-y := | 7 | obj-y := |
8 | obj-m := | 8 | obj-m := |
9 | obj-n := dummy.o | 9 | obj-n := dummy.o |
10 | obj- := | 10 | obj- := |
11 | 11 | ||
12 | # Objects we always build independent of SoC choice | 12 | # Objects we always build independent of SoC choice |
13 | 13 | ||
14 | obj-y += init.o cpu.o | 14 | obj-y += init.o cpu.o |
15 | obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o | 15 | obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o |
16 | obj-y += clock.o | 16 | obj-y += clock.o |
17 | obj-y += pwm-clock.o | 17 | obj-y += pwm-clock.o |
18 | 18 | ||
19 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o | 19 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o |
20 | obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o | 20 | obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o |
21 | 21 | ||
22 | obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o | 22 | obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o |
23 | obj-$(CONFIG_S5P_IRQ) += s5p-irq.o | ||
24 | obj-$(CONFIG_S5P_EXT_INT) += s5p-irq-eint.o | ||
25 | obj-$(CONFIG_S5P_GPIO_INT) += s5p-irq-gpioint.o | ||
23 | 26 | ||
24 | # ADC | 27 | # ADC |
25 | 28 | ||
26 | obj-$(CONFIG_S3C_ADC) += adc.o | 29 | obj-$(CONFIG_S3C_ADC) += adc.o |
27 | 30 | ||
28 | # devices | 31 | # devices |
29 | 32 | ||
30 | obj-y += platformdata.o | 33 | obj-y += platformdata.o |
31 | 34 | ||
32 | obj-y += devs.o | 35 | obj-y += devs.o |
33 | obj-y += dev-uart.o | 36 | obj-y += dev-uart.o |
34 | 37 | ||
35 | obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o | 38 | obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o |
36 | 39 | ||
37 | # DMA support | 40 | # DMA support |
38 | 41 | ||
39 | obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o | 42 | obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o |
40 | 43 | ||
41 | obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o | 44 | obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o |
42 | 45 | ||
43 | # PM support | 46 | # PM support |
44 | 47 | ||
45 | obj-$(CONFIG_PM) += pm.o | 48 | obj-$(CONFIG_PM) += pm.o |
46 | obj-$(CONFIG_PM) += pm-gpio.o | 49 | obj-$(CONFIG_PM) += pm-gpio.o |
47 | obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o | 50 | obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o |
48 | 51 | ||
49 | obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o | 52 | obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o |
50 | 53 | ||
51 | # PD support | 54 | # PD support |
52 | 55 | ||
53 | obj-$(CONFIG_SAMSUNG_PD) += pd.o | 56 | obj-$(CONFIG_SAMSUNG_PD) += pd.o |
54 | 57 | ||
55 | # PWM support | 58 | # PWM support |
56 | 59 | ||
57 | obj-$(CONFIG_HAVE_PWM) += pwm.o | 60 | obj-$(CONFIG_HAVE_PWM) += pwm.o |
58 | 61 |
arch/arm/plat-samsung/s5p-irq-eint.c
File was created | 1 | /* | |
2 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * S5P - IRQ EINT support | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <asm/hardware/vic.h> | ||
20 | |||
21 | #include <plat/regs-irqtype.h> | ||
22 | |||
23 | #include <mach/map.h> | ||
24 | #include <plat/cpu.h> | ||
25 | #include <plat/pm.h> | ||
26 | |||
27 | #include <plat/gpio-cfg.h> | ||
28 | #include <mach/regs-gpio.h> | ||
29 | |||
30 | static inline void s5p_irq_eint_mask(struct irq_data *data) | ||
31 | { | ||
32 | u32 mask; | ||
33 | |||
34 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
35 | mask |= eint_irq_to_bit(data->irq); | ||
36 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
37 | } | ||
38 | |||
39 | static void s5p_irq_eint_unmask(struct irq_data *data) | ||
40 | { | ||
41 | u32 mask; | ||
42 | |||
43 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
44 | mask &= ~(eint_irq_to_bit(data->irq)); | ||
45 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
46 | } | ||
47 | |||
48 | static inline void s5p_irq_eint_ack(struct irq_data *data) | ||
49 | { | ||
50 | __raw_writel(eint_irq_to_bit(data->irq), | ||
51 | S5P_EINT_PEND(EINT_REG_NR(data->irq))); | ||
52 | } | ||
53 | |||
54 | static void s5p_irq_eint_maskack(struct irq_data *data) | ||
55 | { | ||
56 | /* compiler should in-line these */ | ||
57 | s5p_irq_eint_mask(data); | ||
58 | s5p_irq_eint_ack(data); | ||
59 | } | ||
60 | |||
61 | static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) | ||
62 | { | ||
63 | int offs = EINT_OFFSET(data->irq); | ||
64 | int shift; | ||
65 | u32 ctrl, mask; | ||
66 | u32 newvalue = 0; | ||
67 | |||
68 | switch (type) { | ||
69 | case IRQ_TYPE_EDGE_RISING: | ||
70 | newvalue = S5P_IRQ_TYPE_EDGE_RISING; | ||
71 | break; | ||
72 | |||
73 | case IRQ_TYPE_EDGE_FALLING: | ||
74 | newvalue = S5P_IRQ_TYPE_EDGE_FALLING; | ||
75 | break; | ||
76 | |||
77 | case IRQ_TYPE_EDGE_BOTH: | ||
78 | newvalue = S5P_IRQ_TYPE_EDGE_BOTH; | ||
79 | break; | ||
80 | |||
81 | case IRQ_TYPE_LEVEL_LOW: | ||
82 | newvalue = S5P_IRQ_TYPE_LEVEL_LOW; | ||
83 | break; | ||
84 | |||
85 | case IRQ_TYPE_LEVEL_HIGH: | ||
86 | newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; | ||
87 | break; | ||
88 | |||
89 | default: | ||
90 | printk(KERN_ERR "No such irq type %d", type); | ||
91 | return -EINVAL; | ||
92 | } | ||
93 | |||
94 | shift = (offs & 0x7) * 4; | ||
95 | mask = 0x7 << shift; | ||
96 | |||
97 | ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); | ||
98 | ctrl &= ~mask; | ||
99 | ctrl |= newvalue << shift; | ||
100 | __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); | ||
101 | |||
102 | if ((0 <= offs) && (offs < 8)) | ||
103 | s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); | ||
104 | |||
105 | else if ((8 <= offs) && (offs < 16)) | ||
106 | s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); | ||
107 | |||
108 | else if ((16 <= offs) && (offs < 24)) | ||
109 | s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); | ||
110 | |||
111 | else if ((24 <= offs) && (offs < 32)) | ||
112 | s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); | ||
113 | |||
114 | else | ||
115 | printk(KERN_ERR "No such irq number %d", offs); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static struct irq_chip s5p_irq_eint = { | ||
121 | .name = "s5p-eint", | ||
122 | .irq_mask = s5p_irq_eint_mask, | ||
123 | .irq_unmask = s5p_irq_eint_unmask, | ||
124 | .irq_mask_ack = s5p_irq_eint_maskack, | ||
125 | .irq_ack = s5p_irq_eint_ack, | ||
126 | .irq_set_type = s5p_irq_eint_set_type, | ||
127 | #ifdef CONFIG_PM | ||
128 | .irq_set_wake = s3c_irqext_wake, | ||
129 | #endif | ||
130 | }; | ||
131 | |||
132 | /* s5p_irq_demux_eint | ||
133 | * | ||
134 | * This function demuxes the IRQ from the group0 external interrupts, | ||
135 | * from EINTs 16 to 31. It is designed to be inlined into the specific | ||
136 | * handler s5p_irq_demux_eintX_Y. | ||
137 | * | ||
138 | * Each EINT pend/mask registers handle eight of them. | ||
139 | */ | ||
140 | static inline void s5p_irq_demux_eint(unsigned int start) | ||
141 | { | ||
142 | u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); | ||
143 | u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); | ||
144 | unsigned int irq; | ||
145 | |||
146 | status &= ~mask; | ||
147 | status &= 0xff; | ||
148 | |||
149 | while (status) { | ||
150 | irq = fls(status) - 1; | ||
151 | generic_handle_irq(irq + start); | ||
152 | status &= ~(1 << irq); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | ||
157 | { | ||
158 | s5p_irq_demux_eint(IRQ_EINT(16)); | ||
159 | s5p_irq_demux_eint(IRQ_EINT(24)); | ||
160 | } | ||
161 | |||
162 | static inline void s5p_irq_vic_eint_mask(struct irq_data *data) | ||
163 | { | ||
164 | void __iomem *base = irq_data_get_irq_chip_data(data); | ||
165 | |||
166 | s5p_irq_eint_mask(data); | ||
167 | writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR); | ||
168 | } | ||
169 | |||
170 | static void s5p_irq_vic_eint_unmask(struct irq_data *data) | ||
171 | { | ||
172 | void __iomem *base = irq_data_get_irq_chip_data(data); | ||
173 | |||
174 | s5p_irq_eint_unmask(data); | ||
175 | writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE); | ||
176 | } | ||
177 | |||
178 | static inline void s5p_irq_vic_eint_ack(struct irq_data *data) | ||
179 | { | ||
180 | __raw_writel(eint_irq_to_bit(data->irq), | ||
181 | S5P_EINT_PEND(EINT_REG_NR(data->irq))); | ||
182 | } | ||
183 | |||
184 | static void s5p_irq_vic_eint_maskack(struct irq_data *data) | ||
185 | { | ||
186 | s5p_irq_vic_eint_mask(data); | ||
187 | s5p_irq_vic_eint_ack(data); | ||
188 | } | ||
189 | |||
190 | static struct irq_chip s5p_irq_vic_eint = { | ||
191 | .name = "s5p_vic_eint", | ||
192 | .irq_mask = s5p_irq_vic_eint_mask, | ||
193 | .irq_unmask = s5p_irq_vic_eint_unmask, | ||
194 | .irq_mask_ack = s5p_irq_vic_eint_maskack, | ||
195 | .irq_ack = s5p_irq_vic_eint_ack, | ||
196 | .irq_set_type = s5p_irq_eint_set_type, | ||
197 | #ifdef CONFIG_PM | ||
198 | .irq_set_wake = s3c_irqext_wake, | ||
199 | #endif | ||
200 | }; | ||
201 | |||
202 | static int __init s5p_init_irq_eint(void) | ||
203 | { | ||
204 | int irq; | ||
205 | |||
206 | for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++) | ||
207 | irq_set_chip(irq, &s5p_irq_vic_eint); | ||
208 | |||
209 | for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) { | ||
210 | irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq); | ||
211 | set_irq_flags(irq, IRQF_VALID); | ||
212 | } | ||
213 | |||
214 | irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | arch_initcall(s5p_init_irq_eint); | ||
219 |
arch/arm/plat-samsung/s5p-irq-gpioint.c
File was created | 1 | /* | |
2 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
3 | * Author: Kyungmin Park <kyungmin.park@samsung.com> | ||
4 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
5 | * Author: Marek Szyprowski <m.szyprowski@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <mach/map.h> | ||
22 | #include <plat/gpio-core.h> | ||
23 | #include <plat/gpio-cfg.h> | ||
24 | |||
25 | #include <asm/mach/irq.h> | ||
26 | |||
27 | #define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) | ||
28 | |||
29 | #define CON_OFFSET 0x700 | ||
30 | #define MASK_OFFSET 0x900 | ||
31 | #define PEND_OFFSET 0xA00 | ||
32 | #define REG_OFFSET(x) ((x) << 2) | ||
33 | |||
34 | struct s5p_gpioint_bank { | ||
35 | struct list_head list; | ||
36 | int start; | ||
37 | int nr_groups; | ||
38 | int irq; | ||
39 | struct samsung_gpio_chip **chips; | ||
40 | void (*handler)(unsigned int, struct irq_desc *); | ||
41 | }; | ||
42 | |||
43 | static LIST_HEAD(banks); | ||
44 | |||
45 | static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) | ||
46 | { | ||
47 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
48 | struct irq_chip_type *ct = gc->chip_types; | ||
49 | unsigned int shift = (d->irq - gc->irq_base) << 2; | ||
50 | |||
51 | switch (type) { | ||
52 | case IRQ_TYPE_EDGE_RISING: | ||
53 | type = S5P_IRQ_TYPE_EDGE_RISING; | ||
54 | break; | ||
55 | case IRQ_TYPE_EDGE_FALLING: | ||
56 | type = S5P_IRQ_TYPE_EDGE_FALLING; | ||
57 | break; | ||
58 | case IRQ_TYPE_EDGE_BOTH: | ||
59 | type = S5P_IRQ_TYPE_EDGE_BOTH; | ||
60 | break; | ||
61 | case IRQ_TYPE_LEVEL_HIGH: | ||
62 | type = S5P_IRQ_TYPE_LEVEL_HIGH; | ||
63 | break; | ||
64 | case IRQ_TYPE_LEVEL_LOW: | ||
65 | type = S5P_IRQ_TYPE_LEVEL_LOW; | ||
66 | break; | ||
67 | case IRQ_TYPE_NONE: | ||
68 | default: | ||
69 | printk(KERN_WARNING "No irq type\n"); | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | gc->type_cache &= ~(0x7 << shift); | ||
74 | gc->type_cache |= type << shift; | ||
75 | writel(gc->type_cache, gc->reg_base + ct->regs.type); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) | ||
80 | { | ||
81 | struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); | ||
82 | int group, pend_offset, mask_offset; | ||
83 | unsigned int pend, mask; | ||
84 | |||
85 | struct irq_chip *chip = irq_get_chip(irq); | ||
86 | chained_irq_enter(chip, desc); | ||
87 | |||
88 | for (group = 0; group < bank->nr_groups; group++) { | ||
89 | struct samsung_gpio_chip *chip = bank->chips[group]; | ||
90 | if (!chip) | ||
91 | continue; | ||
92 | |||
93 | pend_offset = REG_OFFSET(group); | ||
94 | pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); | ||
95 | if (!pend) | ||
96 | continue; | ||
97 | |||
98 | mask_offset = REG_OFFSET(group); | ||
99 | mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); | ||
100 | pend &= ~mask; | ||
101 | |||
102 | while (pend) { | ||
103 | int offset = fls(pend) - 1; | ||
104 | int real_irq = chip->irq_base + offset; | ||
105 | generic_handle_irq(real_irq); | ||
106 | pend &= ~BIT(offset); | ||
107 | } | ||
108 | } | ||
109 | chained_irq_exit(chip, desc); | ||
110 | } | ||
111 | |||
112 | static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip) | ||
113 | { | ||
114 | static int used_gpioint_groups = 0; | ||
115 | int group = chip->group; | ||
116 | struct s5p_gpioint_bank *b, *bank = NULL; | ||
117 | struct irq_chip_generic *gc; | ||
118 | struct irq_chip_type *ct; | ||
119 | |||
120 | if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) | ||
121 | return -ENOMEM; | ||
122 | |||
123 | list_for_each_entry(b, &banks, list) { | ||
124 | if (group >= b->start && group < b->start + b->nr_groups) { | ||
125 | bank = b; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | if (!bank) | ||
130 | return -EINVAL; | ||
131 | |||
132 | if (!bank->handler) { | ||
133 | bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) * | ||
134 | bank->nr_groups, GFP_KERNEL); | ||
135 | if (!bank->chips) | ||
136 | return -ENOMEM; | ||
137 | |||
138 | irq_set_chained_handler(bank->irq, s5p_gpioint_handler); | ||
139 | irq_set_handler_data(bank->irq, bank); | ||
140 | bank->handler = s5p_gpioint_handler; | ||
141 | printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n", | ||
142 | bank->irq); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * chained GPIO irq has been successfully registered, allocate new gpio | ||
147 | * int group and assign irq nubmers | ||
148 | */ | ||
149 | chip->irq_base = S5P_GPIOINT_BASE + | ||
150 | used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; | ||
151 | used_gpioint_groups++; | ||
152 | |||
153 | bank->chips[group - bank->start] = chip; | ||
154 | |||
155 | gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, | ||
156 | (void __iomem *)GPIO_BASE(chip), | ||
157 | handle_level_irq); | ||
158 | if (!gc) | ||
159 | return -ENOMEM; | ||
160 | ct = gc->chip_types; | ||
161 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
162 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
163 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
164 | ct->chip.irq_set_type = s5p_gpioint_set_type, | ||
165 | ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start); | ||
166 | ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start); | ||
167 | ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start); | ||
168 | irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), | ||
169 | IRQ_GC_INIT_MASK_CACHE, | ||
170 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | int __init s5p_register_gpio_interrupt(int pin) | ||
175 | { | ||
176 | struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin); | ||
177 | int offset, group; | ||
178 | int ret; | ||
179 | |||
180 | if (!my_chip) | ||
181 | return -EINVAL; | ||
182 | |||
183 | offset = pin - my_chip->chip.base; | ||
184 | group = my_chip->group; | ||
185 | |||
186 | /* check if the group has been already registered */ | ||
187 | if (my_chip->irq_base) | ||
188 | return my_chip->irq_base + offset; | ||
189 | |||
190 | /* register gpio group */ | ||
191 | ret = s5p_gpioint_add(my_chip); | ||
192 | if (ret == 0) { | ||
193 | my_chip->chip.to_irq = samsung_gpiolib_to_irq; | ||
194 | printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", | ||
195 | group); | ||
196 | return my_chip->irq_base + offset; | ||
197 | } | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups) | ||
202 | { | ||
203 | struct s5p_gpioint_bank *bank; | ||
204 | |||
205 | bank = kzalloc(sizeof(*bank), GFP_KERNEL); | ||
206 | if (!bank) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | bank->start = start; | ||
210 | bank->nr_groups = nr_groups; | ||
211 | bank->irq = chain_irq; | ||
212 | |||
213 | list_add_tail(&bank->list, &banks); | ||
214 | return 0; | ||
215 | } | ||
216 |
arch/arm/plat-samsung/s5p-irq.c
File was created | 1 | /* | |
2 | * Copyright (c) 2009 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com/ | ||
4 | * | ||
5 | * S5P - Interrupt handling | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/io.h> | ||
16 | |||
17 | #include <asm/hardware/vic.h> | ||
18 | |||
19 | #include <mach/map.h> | ||
20 | #include <plat/regs-timer.h> | ||
21 | #include <plat/cpu.h> | ||
22 | #include <plat/irq-vic-timer.h> | ||
23 | |||
24 | void __init s5p_init_irq(u32 *vic, u32 num_vic) | ||
25 | { | ||
26 | #ifdef CONFIG_ARM_VIC | ||
27 | int irq; | ||
28 | |||
29 | /* initialize the VICs */ | ||
30 | for (irq = 0; irq < num_vic; irq++) | ||
31 | vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); | ||
32 | #endif | ||
33 | |||
34 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); | ||
35 | } | ||
36 |