]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/sh/kernel/cpu/sh4a/setup-shx3.c
UBUNTU: Ubuntu-4.13.0-45.50
[mirror_ubuntu-artful-kernel.git] / arch / sh / kernel / cpu / sh4a / setup-shx3.c
CommitLineData
2b1bd1ac 1/*
ccdaeb4c 2 * SH-X3 Prototype Setup
2b1bd1ac 3 *
f9d885c3 4 * Copyright (C) 2007 - 2010 Paul Mundt
2b1bd1ac
PM
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
96de1a8f 13#include <linux/serial_sci.h>
2b1bd1ac 14#include <linux/io.h>
742759ea 15#include <linux/gpio.h>
ccdaeb4c 16#include <linux/sh_timer.h>
d8be10bb 17#include <linux/sh_intc.h>
742759ea 18#include <cpu/shx3.h>
d6aee69c 19#include <asm/mmzone.h>
2b1bd1ac 20
15dfdddb
PM
21/*
22 * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
23 * INTEVT values overlap with the FPU EXPEVT ones, requiring special
24 * demuxing in the exception dispatch path.
25 *
26 * As this overlap is something that never should have made it in to
27 * silicon in the first place, we just refuse to deal with the port at
28 * all rather than adding infrastructure to hack around it.
29 */
a9571d7b 30static struct plat_sci_port scif0_platform_data = {
c3fa400b 31 .scscr = SCSCR_REIE,
a9571d7b 32 .type = PORT_SCIF,
d850acf9
LP
33};
34
35static struct resource scif0_resources[] = {
36 DEFINE_RES_MEM(0xffc30000, 0x100),
37 DEFINE_RES_IRQ(evt2irq(0x700)),
38 DEFINE_RES_IRQ(evt2irq(0x720)),
39 DEFINE_RES_IRQ(evt2irq(0x760)),
40 DEFINE_RES_IRQ(evt2irq(0x740)),
2b1bd1ac
PM
41};
42
a9571d7b 43static struct platform_device scif0_device = {
2b1bd1ac 44 .name = "sh-sci",
a9571d7b 45 .id = 0,
d850acf9
LP
46 .resource = scif0_resources,
47 .num_resources = ARRAY_SIZE(scif0_resources),
2b1bd1ac 48 .dev = {
a9571d7b
MD
49 .platform_data = &scif0_platform_data,
50 },
51};
52
53static struct plat_sci_port scif1_platform_data = {
c3fa400b 54 .scscr = SCSCR_REIE,
a9571d7b 55 .type = PORT_SCIF,
d850acf9
LP
56};
57
58static struct resource scif1_resources[] = {
59 DEFINE_RES_MEM(0xffc40000, 0x100),
60 DEFINE_RES_IRQ(evt2irq(0x780)),
61 DEFINE_RES_IRQ(evt2irq(0x7a0)),
62 DEFINE_RES_IRQ(evt2irq(0x7e0)),
63 DEFINE_RES_IRQ(evt2irq(0x7c0)),
a9571d7b
MD
64};
65
66static struct platform_device scif1_device = {
67 .name = "sh-sci",
68 .id = 1,
d850acf9
LP
69 .resource = scif1_resources,
70 .num_resources = ARRAY_SIZE(scif1_resources),
a9571d7b
MD
71 .dev = {
72 .platform_data = &scif1_platform_data,
73 },
74};
75
76static struct plat_sci_port scif2_platform_data = {
c3fa400b 77 .scscr = SCSCR_REIE,
a9571d7b 78 .type = PORT_SCIF,
d850acf9
LP
79};
80
81static struct resource scif2_resources[] = {
82 DEFINE_RES_MEM(0xffc60000, 0x100),
83 DEFINE_RES_IRQ(evt2irq(0x880)),
84 DEFINE_RES_IRQ(evt2irq(0x8a0)),
85 DEFINE_RES_IRQ(evt2irq(0x8e0)),
86 DEFINE_RES_IRQ(evt2irq(0x8c0)),
2b1bd1ac
PM
87};
88
a9571d7b 89static struct platform_device scif2_device = {
2b1bd1ac 90 .name = "sh-sci",
a9571d7b 91 .id = 2,
d850acf9
LP
92 .resource = scif2_resources,
93 .num_resources = ARRAY_SIZE(scif2_resources),
2b1bd1ac 94 .dev = {
a9571d7b 95 .platform_data = &scif2_platform_data,
2b1bd1ac
PM
96 },
97};
98
ccdaeb4c 99static struct sh_timer_config tmu0_platform_data = {
1399c195 100 .channels_mask = 7,
ccdaeb4c
PM
101};
102
103static struct resource tmu0_resources[] = {
1399c195
LP
104 DEFINE_RES_MEM(0xffc10000, 0x30),
105 DEFINE_RES_IRQ(evt2irq(0x400)),
106 DEFINE_RES_IRQ(evt2irq(0x420)),
107 DEFINE_RES_IRQ(evt2irq(0x440)),
ccdaeb4c
PM
108};
109
110static struct platform_device tmu0_device = {
1399c195 111 .name = "sh-tmu",
ccdaeb4c
PM
112 .id = 0,
113 .dev = {
114 .platform_data = &tmu0_platform_data,
115 },
116 .resource = tmu0_resources,
117 .num_resources = ARRAY_SIZE(tmu0_resources),
118};
119
120static struct sh_timer_config tmu1_platform_data = {
1399c195 121 .channels_mask = 7,
ccdaeb4c
PM
122};
123
124static struct resource tmu1_resources[] = {
1399c195
LP
125 DEFINE_RES_MEM(0xffc20000, 0x2c),
126 DEFINE_RES_IRQ(evt2irq(0x460)),
127 DEFINE_RES_IRQ(evt2irq(0x480)),
128 DEFINE_RES_IRQ(evt2irq(0x4a0)),
ccdaeb4c
PM
129};
130
131static struct platform_device tmu1_device = {
1399c195 132 .name = "sh-tmu",
ccdaeb4c
PM
133 .id = 1,
134 .dev = {
135 .platform_data = &tmu1_platform_data,
136 },
137 .resource = tmu1_resources,
138 .num_resources = ARRAY_SIZE(tmu1_resources),
139};
140
ccdaeb4c 141static struct platform_device *shx3_early_devices[] __initdata = {
a9571d7b
MD
142 &scif0_device,
143 &scif1_device,
144 &scif2_device,
ccdaeb4c
PM
145 &tmu0_device,
146 &tmu1_device,
ccdaeb4c
PM
147};
148
2b1bd1ac
PM
149static int __init shx3_devices_setup(void)
150{
a9571d7b 151 return platform_add_devices(shx3_early_devices,
ccdaeb4c 152 ARRAY_SIZE(shx3_early_devices));
2b1bd1ac 153}
955c9863 154arch_initcall(shx3_devices_setup);
2b1bd1ac 155
ccdaeb4c
PM
156void __init plat_early_device_setup(void)
157{
158 early_platform_add_devices(shx3_early_devices,
159 ARRAY_SIZE(shx3_early_devices));
160}
161
1ee01008
MD
162enum {
163 UNUSED = 0,
164
165 /* interrupt sources */
166 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
167 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
168 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
169 IRL_HHLL, IRL_HHLH, IRL_HHHL,
170 IRQ0, IRQ1, IRQ2, IRQ3,
171 HUDII,
172 TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
173 PCII0, PCII1, PCII2, PCII3, PCII4,
174 PCII5, PCII6, PCII7, PCII8, PCII9,
175 SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
176 SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
177 SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
178 SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
179 DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
180 DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
181 DU,
182 DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
183 DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
184 IIC, VIN0, VIN1, VCORE0, ATAPI,
3639dfb5 185 DTU0, DTU1, DTU2, DTU3,
1ee01008
MD
186 FE0, FE1,
187 GPIO0, GPIO1, GPIO2, GPIO3,
188 PAM, IRM,
46420e49
MD
189 INTICI0, INTICI1, INTICI2, INTICI3,
190 INTICI4, INTICI5, INTICI6, INTICI7,
1ee01008
MD
191
192 /* interrupt groups */
193 IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
3639dfb5 194 DMAC0, DMAC1,
2b1bd1ac
PM
195};
196
5c37e025 197static struct intc_vect vectors[] __initdata = {
1ee01008
MD
198 INTC_VECT(HUDII, 0x3e0),
199 INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
200 INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
201 INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
202 INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
203 INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
204 INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
205 INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
206 INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
207 INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
208 INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
209 INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
210 INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
1ee01008
MD
211 INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
212 INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
213 INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
214 INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
215 INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
216 INTC_VECT(DMAC0_DMAE, 0x9c0),
217 INTC_VECT(DU, 0x9e0),
218 INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
219 INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
220 INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
221 INTC_VECT(DMAC1_DMAE, 0xac0),
222 INTC_VECT(IIC, 0xae0),
223 INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
224 INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
3639dfb5
PM
225 INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
226 INTC_VECT(DTU0, 0xc40),
227 INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
228 INTC_VECT(DTU1, 0xca0),
229 INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
230 INTC_VECT(DTU2, 0xd00),
231 INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
232 INTC_VECT(DTU3, 0xd60),
1ee01008
MD
233 INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
234 INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
235 INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
236 INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
46420e49
MD
237 INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
238 INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
239 INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
240 INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
1ee01008 241};
2b1bd1ac 242
5c37e025 243static struct intc_group groups[] __initdata = {
1ee01008
MD
244 INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
245 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
246 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
247 IRL_HHLL, IRL_HHLH, IRL_HHHL),
248 INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
249 INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
250 INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
1ee01008
MD
251 INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
252 INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
253 DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
254 INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
255 DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
1ee01008 256};
2b1bd1ac 257
f9d885c3
PM
258#define INT2DISTCR0 0xfe4108a0
259#define INT2DISTCR1 0xfe4108a4
260#define INT2DISTCR2 0xfe4108a8
261
5c37e025 262static struct intc_mask_reg mask_registers[] __initdata = {
1ee01008
MD
263 { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
264 { IRQ0, IRQ1, IRQ2, IRQ3 } },
265 { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
266 { IRL } },
267 { 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
268 { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
269 DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
270 0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
f9d885c3
PM
271 0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
272 INTC_SMP_BALANCING(INT2DISTCR0) },
1ee01008
MD
273 { 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
274 { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
275 PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
276 PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
277 DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
278 DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
f9d885c3
PM
279 DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
280 INTC_SMP_BALANCING(INT2DISTCR1) },
1ee01008
MD
281 { 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
282 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283 SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
284 SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
285 SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
f9d885c3
PM
286 SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
287 INTC_SMP_BALANCING(INT2DISTCR2) },
1ee01008
MD
288};
289
5c37e025 290static struct intc_prio_reg prio_registers[] __initdata = {
6ef5fb2c
MD
291 { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
292
293 { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
294 TMU3, TMU2, TMU1, TMU0 } },
295 { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
296 SCIF3, SCIF2,
297 SCIF1, SCIF0 } },
298 { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
299 PCII56789, PCII4,
300 PCII3, PCII2,
301 PCII1, PCII0 } },
302 { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
303 VIN1, VIN0, IIC, DU} },
304 { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
305 GPIO2, GPIO1, GPIO0, IRM } },
46420e49
MD
306 { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
307 { INTICI7, INTICI6, INTICI5, INTICI4,
ceb9b974 308 INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
2b1bd1ac
PM
309};
310
7f3edee8 311static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
1ee01008
MD
312 mask_registers, prio_registers, NULL);
313
314/* Support for external interrupt pins in IRQ mode */
5c37e025 315static struct intc_vect vectors_irq[] __initdata = {
1ee01008
MD
316 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
317 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
318};
319
5c37e025 320static struct intc_sense_reg sense_registers[] __initdata = {
1ee01008
MD
321 { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
322};
323
324static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
7f3edee8 325 mask_registers, prio_registers, sense_registers);
1ee01008
MD
326
327/* External interrupt pins in IRL mode */
5c37e025 328static struct intc_vect vectors_irl[] __initdata = {
1ee01008
MD
329 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
330 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
331 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
332 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
333 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
334 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
335 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
336 INTC_VECT(IRL_HHHL, 0x3c0),
337};
338
339static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
7f3edee8 340 mask_registers, prio_registers, NULL);
1ee01008
MD
341
342void __init plat_irq_setup_pins(int mode)
343{
742759ea
PM
344 int ret = 0;
345
1ee01008
MD
346 switch (mode) {
347 case IRQ_MODE_IRQ:
742759ea
PM
348 ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
349 ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
350 ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
351 ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
352
353 if (unlikely(ret)) {
354 pr_err("Failed to set IRQ mode\n");
355 return;
356 }
357
1ee01008
MD
358 register_intc_controller(&intc_desc_irq);
359 break;
360 case IRQ_MODE_IRL3210:
742759ea
PM
361 ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
362 ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
363 ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
364 ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
365
366 if (unlikely(ret)) {
367 pr_err("Failed to set IRL mode\n");
368 return;
369 }
370
1ee01008
MD
371 register_intc_controller(&intc_desc_irl);
372 break;
373 default:
374 BUG();
375 }
376}
377
90015c89 378void __init plat_irq_setup(void)
2b1bd1ac 379{
1ee01008 380 register_intc_controller(&intc_desc);
2b1bd1ac 381}
7da3b8ef
PM
382
383void __init plat_mem_setup(void)
384{
d3428e91
PM
385 unsigned int nid = 1;
386
7da3b8ef 387 /* Register CPU#0 URAM space as Node 1 */
d3428e91 388 setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
7da3b8ef
PM
389
390#if 0
391 /* XXX: Not yet.. */
d3428e91
PM
392 setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
393 setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
394 setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
7da3b8ef 395#endif
d3428e91
PM
396
397 setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
7da3b8ef 398}