1b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/*
2b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * Copyright (c) 2011 Samsung Electronics Co., Ltd.
3b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim *		http://www.samsung.com
4b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim *
5b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * Copyright 2008 Openmoko, Inc.
6b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * Copyright 2008 Simtec Electronics
7b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim *	Ben Dooks <ben@simtec.co.uk>
8b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim *	http://armlinux.simtec.co.uk/
9b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim *
10b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * Common Codes for S3C64XX machines
11b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim *
12b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * This program is free software; you can redistribute it and/or modify
13b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * it under the terms of the GNU General Public License version 2 as
14b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * published by the Free Software Foundation.
15b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim */
16b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
17c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa/*
18c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa * NOTE: Code in this file is not used when booting with Device Tree support.
19c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa */
20c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa
21b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/kernel.h>
22b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/init.h>
23b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/module.h>
24b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa#include <linux/clk-provider.h>
25b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/interrupt.h>
26b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/ioport.h>
27b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/serial_core.h>
28334a1c70bb03d7077849e88d8571a32d1d36194dTushar Behera#include <linux/serial_s3c.h>
29b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/platform_device.h>
307b6d864b48d95e6ea1df7df64475b9cb9616dcf9Robin Holt#include <linux/reboot.h>
31b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/io.h>
32b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/dma-mapping.h>
33b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/irq.h>
34b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <linux/gpio.h>
359e47b8bf9815523a5816f2f83e73b13812d74014Rob Herring#include <linux/irqchip/arm-vic.h>
361c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa#include <clocksource/samsung_pwm.h>
37b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
38b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <asm/mach/arch.h>
39b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <asm/mach/map.h>
409f97da78bf018206fb623cd351d454af2f105fe0David Howells#include <asm/system_misc.h>
41b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
42b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <mach/map.h>
43b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <mach/hardware.h>
44b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <mach/regs-gpio.h>
45b0161caa72b6ff60f82f5531b9b728f3b6d19e1bLinus Walleij#include <mach/gpio-samsung.h>
46b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
47b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <plat/cpu.h>
48b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <plat/devs.h>
49b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <plat/pm.h>
50b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <plat/gpio-cfg.h>
51b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <plat/irq-uart.h>
521c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa#include <plat/pwm-core.h>
53b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include <plat/regs-irqtype.h>
54ff84ded26525adb4c0dcef3a4d590b0d08967293Kukjin Kim#include <plat/watchdog-reset.h>
55b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
56b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#include "common.h"
57b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
58b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa/* External clock frequency */
59b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figastatic unsigned long xtal_f = 12000000, xusbxti_f = 48000000;
60b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa
61b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figavoid __init s3c64xx_set_xtal_freq(unsigned long freq)
62b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa{
63b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa	xtal_f = freq;
64b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa}
65b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa
66b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figavoid __init s3c64xx_set_xusbxti_freq(unsigned long freq)
67b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa{
68b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa	xusbxti_f = freq;
69b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa}
70b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa
71b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/* uart registration process */
72b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
73b7c9705cb799adabc0ae430943843e6c6e82617dMark Brownstatic void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
74b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
75b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
76b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
77b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
78b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/* table of supported CPUs */
79b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
80b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic const char name_s3c6400[] = "S3C6400";
81b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic const char name_s3c6410[] = "S3C6410";
82b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
83b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic struct cpu_table cpu_ids[] __initdata = {
84b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	{
85b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.idcode		= S3C6400_CPU_ID,
86b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.idmask		= S3C64XX_CPU_MASK,
87b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.map_io		= s3c6400_map_io,
88b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.init_uarts	= s3c64xx_init_uarts,
89b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.init		= s3c6400_init,
90b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.name		= name_s3c6400,
91b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
92b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.idcode		= S3C6410_CPU_ID,
93b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.idmask		= S3C64XX_CPU_MASK,
94b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.map_io		= s3c6410_map_io,
95b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.init_uarts	= s3c64xx_init_uarts,
96b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.init		= s3c6410_init,
97b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.name		= name_s3c6410,
98b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	},
99b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim};
100b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
101b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/* minimal IO mapping */
102b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
103b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/* see notes on uart map in arch/arm/mach-s3c64xx/include/mach/debug-macro.S */
104b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#define UART_OFFS (S3C_PA_UART & 0xfffff)
105b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
106b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic struct map_desc s3c_iodesc[] __initdata = {
107b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	{
108b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)S3C_VA_SYS,
109b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_SYSCON),
110b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_4K,
111b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
112b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
113b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)S3C_VA_MEM,
114b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_SROM),
115b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_4K,
116b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
117b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
118b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)(S3C_VA_UART + UART_OFFS),
119b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C_PA_UART),
120b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_4K,
121b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
122b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
123b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)VA_VIC0,
124b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC0),
125b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_16K,
126b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
127b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
128b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)VA_VIC1,
129b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC1),
130b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_16K,
131b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
132b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
133b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)S3C_VA_TIMER,
134b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C_PA_TIMER),
135b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_16K,
136b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
137b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
138b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)S3C64XX_VA_GPIO,
139b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_GPIO),
140b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_4K,
141b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
142b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
143b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)S3C64XX_VA_MODEM,
144b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_MODEM),
145b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_4K,
146b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
147b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
148b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)S3C_VA_WATCHDOG,
149b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_WATCHDOG),
150b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_4K,
151b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
152b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}, {
153b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.virtual	= (unsigned long)S3C_VA_USB_HSPHY,
154b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.pfn		= __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
155b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.length		= SZ_1K,
156b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		.type		= MT_DEVICE,
157b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	},
158b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim};
159b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
1607affca3537d74365128e477b40c529d6f2fe86c8Linus Torvaldsstatic struct bus_type s3c64xx_subsys = {
1617affca3537d74365128e477b40c529d6f2fe86c8Linus Torvalds	.name		= "s3c64xx-core",
1627affca3537d74365128e477b40c529d6f2fe86c8Linus Torvalds	.dev_name	= "s3c64xx-core",
163b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim};
164b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
1657affca3537d74365128e477b40c529d6f2fe86c8Linus Torvaldsstatic struct device s3c64xx_dev = {
1667affca3537d74365128e477b40c529d6f2fe86c8Linus Torvalds	.bus	= &s3c64xx_subsys,
167b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim};
168b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
1691c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figastatic struct samsung_pwm_variant s3c64xx_pwm_variant = {
1701c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa	.bits		= 32,
1711c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa	.div_base	= 0,
1721c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa	.has_tint_cstat	= true,
1731c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
1741c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa};
1751c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa
1764280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figavoid __init samsung_set_timer_source(unsigned int event, unsigned int source)
1774280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa{
1784280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
1794280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
1804280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa}
1814280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa
1824280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figavoid __init samsung_timer_init(void)
1834280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa{
1844280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
1854280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
1864280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
1874280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa	};
1884280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa
1894280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa	samsung_pwm_clocksource_init(S3C_VA_TIMER,
1904280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa					timer_irqs, &s3c64xx_pwm_variant);
1914280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa}
1924280506ac9bb17f2450cf1042edf929d26d24a8eTomasz Figa
193b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/* read cpu identification code */
194b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
195b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimvoid __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
196b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
197b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	/* initialise the io descriptors we need for initialisation */
198b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
199b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	iotable_init(mach_desc, size);
200b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
201b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	/* detect cpu id */
202b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c64xx_init_cpu();
203b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
204b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
2051c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa
2061c161fd0d453ff63c8bb3a703d46d10ac5eba7a4Tomasz Figa	samsung_pwm_set_platdata(&s3c64xx_pwm_variant);
207b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
208b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
2097affca3537d74365128e477b40c529d6f2fe86c8Linus Torvaldsstatic __init int s3c64xx_dev_init(void)
210b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
211c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa	/* Not applicable when using DT. */
212c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa	if (of_have_populated_dt())
213c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa		return 0;
214c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa
2157affca3537d74365128e477b40c529d6f2fe86c8Linus Torvalds	subsys_system_register(&s3c64xx_subsys, NULL);
2167affca3537d74365128e477b40c529d6f2fe86c8Linus Torvalds	return device_register(&s3c64xx_dev);
217b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
2187affca3537d74365128e477b40c529d6f2fe86c8Linus Torvaldscore_initcall(s3c64xx_dev_init);
219b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
220b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/*
221b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * setup the sources the vic should advertise resume
222b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * for, even though it is not doing the wake
223b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * (set_irq_wake needs to be valid)
224b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim */
225b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
226b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) |	\
227b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim			 1 << (IRQ_PENDN - IRQ_VIC1_BASE) |	\
228b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim			 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) |	\
229b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim			 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) |	\
230b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim			 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE))
231b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
232b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimvoid __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
233b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
23488f597383824c7a67b3120a3584afca85b91e7bbTomasz Figa	/*
23588f597383824c7a67b3120a3584afca85b91e7bbTomasz Figa	 * FIXME: there is no better place to put this at the moment
236b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa	 * (s3c64xx_clk_init needs ioremap and must happen before init_time
237b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa	 * samsung_wdt_reset_init needs clocks)
23888f597383824c7a67b3120a3584afca85b91e7bbTomasz Figa	 */
239b69f460dc1a074db3f759c2be9cd13271f91fbddTomasz Figa	s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);
24088f597383824c7a67b3120a3584afca85b91e7bbTomasz Figa	samsung_wdt_reset_init(S3C_VA_WATCHDOG);
24188f597383824c7a67b3120a3584afca85b91e7bbTomasz Figa
242b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
243b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
244b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	/* initialise the pair of VICs */
245b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
246b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
247b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
248b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
249b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#define eint_offset(irq)	((irq) - IRQ_EINT(0))
250b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim#define eint_irq_to_bit(irq)	((u32)(1 << eint_offset(irq)))
251b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
252b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic inline void s3c_irq_eint_mask(struct irq_data *data)
253b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
254b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	u32 mask;
255b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
256b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	mask = __raw_readl(S3C64XX_EINT0MASK);
257b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	mask |= (u32)data->chip_data;
258b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	__raw_writel(mask, S3C64XX_EINT0MASK);
259b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
260b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
261b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic void s3c_irq_eint_unmask(struct irq_data *data)
262b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
263b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	u32 mask;
264b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
265b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	mask = __raw_readl(S3C64XX_EINT0MASK);
266b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	mask &= ~((u32)data->chip_data);
267b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	__raw_writel(mask, S3C64XX_EINT0MASK);
268b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
269b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
270b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic inline void s3c_irq_eint_ack(struct irq_data *data)
271b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
272b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	__raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
273b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
274b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
275b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic void s3c_irq_eint_maskack(struct irq_data *data)
276b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
277b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	/* compiler should in-line these */
278b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_irq_eint_mask(data);
279b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_irq_eint_ack(data);
280b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
281b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
282b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
283b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
284b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	int offs = eint_offset(data->irq);
285b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	int pin, pin_val;
286b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	int shift;
287b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	u32 ctrl, mask;
288b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	u32 newvalue = 0;
289b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	void __iomem *reg;
290b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
291b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	if (offs > 27)
292b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		return -EINVAL;
293b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
294b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	if (offs <= 15)
295b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		reg = S3C64XX_EINT0CON0;
296b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	else
297b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		reg = S3C64XX_EINT0CON1;
298b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
299b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	switch (type) {
300b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	case IRQ_TYPE_NONE:
301b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		printk(KERN_WARNING "No edge setting!\n");
302b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		break;
303b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
304b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	case IRQ_TYPE_EDGE_RISING:
305b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		newvalue = S3C2410_EXTINT_RISEEDGE;
306b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		break;
307b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
308b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	case IRQ_TYPE_EDGE_FALLING:
309b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		newvalue = S3C2410_EXTINT_FALLEDGE;
310b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		break;
311b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
312b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	case IRQ_TYPE_EDGE_BOTH:
313b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		newvalue = S3C2410_EXTINT_BOTHEDGE;
314b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		break;
315b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
316b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	case IRQ_TYPE_LEVEL_LOW:
317b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		newvalue = S3C2410_EXTINT_LOWLEV;
318b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		break;
319b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
320b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	case IRQ_TYPE_LEVEL_HIGH:
321b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		newvalue = S3C2410_EXTINT_HILEV;
322b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		break;
323b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
324b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	default:
325b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		printk(KERN_ERR "No such irq type %d", type);
326b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		return -1;
327b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}
328b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
329b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	if (offs <= 15)
330b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		shift = (offs / 2) * 4;
331b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	else
332b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		shift = ((offs - 16) / 2) * 4;
333b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	mask = 0x7 << shift;
334b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
335b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	ctrl = __raw_readl(reg);
336b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	ctrl &= ~mask;
337b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	ctrl |= newvalue << shift;
338b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	__raw_writel(ctrl, reg);
339b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
340b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	/* set the GPIO pin appropriately */
341b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
342b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	if (offs < 16) {
343b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		pin = S3C64XX_GPN(offs);
344b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		pin_val = S3C_GPIO_SFN(2);
345b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	} else if (offs < 23) {
346b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		pin = S3C64XX_GPL(offs + 8 - 16);
347b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		pin_val = S3C_GPIO_SFN(3);
348b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	} else {
349b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		pin = S3C64XX_GPM(offs - 23);
350b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		pin_val = S3C_GPIO_SFN(3);
351b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}
352b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
353b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_gpio_cfgpin(pin, pin_val);
354b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
355b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	return 0;
356b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
357b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
358b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic struct irq_chip s3c_irq_eint = {
359b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	.name		= "s3c-eint",
360b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	.irq_mask	= s3c_irq_eint_mask,
361b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	.irq_unmask	= s3c_irq_eint_unmask,
362b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	.irq_mask_ack	= s3c_irq_eint_maskack,
363b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	.irq_ack	= s3c_irq_eint_ack,
364b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	.irq_set_type	= s3c_irq_eint_set_type,
365b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	.irq_set_wake	= s3c_irqext_wake,
366b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim};
367b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
368b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim/* s3c_irq_demux_eint
369b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim *
370b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * This function demuxes the IRQ from the group0 external interrupts,
371b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
372b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim * the specific handlers s3c_irq_demux_eintX_Y.
373b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim */
374b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
375b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
376b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	u32 status = __raw_readl(S3C64XX_EINT0PEND);
377b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	u32 mask = __raw_readl(S3C64XX_EINT0MASK);
378b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	unsigned int irq;
379b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
380b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	status &= ~mask;
381b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	status >>= start;
382b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	status &= (1 << (end - start + 1)) - 1;
383b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
384b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
385b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		if (status & 1)
386b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim			generic_handle_irq(irq);
387b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
388b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		status >>= 1;
389b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}
390b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
391b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
392b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
393b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
394b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_irq_demux_eint(0, 3);
395b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
396b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
397b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
398b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
399b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_irq_demux_eint(4, 11);
400b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
401b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
402b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
403b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
404b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_irq_demux_eint(12, 19);
405b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
406b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
407b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
408b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
409b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	s3c_irq_demux_eint(20, 27);
410b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
411b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
412b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimstatic int __init s3c64xx_init_irq_eint(void)
413b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim{
414b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	int irq;
415b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
416c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa	/* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */
417c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa	if (of_have_populated_dt())
418c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa		return -ENODEV;
419c836c90e276ec1b1b4193bb6f0b5e6b11cc69f83Tomasz Figa
420b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
421b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq);
422b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq));
423b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim		set_irq_flags(irq, IRQF_VALID);
424b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	}
425b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
426b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
427b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
428b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
429b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
430b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim
431b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim	return 0;
432b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kim}
433b024043b6d0d3feecb1de350de9762a00a79eda1Kukjin Kimarch_initcall(s3c64xx_init_irq_eint);
434ff84ded26525adb4c0dcef3a4d590b0d08967293Kukjin Kim
4357b6d864b48d95e6ea1df7df64475b9cb9616dcf9Robin Holtvoid s3c64xx_restart(enum reboot_mode mode, const char *cmd)
436ff84ded26525adb4c0dcef3a4d590b0d08967293Kukjin Kim{
4377b6d864b48d95e6ea1df7df64475b9cb9616dcf9Robin Holt	if (mode != REBOOT_SOFT)
43888f597383824c7a67b3120a3584afca85b91e7bbTomasz Figa		samsung_wdt_reset();
439ff84ded26525adb4c0dcef3a4d590b0d08967293Kukjin Kim
440ff84ded26525adb4c0dcef3a4d590b0d08967293Kukjin Kim	/* if all else fails, or mode was for soft, jump to 0 */
441ff84ded26525adb4c0dcef3a4d590b0d08967293Kukjin Kim	soft_restart(0);
442ff84ded26525adb4c0dcef3a4d590b0d08967293Kukjin Kim}
443