Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // Copyright (c) 2011 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) //		http://www.samsung.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) // Copyright 2008 Openmoko, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) // Copyright 2008 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) //	Ben Dooks <ben@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) //	http://armlinux.simtec.co.uk/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) // Common Codes for S3C64XX machines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * NOTE: Code in this file is not used when booting with Device Tree support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/serial_s3c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/clk/samsung.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/irqchip/arm-vic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <clocksource/samsung_pwm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <asm/mach/arch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <asm/mach/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <asm/system_misc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <mach/irqs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include "regs-gpio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include "gpio-samsung.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include "cpu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include "devs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include "pm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include "gpio-cfg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include "pwm-core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include "regs-irqtype.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include "s3c64xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #include "irq-uart-s3c64xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* External clock frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static unsigned long xtal_f __ro_after_init = 12000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static unsigned long xusbxti_f __ro_after_init = 48000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) void __init s3c64xx_set_xtal_freq(unsigned long freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	xtal_f = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) void __init s3c64xx_set_xusbxti_freq(unsigned long freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	xusbxti_f = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /* uart registration process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) /* table of supported CPUs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static const char name_s3c6400[] = "S3C6400";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static const char name_s3c6410[] = "S3C6410";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static struct cpu_table cpu_ids[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		.idcode		= S3C6400_CPU_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		.idmask		= S3C64XX_CPU_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		.map_io		= s3c6400_map_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		.init_uarts	= s3c64xx_init_uarts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		.init		= s3c6400_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		.name		= name_s3c6400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		.idcode		= S3C6410_CPU_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		.idmask		= S3C64XX_CPU_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		.map_io		= s3c6410_map_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		.init_uarts	= s3c64xx_init_uarts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		.init		= s3c6410_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		.name		= name_s3c6410,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) /* minimal IO mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * note, for the boot process to work we have to keep the UART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * virtual address aligned to an 1MiB boundary for the L1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * mapping the head code makes. We keep the UART virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * aligned and add in the offset when we load the value here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define UART_OFFS (S3C_PA_UART & 0xfffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static struct map_desc s3c_iodesc[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		.virtual	= (unsigned long)S3C_VA_SYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		.pfn		= __phys_to_pfn(S3C64XX_PA_SYSCON),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		.length		= SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		.virtual	= (unsigned long)S3C_VA_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		.pfn		= __phys_to_pfn(S3C64XX_PA_SROM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		.length		= SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		.virtual	= (unsigned long)(S3C_VA_UART + UART_OFFS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		.pfn		= __phys_to_pfn(S3C_PA_UART),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		.length		= SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		.virtual	= (unsigned long)VA_VIC0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		.length		= SZ_16K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		.virtual	= (unsigned long)VA_VIC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		.pfn		= __phys_to_pfn(S3C64XX_PA_VIC1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		.length		= SZ_16K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		.virtual	= (unsigned long)S3C_VA_TIMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		.pfn		= __phys_to_pfn(S3C_PA_TIMER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		.length		= SZ_16K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		.virtual	= (unsigned long)S3C64XX_VA_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		.pfn		= __phys_to_pfn(S3C64XX_PA_GPIO),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		.length		= SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		.virtual	= (unsigned long)S3C64XX_VA_MODEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		.pfn		= __phys_to_pfn(S3C64XX_PA_MODEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		.length		= SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		.virtual	= (unsigned long)S3C_VA_WATCHDOG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		.pfn		= __phys_to_pfn(S3C64XX_PA_WATCHDOG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		.length		= SZ_4K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		.virtual	= (unsigned long)S3C_VA_USB_HSPHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		.pfn		= __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		.length		= SZ_1K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		.type		= MT_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct bus_type s3c64xx_subsys = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	.name		= "s3c64xx-core",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	.dev_name	= "s3c64xx-core",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static struct device s3c64xx_dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	.bus	= &s3c64xx_subsys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static struct samsung_pwm_variant s3c64xx_pwm_variant = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	.bits		= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	.div_base	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	.has_tint_cstat	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) void __init s3c64xx_set_timer_source(unsigned int event, unsigned int source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) void __init s3c64xx_timer_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	samsung_pwm_clocksource_init(S3C_VA_TIMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 					timer_irqs, &s3c64xx_pwm_variant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* read cpu identification code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	/* initialise the io descriptors we need for initialisation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	iotable_init(mach_desc, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	/* detect cpu id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	s3c64xx_init_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	samsung_pwm_set_platdata(&s3c64xx_pwm_variant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static __init int s3c64xx_dev_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	/* Not applicable when using DT. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (of_have_populated_dt() || !soc_is_s3c64xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	subsys_system_register(&s3c64xx_subsys, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	return device_register(&s3c64xx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) core_initcall(s3c64xx_dev_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * setup the sources the vic should advertise resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  * for, even though it is not doing the wake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * (set_irq_wake needs to be valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) |	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			 1 << (IRQ_PENDN - IRQ_VIC1_BASE) |	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) |	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) |	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	/* initialise the pair of VICs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define eint_offset(irq)	((irq) - IRQ_EINT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define eint_irq_to_bit(irq)	((u32)(1 << eint_offset(irq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static inline void s3c_irq_eint_mask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	mask = __raw_readl(S3C64XX_EINT0MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	mask |= (u32)data->chip_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	__raw_writel(mask, S3C64XX_EINT0MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static void s3c_irq_eint_unmask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	mask = __raw_readl(S3C64XX_EINT0MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	mask &= ~((u32)data->chip_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	__raw_writel(mask, S3C64XX_EINT0MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static inline void s3c_irq_eint_ack(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	__raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void s3c_irq_eint_maskack(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	/* compiler should in-line these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	s3c_irq_eint_mask(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	s3c_irq_eint_ack(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	int offs = eint_offset(data->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	int pin, pin_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	u32 ctrl, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	u32 newvalue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (offs > 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if (offs <= 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		reg = S3C64XX_EINT0CON0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		reg = S3C64XX_EINT0CON1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	case IRQ_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		printk(KERN_WARNING "No edge setting!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		newvalue = S3C2410_EXTINT_RISEEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		newvalue = S3C2410_EXTINT_FALLEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		newvalue = S3C2410_EXTINT_BOTHEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		newvalue = S3C2410_EXTINT_LOWLEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		newvalue = S3C2410_EXTINT_HILEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		printk(KERN_ERR "No such irq type %d", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	if (offs <= 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		shift = (offs / 2) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		shift = ((offs - 16) / 2) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	mask = 0x7 << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	ctrl = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	ctrl &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	ctrl |= newvalue << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	__raw_writel(ctrl, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	/* set the GPIO pin appropriately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (offs < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		pin = S3C64XX_GPN(offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		pin_val = S3C_GPIO_SFN(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	} else if (offs < 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		pin = S3C64XX_GPL(offs + 8 - 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		pin_val = S3C_GPIO_SFN(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		pin = S3C64XX_GPM(offs - 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		pin_val = S3C_GPIO_SFN(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	s3c_gpio_cfgpin(pin, pin_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static struct irq_chip s3c_irq_eint = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	.name		= "s3c-eint",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	.irq_mask	= s3c_irq_eint_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	.irq_unmask	= s3c_irq_eint_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	.irq_mask_ack	= s3c_irq_eint_maskack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	.irq_ack	= s3c_irq_eint_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	.irq_set_type	= s3c_irq_eint_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	.irq_set_wake	= s3c_irqext_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* s3c_irq_demux_eint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)  * This function demuxes the IRQ from the group0 external interrupts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)  * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)  * the specific handlers s3c_irq_demux_eintX_Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	u32 status = __raw_readl(S3C64XX_EINT0PEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	u32 mask = __raw_readl(S3C64XX_EINT0MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	status &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	status >>= start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	status &= (1 << (end - start + 1)) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		if (status & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		status >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static void s3c_irq_demux_eint0_3(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	s3c_irq_demux_eint(0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void s3c_irq_demux_eint4_11(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	s3c_irq_demux_eint(4, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static void s3c_irq_demux_eint12_19(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	s3c_irq_demux_eint(12, 19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static void s3c_irq_demux_eint20_27(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	s3c_irq_demux_eint(20, 27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static int __init s3c64xx_init_irq_eint(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	/* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	if (of_have_populated_dt() || !soc_is_s3c64xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		irq_clear_status_flags(irq, IRQ_NOREQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) arch_initcall(s3c64xx_init_irq_eint);