1/*
2 * linux/arch/arm/mach-sa1100/hackkit.c
3 *
4 * Copyright (C) 2002 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
5 *
6 * This file contains all HackKit tweaks. Based on original work from
7 * Nicolas Pitre's assabet fixes
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/tty.h>
18#include <linux/module.h>
19#include <linux/errno.h>
20#include <linux/cpufreq.h>
21#include <linux/platform_data/sa11x0-serial.h>
22#include <linux/serial_core.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25#include <linux/tty.h>
26#include <linux/gpio.h>
27#include <linux/leds.h>
28#include <linux/platform_device.h>
29
30#include <asm/mach-types.h>
31#include <asm/setup.h>
32#include <asm/page.h>
33#include <asm/pgtable.h>
34
35#include <asm/mach/arch.h>
36#include <asm/mach/flash.h>
37#include <asm/mach/map.h>
38#include <asm/mach/irq.h>
39
40#include <mach/hardware.h>
41#include <mach/irqs.h>
42
43#include "generic.h"
44
45/**********************************************************************
46 *  prototypes
47 */
48
49/* init funcs */
50static void __init hackkit_map_io(void);
51
52static u_int hackkit_get_mctrl(struct uart_port *port);
53static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl);
54static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
55
56/**********************************************************************
57 *  global data
58 */
59
60/**********************************************************************
61 *  static data
62 */
63
64static struct map_desc hackkit_io_desc[] __initdata = {
65	{	/* Flash bank 0 */
66		.virtual	=  0xe8000000,
67		.pfn		= __phys_to_pfn(0x00000000),
68		.length		= 0x01000000,
69		.type		= MT_DEVICE
70	},
71};
72
73static struct sa1100_port_fns hackkit_port_fns __initdata = {
74	.set_mctrl	= hackkit_set_mctrl,
75	.get_mctrl	= hackkit_get_mctrl,
76	.pm		= hackkit_uart_pm,
77};
78
79/**********************************************************************
80 *  Static functions
81 */
82
83static void __init hackkit_map_io(void)
84{
85	sa1100_map_io();
86	iotable_init(hackkit_io_desc, ARRAY_SIZE(hackkit_io_desc));
87
88	sa1100_register_uart_fns(&hackkit_port_fns);
89	sa1100_register_uart(0, 1);	/* com port */
90	sa1100_register_uart(1, 2);
91	sa1100_register_uart(2, 3);	/* radio module */
92
93	Ser1SDCR0 |= SDCR0_SUS;
94}
95
96/**
97 *	hackkit_uart_pm - powermgmt callback function for system 3 UART
98 *	@port: uart port structure
99 *	@state: pm state
100 *	@oldstate: old pm state
101 *
102 */
103static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
104{
105	/* TODO: switch on/off uart in powersave mode */
106}
107
108/*
109 * Note! this can be called from IRQ context.
110 * FIXME: No modem ctrl lines yet.
111 */
112static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl)
113{
114#if 0
115	if (port->mapbase == _Ser1UTCR0) {
116		u_int set = 0, clear = 0;
117
118		if (mctrl & TIOCM_RTS)
119			set |= PT_CTRL2_RS1_RTS;
120		else
121			clear |= PT_CTRL2_RS1_RTS;
122
123		if (mctrl & TIOCM_DTR)
124			set |= PT_CTRL2_RS1_DTR;
125		else
126			clear |= PT_CTRL2_RS1_DTR;
127
128		PTCTRL2_clear(clear);
129		PTCTRL2_set(set);
130	}
131#endif
132}
133
134static u_int hackkit_get_mctrl(struct uart_port *port)
135{
136	u_int ret = 0;
137#if 0
138	u_int irqsr = PT_IRQSR;
139
140	/* need 2 reads to read current value */
141	irqsr = PT_IRQSR;
142
143	/* TODO: check IRQ source register for modem/com
144	 status lines and set them correctly. */
145#endif
146
147	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
148
149	return ret;
150}
151
152static struct mtd_partition hackkit_partitions[] = {
153	{
154		.name		= "BLOB",
155		.size		= 0x00040000,
156		.offset		= 0x00000000,
157		.mask_flags	= MTD_WRITEABLE,  /* force read-only */
158	}, {
159		.name		= "config",
160		.size		= 0x00040000,
161		.offset		= MTDPART_OFS_APPEND,
162	}, {
163		.name		= "kernel",
164		.size		= 0x00100000,
165		.offset		= MTDPART_OFS_APPEND,
166	}, {
167		.name		= "initrd",
168		.size		= 0x00180000,
169		.offset		= MTDPART_OFS_APPEND,
170	}, {
171		.name		= "rootfs",
172		.size		= 0x700000,
173		.offset		= MTDPART_OFS_APPEND,
174	}, {
175		.name		= "data",
176		.size		= MTDPART_SIZ_FULL,
177		.offset		= MTDPART_OFS_APPEND,
178	}
179};
180
181static struct flash_platform_data hackkit_flash_data = {
182	.map_name	= "cfi_probe",
183	.parts		= hackkit_partitions,
184	.nr_parts	= ARRAY_SIZE(hackkit_partitions),
185};
186
187static struct resource hackkit_flash_resource =
188	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
189
190/* LEDs */
191struct gpio_led hackkit_gpio_leds[] = {
192	{
193		.name			= "hackkit:red",
194		.default_trigger	= "cpu0",
195		.gpio			= 22,
196	},
197	{
198		.name			= "hackkit:green",
199		.default_trigger	= "heartbeat",
200		.gpio			= 23,
201	},
202};
203
204static struct gpio_led_platform_data hackkit_gpio_led_info = {
205	.leds		= hackkit_gpio_leds,
206	.num_leds	= ARRAY_SIZE(hackkit_gpio_leds),
207};
208
209static struct platform_device hackkit_leds = {
210	.name	= "leds-gpio",
211	.id	= -1,
212	.dev	= {
213		.platform_data	= &hackkit_gpio_led_info,
214	}
215};
216
217static void __init hackkit_init(void)
218{
219	sa11x0_register_mtd(&hackkit_flash_data, &hackkit_flash_resource, 1);
220	platform_device_register(&hackkit_leds);
221}
222
223/**********************************************************************
224 *  Exported Functions
225 */
226
227MACHINE_START(HACKKIT, "HackKit Cpu Board")
228	.atag_offset	= 0x100,
229	.map_io		= hackkit_map_io,
230	.nr_irqs	= SA1100_NR_IRQS,
231	.init_irq	= sa1100_init_irq,
232	.init_time	= sa1100_timer_init,
233	.init_machine	= hackkit_init,
234	.init_late	= sa11x0_init_late,
235	.restart	= sa11x0_restart,
236MACHINE_END
237