diff options
Diffstat (limited to 'arch/arm/mach-mx3/mx31ads.c')
-rw-r--r-- | arch/arm/mach-mx3/mx31ads.c | 120 |
1 files changed, 116 insertions, 4 deletions
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 60fb4e0d5acd..1be4a390c63f 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/serial_8250.h> | 24 | #include <linux/serial_8250.h> |
25 | #include <linux/irq.h> | ||
25 | 26 | ||
26 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
27 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
@@ -31,6 +32,8 @@ | |||
31 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
32 | #include <mach/common.h> | 33 | #include <mach/common.h> |
33 | #include <mach/board-mx31ads.h> | 34 | #include <mach/board-mx31ads.h> |
35 | #include <mach/imx-uart.h> | ||
36 | #include <mach/iomux-mx3.h> | ||
34 | 37 | ||
35 | /*! | 38 | /*! |
36 | * @file mx31ads.c | 39 | * @file mx31ads.c |
@@ -84,6 +87,108 @@ static inline int mxc_init_extuart(void) | |||
84 | } | 87 | } |
85 | #endif | 88 | #endif |
86 | 89 | ||
90 | #if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) | ||
91 | static struct imxuart_platform_data uart_pdata = { | ||
92 | .flags = IMXUART_HAVE_RTSCTS, | ||
93 | }; | ||
94 | |||
95 | static inline void mxc_init_imx_uart(void) | ||
96 | { | ||
97 | mxc_iomux_mode(MX31_PIN_CTS1__CTS1); | ||
98 | mxc_iomux_mode(MX31_PIN_RTS1__RTS1); | ||
99 | mxc_iomux_mode(MX31_PIN_TXD1__TXD1); | ||
100 | mxc_iomux_mode(MX31_PIN_RXD1__RXD1); | ||
101 | |||
102 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | ||
103 | } | ||
104 | #else /* !SERIAL_IMX */ | ||
105 | static inline void mxc_init_imx_uart(void) | ||
106 | { | ||
107 | } | ||
108 | #endif /* !SERIAL_IMX */ | ||
109 | |||
110 | static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc) | ||
111 | { | ||
112 | u32 imr_val; | ||
113 | u32 int_valid; | ||
114 | u32 expio_irq; | ||
115 | |||
116 | imr_val = __raw_readw(PBC_INTMASK_SET_REG); | ||
117 | int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; | ||
118 | |||
119 | expio_irq = MXC_EXP_IO_BASE; | ||
120 | for (; int_valid != 0; int_valid >>= 1, expio_irq++) { | ||
121 | if ((int_valid & 1) == 0) | ||
122 | continue; | ||
123 | |||
124 | generic_handle_irq(expio_irq); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Disable an expio pin's interrupt by setting the bit in the imr. | ||
130 | * @param irq an expio virtual irq number | ||
131 | */ | ||
132 | static void expio_mask_irq(u32 irq) | ||
133 | { | ||
134 | u32 expio = MXC_IRQ_TO_EXPIO(irq); | ||
135 | /* mask the interrupt */ | ||
136 | __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); | ||
137 | __raw_readw(PBC_INTMASK_CLEAR_REG); | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr. | ||
142 | * @param irq an expanded io virtual irq number | ||
143 | */ | ||
144 | static void expio_ack_irq(u32 irq) | ||
145 | { | ||
146 | u32 expio = MXC_IRQ_TO_EXPIO(irq); | ||
147 | /* clear the interrupt status */ | ||
148 | __raw_writew(1 << expio, PBC_INTSTATUS_REG); | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * Enable a expio pin's interrupt by clearing the bit in the imr. | ||
153 | * @param irq a expio virtual irq number | ||
154 | */ | ||
155 | static void expio_unmask_irq(u32 irq) | ||
156 | { | ||
157 | u32 expio = MXC_IRQ_TO_EXPIO(irq); | ||
158 | /* unmask the interrupt */ | ||
159 | __raw_writew(1 << expio, PBC_INTMASK_SET_REG); | ||
160 | } | ||
161 | |||
162 | static struct irq_chip expio_irq_chip = { | ||
163 | .ack = expio_ack_irq, | ||
164 | .mask = expio_mask_irq, | ||
165 | .unmask = expio_unmask_irq, | ||
166 | }; | ||
167 | |||
168 | static void __init mx31ads_init_expio(void) | ||
169 | { | ||
170 | int i; | ||
171 | |||
172 | printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n"); | ||
173 | |||
174 | /* | ||
175 | * Configure INT line as GPIO input | ||
176 | */ | ||
177 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO)); | ||
178 | |||
179 | /* disable the interrupt and clear the status */ | ||
180 | __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); | ||
181 | __raw_writew(0xFFFF, PBC_INTSTATUS_REG); | ||
182 | for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); | ||
183 | i++) { | ||
184 | set_irq_chip(i, &expio_irq_chip); | ||
185 | set_irq_handler(i, handle_level_irq); | ||
186 | set_irq_flags(i, IRQF_VALID); | ||
187 | } | ||
188 | set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH); | ||
189 | set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler); | ||
190 | } | ||
191 | |||
87 | /*! | 192 | /*! |
88 | * This structure defines static mappings for the i.MX31ADS board. | 193 | * This structure defines static mappings for the i.MX31ADS board. |
89 | */ | 194 | */ |
@@ -92,17 +197,17 @@ static struct map_desc mx31ads_io_desc[] __initdata = { | |||
92 | .virtual = AIPS1_BASE_ADDR_VIRT, | 197 | .virtual = AIPS1_BASE_ADDR_VIRT, |
93 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | 198 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), |
94 | .length = AIPS1_SIZE, | 199 | .length = AIPS1_SIZE, |
95 | .type = MT_NONSHARED_DEVICE | 200 | .type = MT_DEVICE_NONSHARED |
96 | }, { | 201 | }, { |
97 | .virtual = SPBA0_BASE_ADDR_VIRT, | 202 | .virtual = SPBA0_BASE_ADDR_VIRT, |
98 | .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), | 203 | .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), |
99 | .length = SPBA0_SIZE, | 204 | .length = SPBA0_SIZE, |
100 | .type = MT_NONSHARED_DEVICE | 205 | .type = MT_DEVICE_NONSHARED |
101 | }, { | 206 | }, { |
102 | .virtual = AIPS2_BASE_ADDR_VIRT, | 207 | .virtual = AIPS2_BASE_ADDR_VIRT, |
103 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | 208 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), |
104 | .length = AIPS2_SIZE, | 209 | .length = AIPS2_SIZE, |
105 | .type = MT_NONSHARED_DEVICE | 210 | .type = MT_DEVICE_NONSHARED |
106 | }, { | 211 | }, { |
107 | .virtual = CS4_BASE_ADDR_VIRT, | 212 | .virtual = CS4_BASE_ADDR_VIRT, |
108 | .pfn = __phys_to_pfn(CS4_BASE_ADDR), | 213 | .pfn = __phys_to_pfn(CS4_BASE_ADDR), |
@@ -120,12 +225,19 @@ void __init mx31ads_map_io(void) | |||
120 | iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc)); | 225 | iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc)); |
121 | } | 226 | } |
122 | 227 | ||
228 | void __init mx31ads_init_irq(void) | ||
229 | { | ||
230 | mxc_init_irq(); | ||
231 | mx31ads_init_expio(); | ||
232 | } | ||
233 | |||
123 | /*! | 234 | /*! |
124 | * Board specific initialization. | 235 | * Board specific initialization. |
125 | */ | 236 | */ |
126 | static void __init mxc_board_init(void) | 237 | static void __init mxc_board_init(void) |
127 | { | 238 | { |
128 | mxc_init_extuart(); | 239 | mxc_init_extuart(); |
240 | mxc_init_imx_uart(); | ||
129 | } | 241 | } |
130 | 242 | ||
131 | static void __init mx31ads_timer_init(void) | 243 | static void __init mx31ads_timer_init(void) |
@@ -148,7 +260,7 @@ MACHINE_START(MX31ADS, "Freescale MX31ADS") | |||
148 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 260 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
149 | .boot_params = PHYS_OFFSET + 0x100, | 261 | .boot_params = PHYS_OFFSET + 0x100, |
150 | .map_io = mx31ads_map_io, | 262 | .map_io = mx31ads_map_io, |
151 | .init_irq = mxc_init_irq, | 263 | .init_irq = mx31ads_init_irq, |
152 | .init_machine = mxc_board_init, | 264 | .init_machine = mxc_board_init, |
153 | .timer = &mx31ads_timer, | 265 | .timer = &mx31ads_timer, |
154 | MACHINE_END | 266 | MACHINE_END |