blob: 54c34a6f92c7b0940ca2a6c3b4d16edbb65b3825 [file] [log] [blame]
Javier Martin3b161e52010-07-30 10:06:01 +02001/*
2 * mach-imx27_visstrim_m10.c
3 *
4 * Copyright 2010 Javier Martin <javier.martin@vista-silicon.com>
5 *
6 * Based on mach-pcm038.c, mach-pca100.c, mach-mx27ads.c and others.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301, USA.
22 */
23
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26#include <linux/platform_device.h>
27#include <linux/mtd/physmap.h>
28#include <linux/i2c.h>
29#include <linux/i2c/pca953x.h>
Javier Martin3b161e52010-07-30 10:06:01 +020030#include <linux/input.h>
31#include <linux/gpio.h>
Sascha Hauer4bd597b2011-01-03 11:30:28 +010032#include <linux/delay.h>
Javier Martinf52f5a52012-02-28 17:31:51 +010033#include <linux/dma-mapping.h>
Javier Martinacb64642012-02-29 13:17:33 +010034#include <linux/leds.h>
Javier Martinf52f5a52012-02-28 17:31:51 +010035#include <linux/memblock.h>
36#include <media/soc_camera.h>
Javier Martinc86566b2011-06-07 17:37:18 +020037#include <sound/tlv320aic32x4.h>
Javier Martin3b161e52010-07-30 10:06:01 +020038#include <asm/mach-types.h>
39#include <asm/mach/arch.h>
40#include <asm/mach/time.h>
Javier Martin435ca242012-04-10 11:26:59 +020041#include <asm/system.h>
Javier Martin3b161e52010-07-30 10:06:01 +020042#include <mach/common.h>
Shawn Guo438196c2011-12-05 10:12:28 +080043#include <mach/hardware.h>
Sascha Hauerc0450df2011-05-09 18:29:00 +020044#include <mach/iomux-mx27.h>
Javier Martin3b161e52010-07-30 10:06:01 +020045
46#include "devices-imx27.h"
Javier Martin3b161e52010-07-30 10:06:01 +020047
Javier Martinf52f5a52012-02-28 17:31:51 +010048#define TVP5150_RSTN (GPIO_PORTC + 18)
49#define TVP5150_PWDN (GPIO_PORTC + 19)
Javier Martin3b161e52010-07-30 10:06:01 +020050#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
Shawn Guo438196c2011-12-05 10:12:28 +080051#define SDHC1_IRQ_GPIO IMX_GPIO_NR(2, 25)
Javier Martin3b161e52010-07-30 10:06:01 +020052
Javier Martin435ca242012-04-10 11:26:59 +020053#define MOTHERBOARD_BIT2 (GPIO_PORTD + 31)
54#define MOTHERBOARD_BIT1 (GPIO_PORTD + 30)
55#define MOTHERBOARD_BIT0 (GPIO_PORTD + 29)
56
57#define EXPBOARD_BIT2 (GPIO_PORTD + 25)
58#define EXPBOARD_BIT1 (GPIO_PORTD + 27)
59#define EXPBOARD_BIT0 (GPIO_PORTD + 28)
60
Uwe Kleine-König6c80ee52010-09-28 21:53:31 +020061static const int visstrim_m10_pins[] __initconst = {
Javier Martin3b161e52010-07-30 10:06:01 +020062 /* UART1 (console) */
63 PE12_PF_UART1_TXD,
64 PE13_PF_UART1_RXD,
65 PE14_PF_UART1_CTS,
66 PE15_PF_UART1_RTS,
67 /* FEC */
68 PD0_AIN_FEC_TXD0,
69 PD1_AIN_FEC_TXD1,
70 PD2_AIN_FEC_TXD2,
71 PD3_AIN_FEC_TXD3,
72 PD4_AOUT_FEC_RX_ER,
73 PD5_AOUT_FEC_RXD1,
74 PD6_AOUT_FEC_RXD2,
75 PD7_AOUT_FEC_RXD3,
76 PD8_AF_FEC_MDIO,
77 PD9_AIN_FEC_MDC,
78 PD10_AOUT_FEC_CRS,
79 PD11_AOUT_FEC_TX_CLK,
80 PD12_AOUT_FEC_RXD0,
81 PD13_AOUT_FEC_RX_DV,
82 PD14_AOUT_FEC_RX_CLK,
83 PD15_AOUT_FEC_COL,
84 PD16_AIN_FEC_TX_ER,
85 PF23_AIN_FEC_TX_EN,
Javier Martina5e20512011-03-01 15:02:08 +010086 /* SSI1 */
87 PC20_PF_SSI1_FS,
88 PC21_PF_SSI1_RXD,
89 PC22_PF_SSI1_TXD,
90 PC23_PF_SSI1_CLK,
Javier Martin3b161e52010-07-30 10:06:01 +020091 /* SDHC1 */
92 PE18_PF_SD1_D0,
93 PE19_PF_SD1_D1,
94 PE20_PF_SD1_D2,
95 PE21_PF_SD1_D3,
96 PE22_PF_SD1_CMD,
97 PE23_PF_SD1_CLK,
98 /* Both I2Cs */
99 PD17_PF_I2C_DATA,
100 PD18_PF_I2C_CLK,
101 PC5_PF_I2C2_SDA,
102 PC6_PF_I2C2_SCL,
103 /* USB OTG */
104 OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
105 PC9_PF_USBOTG_DATA0,
106 PC11_PF_USBOTG_DATA1,
107 PC10_PF_USBOTG_DATA2,
108 PC13_PF_USBOTG_DATA3,
109 PC12_PF_USBOTG_DATA4,
110 PC7_PF_USBOTG_DATA5,
111 PC8_PF_USBOTG_DATA6,
112 PE25_PF_USBOTG_DATA7,
113 PE24_PF_USBOTG_CLK,
114 PE2_PF_USBOTG_DIR,
115 PE0_PF_USBOTG_NXT,
116 PE1_PF_USBOTG_STP,
117 PB23_PF_USB_PWR,
118 PB24_PF_USB_OC,
Javier Martinf52f5a52012-02-28 17:31:51 +0100119 /* CSI */
120 PB10_PF_CSI_D0,
121 PB11_PF_CSI_D1,
122 PB12_PF_CSI_D2,
123 PB13_PF_CSI_D3,
124 PB14_PF_CSI_D4,
125 PB15_PF_CSI_MCLK,
126 PB16_PF_CSI_PIXCLK,
127 PB17_PF_CSI_D5,
128 PB18_PF_CSI_D6,
129 PB19_PF_CSI_D7,
130 PB20_PF_CSI_VSYNC,
131 PB21_PF_CSI_HSYNC,
Javier Martin435ca242012-04-10 11:26:59 +0200132 /* mother board version */
133 MOTHERBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
134 MOTHERBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
135 MOTHERBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
136 /* expansion board version */
137 EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
138 EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
139 EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
140};
141
142static struct gpio visstrim_m10_version_gpios[] = {
143 { EXPBOARD_BIT0, GPIOF_IN, "exp-version-0" },
144 { EXPBOARD_BIT1, GPIOF_IN, "exp-version-1" },
145 { EXPBOARD_BIT2, GPIOF_IN, "exp-version-2" },
146 { MOTHERBOARD_BIT0, GPIOF_IN, "mother-version-0" },
147 { MOTHERBOARD_BIT1, GPIOF_IN, "mother-version-1" },
148 { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" },
Javier Martin3b161e52010-07-30 10:06:01 +0200149};
150
Javier Martinf52f5a52012-02-28 17:31:51 +0100151/* Camera */
152static int visstrim_camera_power(struct device *dev, int on)
153{
154 gpio_set_value(TVP5150_PWDN, on);
155
156 return 0;
157};
158
159static int visstrim_camera_reset(struct device *dev)
160{
161 gpio_set_value(TVP5150_RSTN, 0);
162 ndelay(500);
163 gpio_set_value(TVP5150_RSTN, 1);
164
165 return 0;
166};
167
168static struct i2c_board_info visstrim_i2c_camera = {
169 I2C_BOARD_INFO("tvp5150", 0x5d),
170};
171
172static struct soc_camera_link iclink_tvp5150 = {
173 .bus_id = 0,
174 .board_info = &visstrim_i2c_camera,
175 .i2c_adapter_id = 0,
176 .power = visstrim_camera_power,
177 .reset = visstrim_camera_reset,
178};
179
180static struct mx2_camera_platform_data visstrim_camera = {
181 .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
Javier Martin5ff203b2012-03-26 09:17:47 -0300182 MX2_CAMERA_PCLK_SAMPLE_RISING,
Javier Martinf52f5a52012-02-28 17:31:51 +0100183 .clk = 100000,
184};
185
186static phys_addr_t mx2_camera_base __initdata;
187#define MX2_CAMERA_BUF_SIZE SZ_8M
188
189static void __init visstrim_camera_init(void)
190{
191 struct platform_device *pdev;
192 int dma;
193
194 /* Initialize tvp5150 gpios */
195 mxc_gpio_mode(TVP5150_RSTN | GPIO_GPIO | GPIO_OUT);
196 mxc_gpio_mode(TVP5150_PWDN | GPIO_GPIO | GPIO_OUT);
197 gpio_set_value(TVP5150_RSTN, 1);
198 gpio_set_value(TVP5150_PWDN, 0);
199 ndelay(1);
200
201 gpio_set_value(TVP5150_PWDN, 1);
202 ndelay(1);
203 gpio_set_value(TVP5150_RSTN, 0);
204 ndelay(500);
205 gpio_set_value(TVP5150_RSTN, 1);
206 ndelay(200000);
207
208 pdev = imx27_add_mx2_camera(&visstrim_camera);
209 if (IS_ERR(pdev))
210 return;
211
212 dma = dma_declare_coherent_memory(&pdev->dev,
213 mx2_camera_base, mx2_camera_base,
214 MX2_CAMERA_BUF_SIZE,
215 DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
216 if (!(dma & DMA_MEMORY_MAP))
217 return;
218}
219
220static void __init visstrim_reserve(void)
221{
222 /* reserve 4 MiB for mx2-camera */
223 mx2_camera_base = memblock_alloc(MX2_CAMERA_BUF_SIZE,
224 MX2_CAMERA_BUF_SIZE);
225 memblock_free(mx2_camera_base, MX2_CAMERA_BUF_SIZE);
226 memblock_remove(mx2_camera_base, MX2_CAMERA_BUF_SIZE);
227}
228
Javier Martin3b161e52010-07-30 10:06:01 +0200229/* GPIOs used as events for applications */
230static struct gpio_keys_button visstrim_gpio_keys[] = {
231 {
232 .type = EV_KEY,
233 .code = KEY_RESTART,
234 .gpio = (GPIO_PORTC + 15),
235 .desc = "Default config",
236 .active_low = 0,
237 .wakeup = 1,
238 },
239 {
240 .type = EV_KEY,
241 .code = KEY_RECORD,
242 .gpio = (GPIO_PORTF + 14),
243 .desc = "Record",
244 .active_low = 0,
245 .wakeup = 1,
246 },
247 {
248 .type = EV_KEY,
249 .code = KEY_STOP,
250 .gpio = (GPIO_PORTF + 13),
251 .desc = "Stop",
252 .active_low = 0,
253 .wakeup = 1,
254 }
255};
256
Uwe Kleine-König53094982011-02-28 18:04:33 +0100257static const struct gpio_keys_platform_data
258 visstrim_gpio_keys_platform_data __initconst = {
Javier Martin3b161e52010-07-30 10:06:01 +0200259 .buttons = visstrim_gpio_keys,
260 .nbuttons = ARRAY_SIZE(visstrim_gpio_keys),
261};
262
Javier Martinacb64642012-02-29 13:17:33 +0100263/* led */
264static const struct gpio_led visstrim_m10_leds[] __initconst = {
265 {
266 .name = "visstrim:ld0",
267 .default_trigger = "nand-disk",
268 .gpio = (GPIO_PORTC + 29),
269 },
270 {
271 .name = "visstrim:ld1",
272 .default_trigger = "nand-disk",
273 .gpio = (GPIO_PORTC + 24),
274 },
275 {
276 .name = "visstrim:ld2",
277 .default_trigger = "nand-disk",
278 .gpio = (GPIO_PORTC + 28),
279 },
280 {
281 .name = "visstrim:ld3",
282 .default_trigger = "nand-disk",
283 .gpio = (GPIO_PORTC + 25),
284 },
285};
286
287static const struct gpio_led_platform_data visstrim_m10_led_data __initconst = {
288 .leds = visstrim_m10_leds,
289 .num_leds = ARRAY_SIZE(visstrim_m10_leds),
290};
291
Javier Martin3b161e52010-07-30 10:06:01 +0200292/* Visstrim_SM10 has a microSD slot connected to sdhc1 */
293static int visstrim_m10_sdhc1_init(struct device *dev,
294 irq_handler_t detect_irq, void *data)
295{
296 int ret;
297
Shawn Guo438196c2011-12-05 10:12:28 +0800298 ret = request_irq(gpio_to_irq(SDHC1_IRQ_GPIO), detect_irq,
299 IRQF_TRIGGER_FALLING, "mmc-detect", data);
Javier Martin3b161e52010-07-30 10:06:01 +0200300 return ret;
301}
302
303static void visstrim_m10_sdhc1_exit(struct device *dev, void *data)
304{
Shawn Guo438196c2011-12-05 10:12:28 +0800305 free_irq(gpio_to_irq(SDHC1_IRQ_GPIO), data);
Javier Martin3b161e52010-07-30 10:06:01 +0200306}
307
Uwe Kleine-König9d3d9452010-11-05 17:26:09 +0100308static const struct imxmmc_platform_data visstrim_m10_sdhc_pdata __initconst = {
Javier Martin3b161e52010-07-30 10:06:01 +0200309 .init = visstrim_m10_sdhc1_init,
310 .exit = visstrim_m10_sdhc1_exit,
311};
312
313/* Visstrim_SM10 NOR flash */
314static struct physmap_flash_data visstrim_m10_flash_data = {
315 .width = 2,
316};
317
318static struct resource visstrim_m10_flash_resource = {
319 .start = 0xc0000000,
320 .end = 0xc0000000 + SZ_64M - 1,
321 .flags = IORESOURCE_MEM,
322};
323
324static struct platform_device visstrim_m10_nor_mtd_device = {
325 .name = "physmap-flash",
326 .id = 0,
327 .dev = {
328 .platform_data = &visstrim_m10_flash_data,
329 },
330 .num_resources = 1,
331 .resource = &visstrim_m10_flash_resource,
332};
333
334static struct platform_device *platform_devices[] __initdata = {
Javier Martin3b161e52010-07-30 10:06:01 +0200335 &visstrim_m10_nor_mtd_device,
Javier Martin3b161e52010-07-30 10:06:01 +0200336};
337
338/* Visstrim_M10 uses UART0 as console */
339static const struct imxuart_platform_data uart_pdata __initconst = {
340 .flags = IMXUART_HAVE_RTSCTS,
341};
342
343/* I2C */
344static const struct imxi2c_platform_data visstrim_m10_i2c_data __initconst = {
345 .bitrate = 100000,
346};
347
348static struct pca953x_platform_data visstrim_m10_pca9555_pdata = {
349 .gpio_base = 240, /* After MX27 internal GPIOs */
350 .invert = 0,
351};
352
Javier Martinc86566b2011-06-07 17:37:18 +0200353static struct aic32x4_pdata visstrim_m10_aic32x4_pdata = {
354 .power_cfg = AIC32X4_PWR_MICBIAS_2075_LDOIN |
355 AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE |
356 AIC32X4_PWR_AIC32X4_LDO_ENABLE |
357 AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 |
358 AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED,
359 .micpga_routing = AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K |
360 AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K,
361 .swapdacs = false,
362};
363
Javier Martin3b161e52010-07-30 10:06:01 +0200364static struct i2c_board_info visstrim_m10_i2c_devices[] = {
365 {
366 I2C_BOARD_INFO("pca9555", 0x20),
367 .platform_data = &visstrim_m10_pca9555_pdata,
368 },
Javier Martina5e20512011-03-01 15:02:08 +0100369 {
370 I2C_BOARD_INFO("tlv320aic32x4", 0x18),
Javier Martinc86566b2011-06-07 17:37:18 +0200371 .platform_data = &visstrim_m10_aic32x4_pdata,
Javier Martin257b49c2012-02-28 11:16:59 +0100372 },
373 {
374 I2C_BOARD_INFO("m41t00", 0x68),
Javier Martina5e20512011-03-01 15:02:08 +0100375 }
Javier Martin3b161e52010-07-30 10:06:01 +0200376};
377
378/* USB OTG */
379static int otg_phy_init(struct platform_device *pdev)
380{
381 gpio_set_value(OTG_PHY_CS_GPIO, 0);
Sascha Hauer4bd597b2011-01-03 11:30:28 +0100382
383 mdelay(10);
384
385 return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
Javier Martin3b161e52010-07-30 10:06:01 +0200386}
387
Uwe Kleine-König2eb42d52010-11-05 18:52:09 +0100388static const struct mxc_usbh_platform_data
389visstrim_m10_usbotg_pdata __initconst = {
Javier Martin3b161e52010-07-30 10:06:01 +0200390 .init = otg_phy_init,
391 .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
Javier Martin3b161e52010-07-30 10:06:01 +0200392};
393
Javier Martina5e20512011-03-01 15:02:08 +0100394/* SSI */
395static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = {
396 .flags = IMX_SSI_DMA | IMX_SSI_SYN,
397};
398
Javier Martin435ca242012-04-10 11:26:59 +0200399static void __init visstrim_m10_revision(void)
400{
401 int exp_version = 0;
402 int mo_version = 0;
403 int ret;
404
405 ret = gpio_request_array(visstrim_m10_version_gpios,
406 ARRAY_SIZE(visstrim_m10_version_gpios));
407 if (ret) {
408 pr_err("Failed to request version gpios");
409 return;
410 }
411
412 /* Get expansion board version (negative logic) */
413 exp_version |= !gpio_get_value(EXPBOARD_BIT2) << 2;
414 exp_version |= !gpio_get_value(EXPBOARD_BIT1) << 1;
415 exp_version |= !gpio_get_value(EXPBOARD_BIT0);
416
417 /* Get mother board version (negative logic) */
418 mo_version |= !gpio_get_value(MOTHERBOARD_BIT2) << 2;
419 mo_version |= !gpio_get_value(MOTHERBOARD_BIT1) << 1;
420 mo_version |= !gpio_get_value(MOTHERBOARD_BIT0);
421
422 system_rev = 0x27000;
423 system_rev |= (mo_version << 4);
424 system_rev |= exp_version;
425}
426
Javier Martin3b161e52010-07-30 10:06:01 +0200427static void __init visstrim_m10_board_init(void)
428{
429 int ret;
430
Shawn Guob78d8e52011-06-06 00:07:55 +0800431 imx27_soc_init();
Javier Martin435ca242012-04-10 11:26:59 +0200432 visstrim_m10_revision();
Shawn Guob78d8e52011-06-06 00:07:55 +0800433
Javier Martin3b161e52010-07-30 10:06:01 +0200434 ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
435 ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
436 if (ret)
437 pr_err("Failed to setup pins (%d)\n", ret);
438
Javier Martina5e20512011-03-01 15:02:08 +0100439 imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata);
Javier Martin3b161e52010-07-30 10:06:01 +0200440 imx27_add_imx_uart0(&uart_pdata);
441
Uwe Kleine-König77a406d2010-08-25 12:19:50 +0200442 imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
443 imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
Javier Martinbaa1dee2012-02-28 17:31:49 +0100444 i2c_register_board_info(0, visstrim_m10_i2c_devices,
445 ARRAY_SIZE(visstrim_m10_i2c_devices));
446
Uwe Kleine-König9d3d9452010-11-05 17:26:09 +0100447 imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata);
Uwe Kleine-König2eb42d52010-11-05 18:52:09 +0100448 imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata);
Uwe Kleine-König6bd96f32010-10-06 12:00:18 +0200449 imx27_add_fec(NULL);
Uwe Kleine-König53094982011-02-28 18:04:33 +0100450 imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
Javier Martin3b161e52010-07-30 10:06:01 +0200451 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
Fabio Estevam5ec65ee2012-03-12 19:48:49 -0300452 imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0);
Javier Martinf52f5a52012-02-28 17:31:51 +0100453 platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0,
454 &iclink_tvp5150, sizeof(iclink_tvp5150));
Javier Martinacb64642012-02-29 13:17:33 +0100455 gpio_led_register_device(0, &visstrim_m10_led_data);
Javier Martinf52f5a52012-02-28 17:31:51 +0100456 visstrim_camera_init();
Javier Martin3b161e52010-07-30 10:06:01 +0200457}
458
459static void __init visstrim_m10_timer_init(void)
460{
461 mx27_clocks_init((unsigned long)25000000);
462}
463
464static struct sys_timer visstrim_m10_timer = {
465 .init = visstrim_m10_timer_init,
466};
467
468MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10")
Nicolas Pitredc8f1902011-07-05 22:38:12 -0400469 .atag_offset = 0x100,
Javier Martinf52f5a52012-02-28 17:31:51 +0100470 .reserve = visstrim_reserve,
Uwe Kleine-König3dac2192011-02-07 16:35:19 +0100471 .map_io = mx27_map_io,
472 .init_early = imx27_init_early,
473 .init_irq = mx27_init_irq,
Sascha Hauerffa2ea32011-09-20 14:31:24 +0200474 .handle_irq = imx27_handle_irq,
Uwe Kleine-König3dac2192011-02-07 16:35:19 +0100475 .timer = &visstrim_m10_timer,
476 .init_machine = visstrim_m10_board_init,
Russell King65ea7882011-11-06 17:12:08 +0000477 .restart = mxc_restart,
Javier Martin3b161e52010-07-30 10:06:01 +0200478MACHINE_END