summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shark/core.c
blob: f4b25d875f3dc13a52c673f25061e314d7a4aec6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 *  linux/arch/arm/mach-shark/arch.c
 *
 *  Architecture specific stuff.
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/serial_8250.h>
#include <linux/io.h>

#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/leds.h>
#include <asm/param.h>

#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>

#define IO_BASE                 0xe0000000
#define IO_SIZE                 0x08000000
#define IO_START                0x40000000
#define ROMCARD_SIZE            0x08000000
#define ROMCARD_START           0x10000000

void arch_reset(char mode, const char *cmd)
{
        short temp;
        /* Reset the Machine via pc[3] of the sequoia chipset */
        outw(0x09,0x24);
        temp=inw(0x26);
        temp = temp | (1<<3) | (1<<10);
        outw(0x09,0x24);
        outw(temp,0x26);
}

static struct plat_serial8250_port serial_platform_data[] = {
	{
		.iobase		= 0x3f8,
		.irq		= 4,
		.uartclk	= 1843200,
		.regshift	= 0,
		.iotype		= UPIO_PORT,
		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
	},
	{
		.iobase		= 0x2f8,
		.irq		= 3,
		.uartclk	= 1843200,
		.regshift	= 0,
		.iotype		= UPIO_PORT,
		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
	},
	{ },
};

static struct platform_device serial_device = {
	.name			= "serial8250",
	.id			= PLAT8250_DEV_PLATFORM,
	.dev			= {
		.platform_data	= serial_platform_data,
	},
};

static struct resource rtc_resources[] = {
	[0] = {
		.start	= 0x70,
		.end	= 0x73,
		.flags	= IORESOURCE_IO,
	},
	[1] = {
		.start	= IRQ_ISA_RTC_ALARM,
		.end	= IRQ_ISA_RTC_ALARM,
		.flags	= IORESOURCE_IRQ,
	}
};

static struct platform_device rtc_device = {
	.name		= "rtc_cmos",
	.id		= -1,
	.resource	= rtc_resources,
	.num_resources	= ARRAY_SIZE(rtc_resources),
};

static int __init shark_init(void)
{
	int ret;

	if (machine_is_shark())
	{
	        ret = platform_device_register(&rtc_device);
		if (ret) printk(KERN_ERR "Unable to register RTC device: %d\n", ret);
		ret = platform_device_register(&serial_device);
		if (ret) printk(KERN_ERR "Unable to register Serial device: %d\n", ret);
	}
	return 0;
}

arch_initcall(shark_init);

extern void shark_init_irq(void);

static struct map_desc shark_io_desc[] __initdata = {
	{
		.virtual	= IO_BASE,
		.pfn		= __phys_to_pfn(IO_START),
		.length		= IO_SIZE,
		.type		= MT_DEVICE
	}
};

static void __init shark_map_io(void)
{
	iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc));
}

#define IRQ_TIMER 0
#define HZ_TIME ((1193180 + HZ/2) / HZ)

static irqreturn_t
shark_timer_interrupt(int irq, void *dev_id)
{
	timer_tick();
	return IRQ_HANDLED;
}

static struct irqaction shark_timer_irq = {
	.name		= "Shark Timer Tick",
	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
	.handler	= shark_timer_interrupt,
};

/*
 * Set up timer interrupt, and return the current time in seconds.
 */
static void __init shark_timer_init(void)
{
	outb(0x34, 0x43);               /* binary, mode 0, LSB/MSB, Ch 0 */
	outb(HZ_TIME & 0xff, 0x40);     /* LSB of count */
	outb(HZ_TIME >> 8, 0x40);

	setup_irq(IRQ_TIMER, &shark_timer_irq);
}

static struct sys_timer shark_timer = {
	.init		= shark_timer_init,
};

MACHINE_START(SHARK, "Shark")
	/* Maintainer: Alexander Schulz */
	.atag_offset	= 0x3000,
	.map_io		= shark_map_io,
	.init_irq	= shark_init_irq,
	.timer		= &shark_timer,
	.dma_zone_size	= SZ_4M,
MACHINE_END