aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-11-21 09:27:52 -0500
committerPaul Mundt <lethal@linux-sh.org>2008-01-27 23:18:55 -0500
commitb4eaa1cc7ce8203ac9af9184c49c635ce79592b1 (patch)
tree83d71382fed9cc992cd6a1c23e6ec28fef304f2a /arch/sh
parent18bc81319b438ae3266e1b2653ce874912dae891 (diff)
sh: Kill off the rest of arch/sh64/kernel/.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/drivers/pci/pci-sh5.c536
-rw-r--r--arch/sh/drivers/pci/pci-sh5.h107
-rw-r--r--arch/sh/kernel/Makefile_322
-rw-r--r--arch/sh/kernel/Makefile_642
-rw-r--r--arch/sh/kernel/time_32.c (renamed from arch/sh/kernel/time.c)0
-rw-r--r--arch/sh/kernel/time_64.c528
6 files changed, 1173 insertions, 2 deletions
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c
new file mode 100644
index 000000000000..b4d9534d2b0e
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh5.c
@@ -0,0 +1,536 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 * Copyright (C) 2003, 2004 Paul Mundt
4 * Copyright (C) 2004 Richard Curnow
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Support functions for the SH5 PCI hardware.
10 */
11
12#include <linux/kernel.h>
13#include <linux/rwsem.h>
14#include <linux/smp.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20#include <linux/types.h>
21#include <asm/pci.h>
22#include <linux/irq.h>
23
24#include <asm/io.h>
25#include <asm/hardware.h>
26#include "pci_sh5.h"
27
28static unsigned long pcicr_virt;
29unsigned long pciio_virt;
30
31static void __init pci_fixup_ide_bases(struct pci_dev *d)
32{
33 int i;
34
35 /*
36 * PCI IDE controllers use non-standard I/O port decoding, respect it.
37 */
38 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
39 return;
40 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
41 for(i=0; i<4; i++) {
42 struct resource *r = &d->resource[i];
43 if ((r->start & ~0x80) == 0x374) {
44 r->start |= 2;
45 r->end = r->start;
46 }
47 }
48}
49DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
50
51char * __devinit pcibios_setup(char *str)
52{
53 return str;
54}
55
56/* Rounds a number UP to the nearest power of two. Used for
57 * sizing the PCI window.
58 */
59static u32 __init r2p2(u32 num)
60{
61 int i = 31;
62 u32 tmp = num;
63
64 if (num == 0)
65 return 0;
66
67 do {
68 if (tmp & (1 << 31))
69 break;
70 i--;
71 tmp <<= 1;
72 } while (i >= 0);
73
74 tmp = 1 << i;
75 /* If the original number isn't a power of 2, round it up */
76 if (tmp != num)
77 tmp <<= 1;
78
79 return tmp;
80}
81
82extern unsigned long long memory_start, memory_end;
83
84int __init sh5pci_init(unsigned memStart, unsigned memSize)
85{
86 u32 lsr0;
87 u32 uval;
88
89 pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
90 if (!pcicr_virt) {
91 panic("Unable to remap PCICR\n");
92 }
93
94 pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
95 if (!pciio_virt) {
96 panic("Unable to remap PCIIO\n");
97 }
98
99 pr_debug("Register base addres is 0x%08lx\n", pcicr_virt);
100
101 /* Clear snoop registers */
102 SH5PCI_WRITE(CSCR0, 0);
103 SH5PCI_WRITE(CSCR1, 0);
104
105 pr_debug("Wrote to reg\n");
106
107 /* Switch off interrupts */
108 SH5PCI_WRITE(INTM, 0);
109 SH5PCI_WRITE(AINTM, 0);
110 SH5PCI_WRITE(PINTM, 0);
111
112 /* Set bus active, take it out of reset */
113 uval = SH5PCI_READ(CR);
114
115 /* Set command Register */
116 SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM);
117
118 uval=SH5PCI_READ(CR);
119 pr_debug("CR is actually 0x%08x\n",uval);
120
121 /* Allow it to be a master */
122 /* NB - WE DISABLE I/O ACCESS to stop overlap */
123 /* set WAIT bit to enable stepping, an attempt to improve stability */
124 SH5PCI_WRITE_SHORT(CSR_CMD,
125 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
126
127 /*
128 ** Set translation mapping memory in order to convert the address
129 ** used for the main bus, to the PCI internal address.
130 */
131 SH5PCI_WRITE(MBR,0x40000000);
132
133 /* Always set the max size 512M */
134 SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
135
136 /*
137 ** I/O addresses are mapped at internal PCI specific address
138 ** as is described into the configuration bridge table.
139 ** These are changed to 0, to allow cards that have legacy
140 ** io such as vga to function correctly. We set the SH5 IOBAR to
141 ** 256K, which is a bit big as we can only have 64K of address space
142 */
143
144 SH5PCI_WRITE(IOBR,0x0);
145
146 pr_debug("PCI:Writing 0x%08x to IOBR\n",0);
147
148 /* Set up a 256K window. Totally pointless waste of address space */
149 SH5PCI_WRITE(IOBMR,0);
150 pr_debug("PCI:Writing 0x%08x to IOBMR\n",0);
151
152 /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally,
153 * we would want to map the I/O region somewhere, but it is so big this is not
154 * that easy!
155 */
156 SH5PCI_WRITE(CSR_IBAR0,~0);
157 /* Set memory size value */
158 memSize = memory_end - memory_start;
159
160 /* Now we set up the mbars so the PCI bus can see the memory of the machine */
161 if (memSize < (1024 * 1024)) {
162 printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
163 return -EINVAL;
164 }
165
166 /* Set LSR 0 */
167 lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
168 SH5PCI_WRITE(LSR0, lsr0);
169
170 pr_debug("PCI:Writing 0x%08x to LSR0\n",lsr0);
171
172 /* Set MBAR 0 */
173 SH5PCI_WRITE(CSR_MBAR0, memory_start);
174 SH5PCI_WRITE(LAR0, memory_start);
175
176 SH5PCI_WRITE(CSR_MBAR1,0);
177 SH5PCI_WRITE(LAR1,0);
178 SH5PCI_WRITE(LSR1,0);
179
180 pr_debug("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);
181 pr_debug("PCI:Writing 0x%08llx to LAR0\n",memory_start);
182
183 /* Enable the PCI interrupts on the device */
184 SH5PCI_WRITE(INTM, ~0);
185 SH5PCI_WRITE(AINTM, ~0);
186 SH5PCI_WRITE(PINTM, ~0);
187
188 pr_debug("Switching on all error interrupts\n");
189
190 return(0);
191}
192
193static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
194 int size, u32 *val)
195{
196 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
197
198 switch (size) {
199 case 1:
200 *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
201 break;
202 case 2:
203 *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
204 break;
205 case 4:
206 *val = SH5PCI_READ(PDR);
207 break;
208 }
209
210 return PCIBIOS_SUCCESSFUL;
211}
212
213static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
214 int size, u32 val)
215{
216 SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
217
218 switch (size) {
219 case 1:
220 SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
221 break;
222 case 2:
223 SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
224 break;
225 case 4:
226 SH5PCI_WRITE(PDR, val);
227 break;
228 }
229
230 return PCIBIOS_SUCCESSFUL;
231}
232
233static struct pci_ops pci_config_ops = {
234 .read = sh5pci_read,
235 .write = sh5pci_write,
236};
237
238/* Everything hangs off this */
239static struct pci_bus *pci_root_bus;
240
241
242static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
243{
244 pr_debug("swizzle for dev %d on bus %d slot %d pin is %d\n",
245 dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
246 return PCI_SLOT(dev->devfn);
247}
248
249static inline u8 bridge_swizzle(u8 pin, u8 slot)
250{
251 return (((pin-1) + slot) % 4) + 1;
252}
253
254u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
255{
256 if (dev->bus->number != 0) {
257 u8 pin = *pinp;
258 do {
259 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
260 /* Move up the chain of bridges. */
261 dev = dev->bus->self;
262 } while (dev->bus->self);
263 *pinp = pin;
264
265 /* The slot is the slot of the last bridge. */
266 }
267
268 return PCI_SLOT(dev->devfn);
269}
270
271/* This needs to be shunted out of here into the board specific bit */
272
273static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
274{
275 int result = -1;
276
277 /* The complication here is that the PCI IRQ lines from the Cayman's 2
278 5V slots get into the CPU via a different path from the IRQ lines
279 from the 3 3.3V slots. Thus, we have to detect whether the card's
280 interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
281 at the point where we cross from 5V to 3.3V is not the normal case.
282
283 The added complication is that we don't know that the 5V slots are
284 always bus 2, because a card containing a PCI-PCI bridge may be
285 plugged into a 3.3V slot, and this changes the bus numbering.
286
287 Also, the Cayman has an intermediate PCI bus that goes a custom
288 expansion board header (and to the secondary bridge). This bus has
289 never been used in practice.
290
291 The 1ary onboard PCI-PCI bridge is device 3 on bus 0
292 The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of the 1ary bridge.
293 */
294
295 struct slot_pin {
296 int slot;
297 int pin;
298 } path[4];
299 int i=0;
300
301 while (dev->bus->number > 0) {
302
303 slot = path[i].slot = PCI_SLOT(dev->devfn);
304 pin = path[i].pin = bridge_swizzle(pin, slot);
305 dev = dev->bus->self;
306 i++;
307 if (i > 3) panic("PCI path to root bus too long!\n");
308 }
309
310 slot = PCI_SLOT(dev->devfn);
311 /* This is the slot on bus 0 through which the device is eventually
312 reachable. */
313
314 /* Now work back up. */
315 if ((slot < 3) || (i == 0)) {
316 /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
317 swizzle now. */
318 result = IRQ_INTA + bridge_swizzle(pin, slot) - 1;
319 } else {
320 i--;
321 slot = path[i].slot;
322 pin = path[i].pin;
323 if (slot > 0) {
324 panic("PCI expansion bus device found - not handled!\n");
325 } else {
326 if (i > 0) {
327 /* 5V slots */
328 i--;
329 slot = path[i].slot;
330 pin = path[i].pin;
331 /* 'pin' was swizzled earlier wrt slot, don't do it again. */
332 result = IRQ_P2INTA + (pin - 1);
333 } else {
334 /* IRQ for 2ary PCI-PCI bridge : unused */
335 result = -1;
336 }
337 }
338 }
339
340 return result;
341}
342
343static irqreturn_t pcish5_err_irq(int irq, void *dev_id)
344{
345 struct pt_regs *regs = get_irq_regs();
346 unsigned pci_int, pci_air, pci_cir, pci_aint;
347
348 pci_int = SH5PCI_READ(INT);
349 pci_cir = SH5PCI_READ(CIR);
350 pci_air = SH5PCI_READ(AIR);
351
352 if (pci_int) {
353 printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
354 printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
355 printk("PCI AIR -> 0x%x\n", pci_air);
356 printk("PCI CIR -> 0x%x\n", pci_cir);
357 SH5PCI_WRITE(INT, ~0);
358 }
359
360 pci_aint = SH5PCI_READ(AINT);
361 if (pci_aint) {
362 printk("PCI ARB INTERRUPT!\n");
363 printk("PCI AINT -> 0x%x\n", pci_aint);
364 printk("PCI AIR -> 0x%x\n", pci_air);
365 printk("PCI CIR -> 0x%x\n", pci_cir);
366 SH5PCI_WRITE(AINT, ~0);
367 }
368
369 return IRQ_HANDLED;
370}
371
372static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
373{
374 printk("SERR IRQ\n");
375
376 return IRQ_NONE;
377}
378
379static void __init
380pcibios_size_bridge(struct pci_bus *bus, struct resource *ior,
381 struct resource *memr)
382{
383 struct resource io_res, mem_res;
384 struct pci_dev *dev;
385 struct pci_dev *bridge = bus->self;
386 struct list_head *ln;
387
388 if (!bridge)
389 return; /* host bridge, nothing to do */
390
391 /* set reasonable default locations for pcibios_align_resource */
392 io_res.start = PCIBIOS_MIN_IO;
393 mem_res.start = PCIBIOS_MIN_MEM;
394
395 io_res.end = io_res.start;
396 mem_res.end = mem_res.start;
397
398 /* Collect information about how our direct children are layed out. */
399 for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
400 int i;
401 dev = pci_dev_b(ln);
402
403 /* Skip bridges for now */
404 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
405 continue;
406
407 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
408 struct resource res;
409 unsigned long size;
410
411 memcpy(&res, &dev->resource[i], sizeof(res));
412 size = res.end - res.start + 1;
413
414 if (res.flags & IORESOURCE_IO) {
415 res.start = io_res.end;
416 pcibios_align_resource(dev, &res, size, 0);
417 io_res.end = res.start + size;
418 } else if (res.flags & IORESOURCE_MEM) {
419 res.start = mem_res.end;
420 pcibios_align_resource(dev, &res, size, 0);
421 mem_res.end = res.start + size;
422 }
423 }
424 }
425
426 /* And for all of the subordinate busses. */
427 for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
428 pcibios_size_bridge(pci_bus_b(ln), &io_res, &mem_res);
429
430 /* turn the ending locations into sizes (subtract start) */
431 io_res.end -= io_res.start;
432 mem_res.end -= mem_res.start;
433
434 /* Align the sizes up by bridge rules */
435 io_res.end = ALIGN(io_res.end, 4*1024) - 1;
436 mem_res.end = ALIGN(mem_res.end, 1*1024*1024) - 1;
437
438 /* Adjust the bridge's allocation requirements */
439 bridge->resource[0].end = bridge->resource[0].start + io_res.end;
440 bridge->resource[1].end = bridge->resource[1].start + mem_res.end;
441
442 bridge->resource[PCI_BRIDGE_RESOURCES].end =
443 bridge->resource[PCI_BRIDGE_RESOURCES].start + io_res.end;
444 bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
445 bridge->resource[PCI_BRIDGE_RESOURCES+1].start + mem_res.end;
446
447 /* adjust parent's resource requirements */
448 if (ior) {
449 ior->end = ALIGN(ior->end, 4*1024);
450 ior->end += io_res.end;
451 }
452
453 if (memr) {
454 memr->end = ALIGN(memr->end, 1*1024*1024);
455 memr->end += mem_res.end;
456 }
457}
458
459static void __init pcibios_size_bridges(void)
460{
461 struct resource io_res, mem_res;
462
463 memset(&io_res, 0, sizeof(io_res));
464 memset(&mem_res, 0, sizeof(mem_res));
465
466 pcibios_size_bridge(pci_root_bus, &io_res, &mem_res);
467}
468
469static int __init pcibios_init(void)
470{
471 if (request_irq(IRQ_ERR, pcish5_err_irq,
472 IRQF_DISABLED, "PCI Error",NULL) < 0) {
473 printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
474 return -EINVAL;
475 }
476
477 if (request_irq(IRQ_SERR, pcish5_serr_irq,
478 IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) {
479 printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
480 return -EINVAL;
481 }
482
483 /* The pci subsystem needs to know where memory is and how much
484 * of it there is. I've simply made these globals. A better mechanism
485 * is probably needed.
486 */
487 sh5pci_init(__pa(memory_start),
488 __pa(memory_end) - __pa(memory_start));
489
490 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
491 pcibios_size_bridges();
492 pci_assign_unassigned_resources();
493 pci_fixup_irqs(no_swizzle, map_cayman_irq);
494
495 return 0;
496}
497
498subsys_initcall(pcibios_init);
499
500void __devinit pcibios_fixup_bus(struct pci_bus *bus)
501{
502 struct pci_dev *dev = bus->self;
503 int i;
504
505#if 1
506 if(dev) {
507 for(i=0; i<3; i++) {
508 bus->resource[i] =
509 &dev->resource[PCI_BRIDGE_RESOURCES+i];
510 bus->resource[i]->name = bus->name;
511 }
512 bus->resource[0]->flags |= IORESOURCE_IO;
513 bus->resource[1]->flags |= IORESOURCE_MEM;
514
515 /* For now, propagate host limits to the bus;
516 * we'll adjust them later. */
517
518#if 1
519 bus->resource[0]->end = 64*1024 - 1 ;
520 bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
521 bus->resource[0]->start = PCIBIOS_MIN_IO;
522 bus->resource[1]->start = PCIBIOS_MIN_MEM;
523#else
524 bus->resource[0]->end = 0;
525 bus->resource[1]->end = 0;
526 bus->resource[0]->start =0;
527 bus->resource[1]->start = 0;
528#endif
529 /* Turn off downstream PF memory address range by default */
530 bus->resource[2]->start = 1024*1024;
531 bus->resource[2]->end = bus->resource[2]->start - 1;
532 }
533#endif
534
535}
536
diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h
new file mode 100644
index 000000000000..c71159dd04b9
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh5.h
@@ -0,0 +1,107 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Definitions for the SH5 PCI hardware.
8 */
9
10/* Product ID */
11#define PCISH5_PID 0x350d
12
13/* vendor ID */
14#define PCISH5_VID 0x1054
15
16/* Configuration types */
17#define ST_TYPE0 0x00 /* Configuration cycle type 0 */
18#define ST_TYPE1 0x01 /* Configuration cycle type 1 */
19
20/* VCR data */
21#define PCISH5_VCR_STATUS 0x00
22#define PCISH5_VCR_VERSION 0x08
23
24/*
25** ICR register offsets and bits
26*/
27#define PCISH5_ICR_CR 0x100 /* PCI control register values */
28#define CR_PBAM (1<<12)
29#define CR_PFCS (1<<11)
30#define CR_FTO (1<<10)
31#define CR_PFE (1<<9)
32#define CR_TBS (1<<8)
33#define CR_SPUE (1<<7)
34#define CR_BMAM (1<<6)
35#define CR_HOST (1<<5)
36#define CR_CLKEN (1<<4)
37#define CR_SOCS (1<<3)
38#define CR_IOCS (1<<2)
39#define CR_RSTCTL (1<<1)
40#define CR_CFINT (1<<0)
41#define CR_LOCK_MASK 0xa5000000
42
43#define PCISH5_ICR_INT 0x114 /* Interrupt registert values */
44#define INT_MADIM (1<<2)
45
46#define PCISH5_ICR_LSR0 0X104 /* Local space register values */
47#define PCISH5_ICR_LSR1 0X108 /* Local space register values */
48#define PCISH5_ICR_LAR0 0x10c /* Local address register values */
49#define PCISH5_ICR_LAR1 0x110 /* Local address register values */
50#define PCISH5_ICR_INTM 0x118 /* Interrupt mask register values */
51#define PCISH5_ICR_AIR 0x11c /* Interrupt error address information register values */
52#define PCISH5_ICR_CIR 0x120 /* Interrupt error command information register values */
53#define PCISH5_ICR_AINT 0x130 /* Interrupt error arbiter interrupt register values */
54#define PCISH5_ICR_AINTM 0x134 /* Interrupt error arbiter interrupt mask register values */
55#define PCISH5_ICR_BMIR 0x138 /* Interrupt error info register of bus master values */
56#define PCISH5_ICR_PAR 0x1c0 /* Pio address register values */
57#define PCISH5_ICR_MBR 0x1c4 /* Memory space bank register values */
58#define PCISH5_ICR_IOBR 0x1c8 /* I/O space bank register values */
59#define PCISH5_ICR_PINT 0x1cc /* power management interrupt register values */
60#define PCISH5_ICR_PINTM 0x1d0 /* power management interrupt mask register values */
61#define PCISH5_ICR_MBMR 0x1d8 /* memory space bank mask register values */
62#define PCISH5_ICR_IOBMR 0x1dc /* I/O space bank mask register values */
63#define PCISH5_ICR_CSCR0 0x210 /* PCI cache snoop control register 0 */
64#define PCISH5_ICR_CSCR1 0x214 /* PCI cache snoop control register 1 */
65#define PCISH5_ICR_PDR 0x220 /* Pio data register values */
66
67/* These are configs space registers */
68#define PCISH5_ICR_CSR_VID 0x000 /* Vendor id */
69#define PCISH5_ICR_CSR_DID 0x002 /* Device id */
70#define PCISH5_ICR_CSR_CMD 0x004 /* Command register */
71#define PCISH5_ICR_CSR_STATUS 0x006 /* Stautus */
72#define PCISH5_ICR_CSR_IBAR0 0x010 /* I/O base address register */
73#define PCISH5_ICR_CSR_MBAR0 0x014 /* First Memory base address register */
74#define PCISH5_ICR_CSR_MBAR1 0x018 /* Second Memory base address register */
75
76
77
78/* Base address of registers */
79#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000)
80#define SH5PCI_IO_BASE (PHYS_PCI_BLOCK + 0x00800000)
81/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG) */
82
83/* Register selection macro */
84#define PCISH5_ICR_REG(x) ( pcicr_virt + (PCISH5_ICR_##x))
85/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
86
87/* Write I/O functions */
88#define SH5PCI_WRITE(reg,val) ctrl_outl((u32)(val),PCISH5_ICR_REG(reg))
89#define SH5PCI_WRITE_SHORT(reg,val) ctrl_outw((u16)(val),PCISH5_ICR_REG(reg))
90#define SH5PCI_WRITE_BYTE(reg,val) ctrl_outb((u8)(val),PCISH5_ICR_REG(reg))
91
92/* Read I/O functions */
93#define SH5PCI_READ(reg) ctrl_inl(PCISH5_ICR_REG(reg))
94#define SH5PCI_READ_SHORT(reg) ctrl_inw(PCISH5_ICR_REG(reg))
95#define SH5PCI_READ_BYTE(reg) ctrl_inb(PCISH5_ICR_REG(reg))
96
97/* Set PCI config bits */
98#define SET_CONFIG_BITS(bus,devfn,where) ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
99
100/* Set PCI command register */
101#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
102
103/* Size converters */
104#define PCISH5_MEM_SIZCONV(x) (((x / 0x40000) - 1) << 18)
105#define PCISH5_IO_SIZCONV(x) (((x / 0x40000) - 1) << 18)
106
107
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 990ba74db0d6..c89289831053 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -6,7 +6,7 @@ extra-y := head_32.o init_task.o vmlinux.lds
6 6
7obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ 7obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \
8 ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \ 8 ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \
9 syscalls_32.o time.o topology.o traps.o traps_32.o 9 syscalls_32.o time_32.o topology.o traps.o traps_32.o
10 10
11obj-y += cpu/ timers/ 11obj-y += cpu/ timers/
12obj-$(CONFIG_VSYSCALL) += vsyscall/ 12obj-$(CONFIG_VSYSCALL) += vsyscall/
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index 10e3ae1c64b8..1ef21cc087f3 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -2,7 +2,7 @@ extra-y := head_64.o init_task.o vmlinux.lds
2 2
3obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ 3obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \
4 ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \ 4 ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \
5 syscalls_64.o time.o topology.o traps.o traps_64.o 5 syscalls_64.o time_64.o topology.o traps.o traps_64.o
6 6
7obj-y += cpu/ timers/ 7obj-y += cpu/ timers/
8obj-$(CONFIG_VSYSCALL) += vsyscall/ 8obj-$(CONFIG_VSYSCALL) += vsyscall/
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time_32.c
index 2bc04bfee738..2bc04bfee738 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time_32.c
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
new file mode 100644
index 000000000000..4c52feead115
--- /dev/null
+++ b/arch/sh/kernel/time_64.c
@@ -0,0 +1,528 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh64/kernel/time.c
7 *
8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2003 - 2007 Paul Mundt
10 * Copyright (C) 2003 Richard Curnow
11 *
12 * Original TMU/RTC code taken from sh version.
13 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
14 * Some code taken from i386 version.
15 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
16 */
17#include <linux/errno.h>
18#include <linux/rwsem.h>
19#include <linux/sched.h>
20#include <linux/kernel.h>
21#include <linux/param.h>
22#include <linux/string.h>
23#include <linux/mm.h>
24#include <linux/interrupt.h>
25#include <linux/time.h>
26#include <linux/delay.h>
27#include <linux/init.h>
28#include <linux/profile.h>
29#include <linux/smp.h>
30#include <linux/module.h>
31#include <linux/bcd.h>
32#include <linux/timex.h>
33#include <linux/irq.h>
34#include <linux/io.h>
35#include <linux/platform_device.h>
36#include <asm/cpu/registers.h> /* required by inline __asm__ stmt. */
37#include <asm/cpu/irq.h>
38#include <asm/addrspace.h>
39#include <asm/processor.h>
40#include <asm/uaccess.h>
41#include <asm/delay.h>
42
43#define TMU_TOCR_INIT 0x00
44#define TMU0_TCR_INIT 0x0020
45#define TMU_TSTR_INIT 1
46#define TMU_TSTR_OFF 0
47
48/* Real Time Clock */
49#define RTC_BLOCK_OFF 0x01040000
50#define RTC_BASE PHYS_PERIPHERAL_BLOCK + RTC_BLOCK_OFF
51#define RTC_RCR1_CIE 0x10 /* Carry Interrupt Enable */
52#define RTC_RCR1 (rtc_base + 0x38)
53
54/* Clock, Power and Reset Controller */
55#define CPRC_BLOCK_OFF 0x01010000
56#define CPRC_BASE PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF
57
58#define FRQCR (cprc_base+0x0)
59#define WTCSR (cprc_base+0x0018)
60#define STBCR (cprc_base+0x0030)
61
62/* Time Management Unit */
63#define TMU_BLOCK_OFF 0x01020000
64#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
65#define TMU0_BASE tmu_base + 0x8 + (0xc * 0x0)
66#define TMU1_BASE tmu_base + 0x8 + (0xc * 0x1)
67#define TMU2_BASE tmu_base + 0x8 + (0xc * 0x2)
68
69#define TMU_TOCR tmu_base+0x0 /* Byte access */
70#define TMU_TSTR tmu_base+0x4 /* Byte access */
71
72#define TMU0_TCOR TMU0_BASE+0x0 /* Long access */
73#define TMU0_TCNT TMU0_BASE+0x4 /* Long access */
74#define TMU0_TCR TMU0_BASE+0x8 /* Word access */
75
76#define TICK_SIZE (tick_nsec / 1000)
77
78static unsigned long tmu_base, rtc_base;
79unsigned long cprc_base;
80
81/* Variables to allow interpolation of time of day to resolution better than a
82 * jiffy. */
83
84/* This is effectively protected by xtime_lock */
85static unsigned long ctc_last_interrupt;
86static unsigned long long usecs_per_jiffy = 1000000/HZ; /* Approximation */
87
88#define CTC_JIFFY_SCALE_SHIFT 40
89
90/* 2**CTC_JIFFY_SCALE_SHIFT / ctc_ticks_per_jiffy */
91static unsigned long long scaled_recip_ctc_ticks_per_jiffy;
92
93/* Estimate number of microseconds that have elapsed since the last timer tick,
94 by scaling the delta that has occurred in the CTC register.
95
96 WARNING WARNING WARNING : This algorithm relies on the CTC decrementing at
97 the CPU clock rate. If the CPU sleeps, the CTC stops counting. Bear this
98 in mind if enabling SLEEP_WORKS in process.c. In that case, this algorithm
99 probably needs to use TMU.TCNT0 instead. This will work even if the CPU is
100 sleeping, though will be coarser.
101
102 FIXME : What if usecs_per_tick is moving around too much, e.g. if an adjtime
103 is running or if the freq or tick arguments of adjtimex are modified after
104 we have calibrated the scaling factor? This will result in either a jump at
105 the end of a tick period, or a wrap backwards at the start of the next one,
106 if the application is reading the time of day often enough. I think we
107 ought to do better than this. For this reason, usecs_per_jiffy is left
108 separated out in the calculation below. This allows some future hook into
109 the adjtime-related stuff in kernel/timer.c to remove this hazard.
110
111*/
112
113static unsigned long usecs_since_tick(void)
114{
115 unsigned long long current_ctc;
116 long ctc_ticks_since_interrupt;
117 unsigned long long ull_ctc_ticks_since_interrupt;
118 unsigned long result;
119
120 unsigned long long mul1_out;
121 unsigned long long mul1_out_high;
122 unsigned long long mul2_out_low, mul2_out_high;
123
124 /* Read CTC register */
125 asm ("getcon cr62, %0" : "=r" (current_ctc));
126 /* Note, the CTC counts down on each CPU clock, not up.
127 Note(2), use long type to get correct wraparound arithmetic when
128 the counter crosses zero. */
129 ctc_ticks_since_interrupt = (long) ctc_last_interrupt - (long) current_ctc;
130 ull_ctc_ticks_since_interrupt = (unsigned long long) ctc_ticks_since_interrupt;
131
132 /* Inline assembly to do 32x32x32->64 multiplier */
133 asm volatile ("mulu.l %1, %2, %0" :
134 "=r" (mul1_out) :
135 "r" (ull_ctc_ticks_since_interrupt), "r" (usecs_per_jiffy));
136
137 mul1_out_high = mul1_out >> 32;
138
139 asm volatile ("mulu.l %1, %2, %0" :
140 "=r" (mul2_out_low) :
141 "r" (mul1_out), "r" (scaled_recip_ctc_ticks_per_jiffy));
142
143#if 1
144 asm volatile ("mulu.l %1, %2, %0" :
145 "=r" (mul2_out_high) :
146 "r" (mul1_out_high), "r" (scaled_recip_ctc_ticks_per_jiffy));
147#endif
148
149 result = (unsigned long) (((mul2_out_high << 32) + mul2_out_low) >> CTC_JIFFY_SCALE_SHIFT);
150
151 return result;
152}
153
154void do_gettimeofday(struct timeval *tv)
155{
156 unsigned long flags;
157 unsigned long seq;
158 unsigned long usec, sec;
159
160 do {
161 seq = read_seqbegin_irqsave(&xtime_lock, flags);
162 usec = usecs_since_tick();
163 sec = xtime.tv_sec;
164 usec += xtime.tv_nsec / 1000;
165 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
166
167 while (usec >= 1000000) {
168 usec -= 1000000;
169 sec++;
170 }
171
172 tv->tv_sec = sec;
173 tv->tv_usec = usec;
174}
175
176int do_settimeofday(struct timespec *tv)
177{
178 time_t wtm_sec, sec = tv->tv_sec;
179 long wtm_nsec, nsec = tv->tv_nsec;
180
181 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
182 return -EINVAL;
183
184 write_seqlock_irq(&xtime_lock);
185 /*
186 * This is revolting. We need to set "xtime" correctly. However, the
187 * value in this location is the value at the most recent update of
188 * wall time. Discover what correction gettimeofday() would have
189 * made, and then undo it!
190 */
191 nsec -= 1000 * usecs_since_tick();
192
193 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
194 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
195
196 set_normalized_timespec(&xtime, sec, nsec);
197 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
198
199 ntp_clear();
200 write_sequnlock_irq(&xtime_lock);
201 clock_was_set();
202
203 return 0;
204}
205EXPORT_SYMBOL(do_settimeofday);
206
207/* Dummy RTC ops */
208static void null_rtc_get_time(struct timespec *tv)
209{
210 tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0);
211 tv->tv_nsec = 0;
212}
213
214static int null_rtc_set_time(const time_t secs)
215{
216 return 0;
217}
218
219void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
220int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
221
222/* last time the RTC clock got updated */
223static long last_rtc_update;
224
225/*
226 * timer_interrupt() needs to keep up the real-time clock,
227 * as well as call the "do_timer()" routine every clocktick
228 */
229static inline void do_timer_interrupt(void)
230{
231 unsigned long long current_ctc;
232 asm ("getcon cr62, %0" : "=r" (current_ctc));
233 ctc_last_interrupt = (unsigned long) current_ctc;
234
235 do_timer(1);
236#ifndef CONFIG_SMP
237 update_process_times(user_mode(get_irq_regs()));
238#endif
239 if (current->pid)
240 profile_tick(CPU_PROFILING);
241
242#ifdef CONFIG_HEARTBEAT
243 if (sh_mv.mv_heartbeat != NULL)
244 sh_mv.mv_heartbeat();
245#endif
246
247 /*
248 * If we have an externally synchronized Linux clock, then update
249 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
250 * called as close as possible to 500 ms before the new second starts.
251 */
252 if (ntp_synced() &&
253 xtime.tv_sec > last_rtc_update + 660 &&
254 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
255 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
256 if (rtc_sh_set_time(xtime.tv_sec) == 0)
257 last_rtc_update = xtime.tv_sec;
258 else
259 /* do it again in 60 s */
260 last_rtc_update = xtime.tv_sec - 600;
261 }
262}
263
264/*
265 * This is the same as the above, except we _also_ save the current
266 * Time Stamp Counter value at the time of the timer interrupt, so that
267 * we later on can estimate the time of day more exactly.
268 */
269static irqreturn_t timer_interrupt(int irq, void *dev_id)
270{
271 unsigned long timer_status;
272
273 /* Clear UNF bit */
274 timer_status = ctrl_inw(TMU0_TCR);
275 timer_status &= ~0x100;
276 ctrl_outw(timer_status, TMU0_TCR);
277
278 /*
279 * Here we are in the timer irq handler. We just have irqs locally
280 * disabled but we don't know if the timer_bh is running on the other
281 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
282 * the irq version of write_lock because as just said we have irq
283 * locally disabled. -arca
284 */
285 write_lock(&xtime_lock);
286 do_timer_interrupt();
287 write_unlock(&xtime_lock);
288
289 return IRQ_HANDLED;
290}
291
292
293static __init unsigned int get_cpu_hz(void)
294{
295 unsigned int count;
296 unsigned long __dummy;
297 unsigned long ctc_val_init, ctc_val;
298
299 /*
300 ** Regardless the toolchain, force the compiler to use the
301 ** arbitrary register r3 as a clock tick counter.
302 ** NOTE: r3 must be in accordance with sh64_rtc_interrupt()
303 */
304 register unsigned long long __rtc_irq_flag __asm__ ("r3");
305
306 local_irq_enable();
307 do {} while (ctrl_inb(rtc_base) != 0);
308 ctrl_outb(RTC_RCR1_CIE, RTC_RCR1); /* Enable carry interrupt */
309
310 /*
311 * r3 is arbitrary. CDC does not support "=z".
312 */
313 ctc_val_init = 0xffffffff;
314 ctc_val = ctc_val_init;
315
316 asm volatile("gettr tr0, %1\n\t"
317 "putcon %0, " __CTC "\n\t"
318 "and %2, r63, %2\n\t"
319 "pta $+4, tr0\n\t"
320 "beq/l %2, r63, tr0\n\t"
321 "ptabs %1, tr0\n\t"
322 "getcon " __CTC ", %0\n\t"
323 : "=r"(ctc_val), "=r" (__dummy), "=r" (__rtc_irq_flag)
324 : "0" (0));
325 local_irq_disable();
326 /*
327 * SH-3:
328 * CPU clock = 4 stages * loop
329 * tst rm,rm if id ex
330 * bt/s 1b if id ex
331 * add #1,rd if id ex
332 * (if) pipe line stole
333 * tst rm,rm if id ex
334 * ....
335 *
336 *
337 * SH-4:
338 * CPU clock = 6 stages * loop
339 * I don't know why.
340 * ....
341 *
342 * SH-5:
343 * Use CTC register to count. This approach returns the right value
344 * even if the I-cache is disabled (e.g. whilst debugging.)
345 *
346 */
347
348 count = ctc_val_init - ctc_val; /* CTC counts down */
349
350#if defined (CONFIG_SH_SIMULATOR)
351 /*
352 * Let's pretend we are a 5MHz SH-5 to avoid a too
353 * little timer interval. Also to keep delay
354 * calibration within a reasonable time.
355 */
356 return 5000000;
357#else
358 /*
359 * This really is count by the number of clock cycles
360 * by the ratio between a complete R64CNT
361 * wrap-around (128) and CUI interrupt being raised (64).
362 */
363 return count*2;
364#endif
365}
366
367static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id)
368{
369 struct pt_regs *regs = get_irq_regs();
370
371 ctrl_outb(0, RTC_RCR1); /* Disable Carry Interrupts */
372 regs->regs[3] = 1; /* Using r3 */
373
374 return IRQ_HANDLED;
375}
376
377static struct irqaction irq0 = {
378 .handler = timer_interrupt,
379 .flags = IRQF_DISABLED,
380 .mask = CPU_MASK_NONE,
381 .name = "timer",
382};
383static struct irqaction irq1 = {
384 .handler = sh64_rtc_interrupt,
385 .flags = IRQF_DISABLED,
386 .mask = CPU_MASK_NONE,
387 .name = "rtc",
388};
389
390void __init time_init(void)
391{
392 unsigned int cpu_clock, master_clock, bus_clock, module_clock;
393 unsigned long interval;
394 unsigned long frqcr, ifc, pfc;
395 static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
396#define bfc_table ifc_table /* Same */
397#define pfc_table ifc_table /* Same */
398
399 tmu_base = onchip_remap(TMU_BASE, 1024, "TMU");
400 if (!tmu_base) {
401 panic("Unable to remap TMU\n");
402 }
403
404 rtc_base = onchip_remap(RTC_BASE, 1024, "RTC");
405 if (!rtc_base) {
406 panic("Unable to remap RTC\n");
407 }
408
409 cprc_base = onchip_remap(CPRC_BASE, 1024, "CPRC");
410 if (!cprc_base) {
411 panic("Unable to remap CPRC\n");
412 }
413
414 rtc_sh_get_time(&xtime);
415
416 setup_irq(TIMER_IRQ, &irq0);
417 setup_irq(RTC_IRQ, &irq1);
418
419 /* Check how fast it is.. */
420 cpu_clock = get_cpu_hz();
421
422 /* Note careful order of operations to maintain reasonable precision and avoid overflow. */
423 scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) / (unsigned long long)(cpu_clock / HZ));
424
425 free_irq(RTC_IRQ, NULL);
426
427 printk("CPU clock: %d.%02dMHz\n",
428 (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
429 {
430 unsigned short bfc;
431 frqcr = ctrl_inl(FRQCR);
432 ifc = ifc_table[(frqcr>> 6) & 0x0007];
433 bfc = bfc_table[(frqcr>> 3) & 0x0007];
434 pfc = pfc_table[(frqcr>> 12) & 0x0007];
435 master_clock = cpu_clock * ifc;
436 bus_clock = master_clock/bfc;
437 }
438
439 printk("Bus clock: %d.%02dMHz\n",
440 (bus_clock/1000000), (bus_clock % 1000000)/10000);
441 module_clock = master_clock/pfc;
442 printk("Module clock: %d.%02dMHz\n",
443 (module_clock/1000000), (module_clock % 1000000)/10000);
444 interval = (module_clock/(HZ*4));
445
446 printk("Interval = %ld\n", interval);
447
448 current_cpu_data.cpu_clock = cpu_clock;
449 current_cpu_data.master_clock = master_clock;
450 current_cpu_data.bus_clock = bus_clock;
451 current_cpu_data.module_clock = module_clock;
452
453 /* Start TMU0 */
454 ctrl_outb(TMU_TSTR_OFF, TMU_TSTR);
455 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
456 ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
457 ctrl_outl(interval, TMU0_TCOR);
458 ctrl_outl(interval, TMU0_TCNT);
459 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
460}
461
462void enter_deep_standby(void)
463{
464 /* Disable watchdog timer */
465 ctrl_outl(0xa5000000, WTCSR);
466 /* Configure deep standby on sleep */
467 ctrl_outl(0x03, STBCR);
468
469#ifdef CONFIG_SH_ALPHANUMERIC
470 {
471 extern void mach_alphanum(int position, unsigned char value);
472 extern void mach_alphanum_brightness(int setting);
473 char halted[] = "Halted. ";
474 int i;
475 mach_alphanum_brightness(6); /* dimmest setting above off */
476 for (i=0; i<8; i++) {
477 mach_alphanum(i, halted[i]);
478 }
479 asm __volatile__ ("synco");
480 }
481#endif
482
483 asm __volatile__ ("sleep");
484 asm __volatile__ ("synci");
485 asm __volatile__ ("nop");
486 asm __volatile__ ("nop");
487 asm __volatile__ ("nop");
488 asm __volatile__ ("nop");
489 panic("Unexpected wakeup!\n");
490}
491
492static struct resource rtc_resources[] = {
493 [0] = {
494 /* RTC base, filled in by rtc_init */
495 .flags = IORESOURCE_IO,
496 },
497 [1] = {
498 /* Period IRQ */
499 .start = IRQ_PRI,
500 .flags = IORESOURCE_IRQ,
501 },
502 [2] = {
503 /* Carry IRQ */
504 .start = IRQ_CUI,
505 .flags = IORESOURCE_IRQ,
506 },
507 [3] = {
508 /* Alarm IRQ */
509 .start = IRQ_ATI,
510 .flags = IORESOURCE_IRQ,
511 },
512};
513
514static struct platform_device rtc_device = {
515 .name = "sh-rtc",
516 .id = -1,
517 .num_resources = ARRAY_SIZE(rtc_resources),
518 .resource = rtc_resources,
519};
520
521static int __init rtc_init(void)
522{
523 rtc_resources[0].start = rtc_base;
524 rtc_resources[0].end = rtc_resources[0].start + 0x58 - 1;
525
526 return platform_device_register(&rtc_device);
527}
528device_initcall(rtc_init);