Commit 43835aac4803d459dd73fabce09b27a826a381d7
1 parent
e8143e72e1
Exists in
master
and in
55 other branches
Added interrupt handling capabilities for mpc5xxx processors.
Also added Linux like BUG() macros.
Showing 3 changed files with 342 additions and 15 deletions Side-by-side Diff
cpu/mpc5xxx/interrupts.c
1 | 1 | /* |
2 | + * (C) Copyright 2006 | |
3 | + * Detlev Zundel, DENX Software Engineering, dzu@denx.de | |
4 | + * | |
2 | 5 | * (C) Copyright -2003 |
3 | 6 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | 7 | * |
5 | 8 | |
6 | 9 | |
7 | 10 | |
8 | 11 | |
... | ... | @@ -24,18 +27,212 @@ |
24 | 27 | * MA 02111-1307 USA |
25 | 28 | */ |
26 | 29 | |
27 | -/* | |
28 | - * interrupts.c - just enough support for the decrementer/timer | |
30 | +/* this section was ripped out of arch/ppc/syslib/mpc52xx_pic.c in the | |
31 | + * Linux 2.6 source with the following copyright. | |
32 | + * | |
33 | + * Based on (well, mostly copied from) the code from the 2.4 kernel by | |
34 | + * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg. | |
35 | + * | |
36 | + * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com> | |
37 | + * Copyright (C) 2003 Montavista Software, Inc | |
29 | 38 | */ |
30 | 39 | |
31 | 40 | #include <common.h> |
32 | 41 | #include <asm/processor.h> |
42 | +#include <asm/io.h> | |
33 | 43 | #include <command.h> |
34 | 44 | |
35 | -int interrupt_init_cpu (ulong *decrementer_count) | |
45 | +struct irq_action { | |
46 | + interrupt_handler_t *handler; | |
47 | + void *arg; | |
48 | + ulong count; | |
49 | +}; | |
50 | + | |
51 | +static struct irq_action irq_handlers[NR_IRQS]; | |
52 | + | |
53 | +static struct mpc5xxx_intr *intr; | |
54 | +static struct mpc5xxx_sdma *sdma; | |
55 | + | |
56 | +static void mpc5xxx_ic_disable(unsigned int irq) | |
36 | 57 | { |
58 | + u32 val; | |
59 | + | |
60 | + if (irq == MPC5XXX_IRQ0) { | |
61 | + val = in_be32(&intr->ctrl); | |
62 | + val &= ~(1 << 11); | |
63 | + out_be32(&intr->ctrl, val); | |
64 | + } else if (irq < MPC5XXX_IRQ1) { | |
65 | + BUG(); | |
66 | + } else if (irq <= MPC5XXX_IRQ3) { | |
67 | + val = in_be32(&intr->ctrl); | |
68 | + val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1))); | |
69 | + out_be32(&intr->ctrl, val); | |
70 | + } else if (irq < MPC5XXX_SDMA_IRQ_BASE) { | |
71 | + val = in_be32(&intr->main_mask); | |
72 | + val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)); | |
73 | + out_be32(&intr->main_mask, val); | |
74 | + } else if (irq < MPC5XXX_PERP_IRQ_BASE) { | |
75 | + val = in_be32(&sdma->IntMask); | |
76 | + val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE); | |
77 | + out_be32(&sdma->IntMask, val); | |
78 | + } else { | |
79 | + val = in_be32(&intr->per_mask); | |
80 | + val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)); | |
81 | + out_be32(&intr->per_mask, val); | |
82 | + } | |
83 | +} | |
84 | + | |
85 | +static void mpc5xxx_ic_enable(unsigned int irq) | |
86 | +{ | |
87 | + u32 val; | |
88 | + | |
89 | + if (irq == MPC5XXX_IRQ0) { | |
90 | + val = in_be32(&intr->ctrl); | |
91 | + val |= 1 << 11; | |
92 | + out_be32(&intr->ctrl, val); | |
93 | + } else if (irq < MPC5XXX_IRQ1) { | |
94 | + BUG(); | |
95 | + } else if (irq <= MPC5XXX_IRQ3) { | |
96 | + val = in_be32(&intr->ctrl); | |
97 | + val |= 1 << (10 - (irq - MPC5XXX_IRQ1)); | |
98 | + out_be32(&intr->ctrl, val); | |
99 | + } else if (irq < MPC5XXX_SDMA_IRQ_BASE) { | |
100 | + val = in_be32(&intr->main_mask); | |
101 | + val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE))); | |
102 | + out_be32(&intr->main_mask, val); | |
103 | + } else if (irq < MPC5XXX_PERP_IRQ_BASE) { | |
104 | + val = in_be32(&sdma->IntMask); | |
105 | + val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE)); | |
106 | + out_be32(&sdma->IntMask, val); | |
107 | + } else { | |
108 | + val = in_be32(&intr->per_mask); | |
109 | + val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE))); | |
110 | + out_be32(&intr->per_mask, val); | |
111 | + } | |
112 | +} | |
113 | + | |
114 | +static void mpc5xxx_ic_ack(unsigned int irq) | |
115 | +{ | |
116 | + u32 val; | |
117 | + | |
118 | + /* | |
119 | + * Only some irqs are reset here, others in interrupting hardware. | |
120 | + */ | |
121 | + | |
122 | + switch (irq) { | |
123 | + case MPC5XXX_IRQ0: | |
124 | + val = in_be32(&intr->ctrl); | |
125 | + val |= 0x08000000; | |
126 | + out_be32(&intr->ctrl, val); | |
127 | + break; | |
128 | + case MPC5XXX_CCS_IRQ: | |
129 | + val = in_be32(&intr->enc_status); | |
130 | + val |= 0x00000400; | |
131 | + out_be32(&intr->enc_status, val); | |
132 | + break; | |
133 | + case MPC5XXX_IRQ1: | |
134 | + val = in_be32(&intr->ctrl); | |
135 | + val |= 0x04000000; | |
136 | + out_be32(&intr->ctrl, val); | |
137 | + break; | |
138 | + case MPC5XXX_IRQ2: | |
139 | + val = in_be32(&intr->ctrl); | |
140 | + val |= 0x02000000; | |
141 | + out_be32(&intr->ctrl, val); | |
142 | + break; | |
143 | + case MPC5XXX_IRQ3: | |
144 | + val = in_be32(&intr->ctrl); | |
145 | + val |= 0x01000000; | |
146 | + out_be32(&intr->ctrl, val); | |
147 | + break; | |
148 | + default: | |
149 | + if (irq >= MPC5XXX_SDMA_IRQ_BASE | |
150 | + && irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) { | |
151 | + out_be32(&sdma->IntPend, | |
152 | + 1 << (irq - MPC5XXX_SDMA_IRQ_BASE)); | |
153 | + } | |
154 | + break; | |
155 | + } | |
156 | +} | |
157 | + | |
158 | +static void mpc5xxx_ic_disable_and_ack(unsigned int irq) | |
159 | +{ | |
160 | + mpc5xxx_ic_disable(irq); | |
161 | + mpc5xxx_ic_ack(irq); | |
162 | +} | |
163 | + | |
164 | +static void mpc5xxx_ic_end(unsigned int irq) | |
165 | +{ | |
166 | + mpc5xxx_ic_enable(irq); | |
167 | +} | |
168 | + | |
169 | +void mpc5xxx_init_irq(void) | |
170 | +{ | |
171 | + u32 intr_ctrl; | |
172 | + | |
173 | + /* Remap the necessary zones */ | |
174 | + intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL); | |
175 | + sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA); | |
176 | + | |
177 | + /* Disable all interrupt sources. */ | |
178 | + out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */ | |
179 | + out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */ | |
180 | + out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */ | |
181 | + out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */ | |
182 | + intr_ctrl = in_be32(&intr->ctrl); | |
183 | + intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */ | |
184 | + 0x00ff0000 | /* IRQ 0-3 level sensitive low active */ | |
185 | + 0x00001000 | /* MEE master external enable */ | |
186 | + 0x00000000 | /* 0 means disable IRQ 0-3 */ | |
187 | + 0x00000001; /* CEb route critical normally */ | |
188 | + out_be32(&intr->ctrl, intr_ctrl); | |
189 | + | |
190 | + /* Zero a bunch of the priority settings. */ | |
191 | + out_be32(&intr->per_pri1, 0); | |
192 | + out_be32(&intr->per_pri2, 0); | |
193 | + out_be32(&intr->per_pri3, 0); | |
194 | + out_be32(&intr->main_pri1, 0); | |
195 | + out_be32(&intr->main_pri2, 0); | |
196 | +} | |
197 | + | |
198 | +int mpc5xxx_get_irq(struct pt_regs *regs) | |
199 | +{ | |
200 | + u32 status; | |
201 | + int irq = -1; | |
202 | + | |
203 | + status = in_be32(&intr->enc_status); | |
204 | + | |
205 | + if (status & 0x00000400) { /* critical */ | |
206 | + irq = (status >> 8) & 0x3; | |
207 | + if (irq == 2) /* high priority peripheral */ | |
208 | + goto peripheral; | |
209 | + irq += MPC5XXX_CRIT_IRQ_BASE; | |
210 | + } else if (status & 0x00200000) { /* main */ | |
211 | + irq = (status >> 16) & 0x1f; | |
212 | + if (irq == 4) /* low priority peripheral */ | |
213 | + goto peripheral; | |
214 | + irq += MPC5XXX_MAIN_IRQ_BASE; | |
215 | + } else if (status & 0x20000000) { /* peripheral */ | |
216 | + peripheral: | |
217 | + irq = (status >> 24) & 0x1f; | |
218 | + if (irq == 0) { /* bestcomm */ | |
219 | + status = in_be32(&sdma->IntPend); | |
220 | + irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1; | |
221 | + } else | |
222 | + irq += MPC5XXX_PERP_IRQ_BASE; | |
223 | + } | |
224 | + | |
225 | + return irq; | |
226 | +} | |
227 | + | |
228 | +/****************************************************************************/ | |
229 | + | |
230 | +int interrupt_init_cpu(ulong * decrementer_count) | |
231 | +{ | |
37 | 232 | *decrementer_count = get_tbclk() / CFG_HZ; |
38 | 233 | |
234 | + mpc5xxx_init_irq(); | |
235 | + | |
39 | 236 | return (0); |
40 | 237 | } |
41 | 238 | |
42 | 239 | |
43 | 240 | |
... | ... | @@ -44,14 +241,32 @@ |
44 | 241 | /* |
45 | 242 | * Handle external interrupts |
46 | 243 | */ |
47 | -void | |
48 | -external_interrupt(struct pt_regs *regs) | |
244 | +void external_interrupt(struct pt_regs *regs) | |
49 | 245 | { |
50 | - puts("external_interrupt (oops!)\n"); | |
246 | + int irq, unmask = 1; | |
247 | + | |
248 | + irq = mpc5xxx_get_irq(regs); | |
249 | + | |
250 | + mpc5xxx_ic_disable_and_ack(irq); | |
251 | + | |
252 | + enable_interrupts(); | |
253 | + | |
254 | + if (irq_handlers[irq].handler != NULL) | |
255 | + (*irq_handlers[irq].handler) (irq_handlers[irq].arg); | |
256 | + else { | |
257 | + printf("\nBogus External Interrupt IRQ %d\n", irq); | |
258 | + /* | |
259 | + * turn off the bogus interrupt, otherwise it | |
260 | + * might repeat forever | |
261 | + */ | |
262 | + unmask = 0; | |
263 | + } | |
264 | + | |
265 | + if (unmask) | |
266 | + mpc5xxx_ic_end(irq); | |
51 | 267 | } |
52 | 268 | |
53 | -void | |
54 | -timer_interrupt_cpu (struct pt_regs *regs) | |
269 | +void timer_interrupt_cpu(struct pt_regs *regs) | |
55 | 270 | { |
56 | 271 | /* nothing to do here */ |
57 | 272 | return; |
58 | 273 | |
59 | 274 | |
60 | 275 | |
61 | 276 | |
62 | 277 | |
63 | 278 | |
64 | 279 | |
65 | 280 | |
... | ... | @@ -63,23 +278,70 @@ |
63 | 278 | * Install and free a interrupt handler. |
64 | 279 | */ |
65 | 280 | |
66 | -void | |
67 | -irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) | |
281 | +void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg) | |
68 | 282 | { |
283 | + if (irq < 0 || irq >= NR_IRQS) { | |
284 | + printf("irq_install_handler: bad irq number %d\n", irq); | |
285 | + return; | |
286 | + } | |
69 | 287 | |
288 | + if (irq_handlers[irq].handler != NULL) | |
289 | + printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n", | |
290 | + (ulong) handler, (ulong) irq_handlers[irq].handler); | |
291 | + | |
292 | + irq_handlers[irq].handler = handler; | |
293 | + irq_handlers[irq].arg = arg; | |
294 | + | |
295 | + mpc5xxx_ic_enable(irq); | |
70 | 296 | } |
71 | 297 | |
72 | -void | |
73 | -irq_free_handler(int vec) | |
298 | +void irq_free_handler(int irq) | |
74 | 299 | { |
300 | + if (irq < 0 || irq >= NR_IRQS) { | |
301 | + printf("irq_free_handler: bad irq number %d\n", irq); | |
302 | + return; | |
303 | + } | |
75 | 304 | |
305 | + mpc5xxx_ic_disable(irq); | |
306 | + | |
307 | + irq_handlers[irq].handler = NULL; | |
308 | + irq_handlers[irq].arg = NULL; | |
76 | 309 | } |
77 | 310 | |
78 | 311 | /****************************************************************************/ |
79 | 312 | |
80 | -void | |
81 | -do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) | |
313 | +#if (CONFIG_COMMANDS & CFG_CMD_IRQ) | |
314 | +void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) | |
82 | 315 | { |
83 | - puts("IRQ related functions are unimplemented currently.\n"); | |
316 | + int irq, re_enable; | |
317 | + u32 intr_ctrl; | |
318 | + char *irq_config[] = { "level sensitive, active high", | |
319 | + "edge sensitive, rising active edge", | |
320 | + "edge sensitive, falling active edge", | |
321 | + "level sensitive, active low" | |
322 | + }; | |
323 | + | |
324 | + re_enable = disable_interrupts(); | |
325 | + | |
326 | + intr_ctrl = in_be32(&intr->ctrl); | |
327 | + printf("Interrupt configuration:\n"); | |
328 | + | |
329 | + for (irq = 0; irq <= 3; irq++) { | |
330 | + printf("IRQ%d: %s\n", irq, | |
331 | + irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]); | |
332 | + } | |
333 | + | |
334 | + puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n"); | |
335 | + | |
336 | + for (irq = 0; irq < NR_IRQS; irq++) | |
337 | + if (irq_handlers[irq].handler != NULL) | |
338 | + printf("%02d %08lx %08lx %ld\n", irq, | |
339 | + (ulong) irq_handlers[irq].handler, | |
340 | + (ulong) irq_handlers[irq].arg, | |
341 | + irq_handlers[irq].count); | |
342 | + | |
343 | + if (re_enable) | |
344 | + enable_interrupts(); | |
84 | 345 | } |
346 | +#endif |
include/common.h
... | ... | @@ -109,6 +109,12 @@ |
109 | 109 | #define debugX(level,fmt,args...) |
110 | 110 | #endif /* DEBUG */ |
111 | 111 | |
112 | +#define BUG() do { \ | |
113 | + printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ | |
114 | + panic("BUG!"); \ | |
115 | +} while (0) | |
116 | +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) | |
117 | + | |
112 | 118 | typedef void (interrupt_handler_t)(void *); |
113 | 119 | |
114 | 120 | #include <asm/u-boot.h> /* boot information for Linux kernel */ |
include/mpc5xxx.h
... | ... | @@ -232,6 +232,65 @@ |
232 | 232 | #define MPC5XXX_ICTL_PER_STS (MPC5XXX_ICTL + 0x0030) |
233 | 233 | #define MPC5XXX_ICTL_BUS_STS (MPC5XXX_ICTL + 0x0038) |
234 | 234 | |
235 | +#define NR_IRQS 64 | |
236 | + | |
237 | +/* IRQ mapping - these are our logical IRQ numbers */ | |
238 | +#define MPC5XXX_CRIT_IRQ_NUM 4 | |
239 | +#define MPC5XXX_MAIN_IRQ_NUM 17 | |
240 | +#define MPC5XXX_SDMA_IRQ_NUM 17 | |
241 | +#define MPC5XXX_PERP_IRQ_NUM 23 | |
242 | + | |
243 | +#define MPC5XXX_CRIT_IRQ_BASE 1 | |
244 | +#define MPC5XXX_MAIN_IRQ_BASE (MPC5XXX_CRIT_IRQ_BASE + MPC5XXX_CRIT_IRQ_NUM) | |
245 | +#define MPC5XXX_SDMA_IRQ_BASE (MPC5XXX_MAIN_IRQ_BASE + MPC5XXX_MAIN_IRQ_NUM) | |
246 | +#define MPC5XXX_PERP_IRQ_BASE (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM) | |
247 | + | |
248 | +#define MPC5XXX_IRQ0 (MPC5XXX_CRIT_IRQ_BASE + 0) | |
249 | +#define MPC5XXX_SLICE_TIMER_0_IRQ (MPC5XXX_CRIT_IRQ_BASE + 1) | |
250 | +#define MPC5XXX_HI_INT_IRQ (MPC5XXX_CRIT_IRQ_BASE + 2) | |
251 | +#define MPC5XXX_CCS_IRQ (MPC5XXX_CRIT_IRQ_BASE + 3) | |
252 | + | |
253 | +#define MPC5XXX_IRQ1 (MPC5XXX_MAIN_IRQ_BASE + 1) | |
254 | +#define MPC5XXX_IRQ2 (MPC5XXX_MAIN_IRQ_BASE + 2) | |
255 | +#define MPC5XXX_IRQ3 (MPC5XXX_MAIN_IRQ_BASE + 3) | |
256 | +#define MPC5XXX_RTC_PINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 5) | |
257 | +#define MPC5XXX_RTC_SINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 6) | |
258 | +#define MPC5XXX_RTC_GPIO_STD_IRQ (MPC5XXX_MAIN_IRQ_BASE + 7) | |
259 | +#define MPC5XXX_RTC_GPIO_WKUP_IRQ (MPC5XXX_MAIN_IRQ_BASE + 8) | |
260 | +#define MPC5XXX_TMR0_IRQ (MPC5XXX_MAIN_IRQ_BASE + 9) | |
261 | +#define MPC5XXX_TMR1_IRQ (MPC5XXX_MAIN_IRQ_BASE + 10) | |
262 | +#define MPC5XXX_TMR2_IRQ (MPC5XXX_MAIN_IRQ_BASE + 11) | |
263 | +#define MPC5XXX_TMR3_IRQ (MPC5XXX_MAIN_IRQ_BASE + 12) | |
264 | +#define MPC5XXX_TMR4_IRQ (MPC5XXX_MAIN_IRQ_BASE + 13) | |
265 | +#define MPC5XXX_TMR5_IRQ (MPC5XXX_MAIN_IRQ_BASE + 14) | |
266 | +#define MPC5XXX_TMR6_IRQ (MPC5XXX_MAIN_IRQ_BASE + 15) | |
267 | +#define MPC5XXX_TMR7_IRQ (MPC5XXX_MAIN_IRQ_BASE + 16) | |
268 | + | |
269 | +#define MPC5XXX_SDMA_IRQ (MPC5XXX_PERP_IRQ_BASE + 0) | |
270 | +#define MPC5XXX_PSC1_IRQ (MPC5XXX_PERP_IRQ_BASE + 1) | |
271 | +#define MPC5XXX_PSC2_IRQ (MPC5XXX_PERP_IRQ_BASE + 2) | |
272 | +#define MPC5XXX_PSC3_IRQ (MPC5XXX_PERP_IRQ_BASE + 3) | |
273 | +#define MPC5XXX_PSC6_IRQ (MPC5XXX_PERP_IRQ_BASE + 4) | |
274 | +#define MPC5XXX_IRDA_IRQ (MPC5XXX_PERP_IRQ_BASE + 4) | |
275 | +#define MPC5XXX_FEC_IRQ (MPC5XXX_PERP_IRQ_BASE + 5) | |
276 | +#define MPC5XXX_USB_IRQ (MPC5XXX_PERP_IRQ_BASE + 6) | |
277 | +#define MPC5XXX_ATA_IRQ (MPC5XXX_PERP_IRQ_BASE + 7) | |
278 | +#define MPC5XXX_PCI_CNTRL_IRQ (MPC5XXX_PERP_IRQ_BASE + 8) | |
279 | +#define MPC5XXX_PCI_SCIRX_IRQ (MPC5XXX_PERP_IRQ_BASE + 9) | |
280 | +#define MPC5XXX_PCI_SCITX_IRQ (MPC5XXX_PERP_IRQ_BASE + 10) | |
281 | +#define MPC5XXX_PSC4_IRQ (MPC5XXX_PERP_IRQ_BASE + 11) | |
282 | +#define MPC5XXX_PSC5_IRQ (MPC5XXX_PERP_IRQ_BASE + 12) | |
283 | +#define MPC5XXX_SPI_MODF_IRQ (MPC5XXX_PERP_IRQ_BASE + 13) | |
284 | +#define MPC5XXX_SPI_SPIF_IRQ (MPC5XXX_PERP_IRQ_BASE + 14) | |
285 | +#define MPC5XXX_I2C1_IRQ (MPC5XXX_PERP_IRQ_BASE + 15) | |
286 | +#define MPC5XXX_I2C2_IRQ (MPC5XXX_PERP_IRQ_BASE + 16) | |
287 | +#define MPC5XXX_MSCAN1_IRQ (MPC5XXX_PERP_IRQ_BASE + 17) | |
288 | +#define MPC5XXX_MSCAN2_IRQ (MPC5XXX_PERP_IRQ_BASE + 18) | |
289 | +#define MPC5XXX_IR_RX_IRQ (MPC5XXX_PERP_IRQ_BASE + 19) | |
290 | +#define MPC5XXX_IR_TX_IRQ (MPC5XXX_PERP_IRQ_BASE + 20) | |
291 | +#define MPC5XXX_XLB_ARB_IRQ (MPC5XXX_PERP_IRQ_BASE + 21) | |
292 | +#define MPC5XXX_BDLC_IRQ (MPC5XXX_PERP_IRQ_BASE + 22) | |
293 | + | |
235 | 294 | /* General Purpose Timers registers */ |
236 | 295 | #define MPC5XXX_GPT0_ENABLE (MPC5XXX_GPT + 0x0) |
237 | 296 | #define MPC5XXX_GPT0_COUNTER (MPC5XXX_GPT + 0x4) |