code:
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/hardware.h>

	.equ	ioc_base_high, IOC_BASE & 0xff000000
	.equ	ioc_base_low, IOC_BASE & 0x00ff0000

	.text
	.global	rpc_default_fiq_end
ENTRY(rpc_default_fiq_start)
	mov	r12, #ioc_base_high
	.if	ioc_base_low
	orr	r12, r12, #ioc_base_low
	.endif
	strb	r12, [r12, #0x38]	@ Disable FIQ register
	subs	pc, lr, #4
rpc_default_fiq_end:


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  linux/arch/arm/lib/floppydma.S
 *
 *  Copyright (C) 1995, 1996 Russell King
 */
#include <linux/linkage.h>
#include <asm/assembler.h>
		.text

		.global	floppy_fiqin_end
ENTRY(floppy_fiqin_start)
		subs	r9, r9, #1
		ldrbgt	r12, [r11, #-4]
		ldrble	r12, [r11], #0
		strb	r12, [r10], #1
		subs	pc, lr, #4
floppy_fiqin_end:

		.global	floppy_fiqout_end
ENTRY(floppy_fiqout_start)
		subs	r9, r9, #1
		ldrbge	r12, [r10], #1
		movlt	r12, #0
		strble	r12, [r11], #0
		subsle	pc, lr, #4
		strb	r12, [r11, #-4]
		subs	pc, lr, #4
floppy_fiqout_end:

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/acornfb.h
 *
 *  Copyright (C) 1999 Russell King
 *
 *  AcornFB architecture specific code
 */

#define acornfb_bandwidth(var) ((var)->pixclock * 8 / (var)->bits_per_pixel)

static inline int
acornfb_valid_pixrate(struct fb_var_screeninfo *var)
{
	u_long limit;

	if (!var->pixclock)
		return 0;

	/*
	 * Limits below are taken from RISC OS bandwidthlimit file
	 */
	if (current_par.using_vram) {
		if (current_par.vram_half_sam == 2048)
			limit = 6578;
		else
			limit = 13157;
	} else {
		limit = 26315;
	}

	return acornfb_bandwidth(var) >= limit;
}

/*
 * Try to find the best PLL parameters for the pixel clock.
 * This algorithm seems to give best predictable results,
 * and produces the same values as detailed in the VIDC20
 * data sheet.
 */
static inline u_int
acornfb_vidc20_find_pll(u_int pixclk)
{
	u_int r, best_r = 2, best_v = 2;
	int best_d = 0x7fffffff;

	for (r = 2; r <= 32; r++) {
		u_int rr, v, p;
		int d;

		rr = 41667 * r;

		v = (rr + pixclk / 2) / pixclk;

		if (v > 32 || v < 2)
			continue;

		p = (rr + v / 2) / v;

		d = pixclk - p;

		if (d < 0)
			d = -d;

		if (d < best_d) {
			best_d = d;
			best_v = v - 1;
			best_r = r - 1;
		}

		if (d == 0)
			break;
	}

	return best_v << 8 | best_r;
}

static inline void
acornfb_vidc20_find_rates(struct vidc_timing *vidc,
			  struct fb_var_screeninfo *var)
{
	u_int div;

	/* Select pixel-clock divisor to keep PLL in range */
	div = var->pixclock / 9090; /*9921*/

	/* Limit divisor */
	if (div == 0)
		div = 1;
	if (div > 8)
		div = 8;

	/* Encode divisor to VIDC20 setting */
	switch (div) {
	case 1:	vidc->control |= VIDC20_CTRL_PIX_CK;  break;
	case 2:	vidc->control |= VIDC20_CTRL_PIX_CK2; break;
	case 3:	vidc->control |= VIDC20_CTRL_PIX_CK3; break;
	case 4:	vidc->control |= VIDC20_CTRL_PIX_CK4; break;
	case 5:	vidc->control |= VIDC20_CTRL_PIX_CK5; break;
	case 6:	vidc->control |= VIDC20_CTRL_PIX_CK6; break;
	case 7:	vidc->control |= VIDC20_CTRL_PIX_CK7; break;
	case 8: vidc->control |= VIDC20_CTRL_PIX_CK8; break;
	}

	/*
	 * With VRAM, the FIFO can be set to the highest possible setting
	 * because there are no latency considerations for other memory
	 * accesses. However, in 64 bit bus mode the FIFO preload value
	 * must not be set to VIDC20_CTRL_FIFO_28 because this will let
	 * the FIFO overflow. See VIDC20 manual page 33 (6.0 Setting the
	 * FIFO preload value).
	 */
	if (current_par.using_vram) {
		if (current_par.vram_half_sam == 2048)
			vidc->control |= VIDC20_CTRL_FIFO_24;
		else
			vidc->control |= VIDC20_CTRL_FIFO_28;
	} else {
		unsigned long bandwidth = acornfb_bandwidth(var);

		/* Encode bandwidth as VIDC20 setting */
		if (bandwidth > 33334)		/* < 30.0MB/s */
			vidc->control |= VIDC20_CTRL_FIFO_16;
		else if (bandwidth > 26666)	/* < 37.5MB/s */
			vidc->control |= VIDC20_CTRL_FIFO_20;
		else if (bandwidth > 22222)	/* < 45.0MB/s */
			vidc->control |= VIDC20_CTRL_FIFO_24;
		else				/* > 45.0MB/s */
			vidc->control |= VIDC20_CTRL_FIFO_28;
	}

	/* Find the PLL values */
	vidc->pll_ctl = acornfb_vidc20_find_pll(var->pixclock / div);
}

#define acornfb_default_control()	(VIDC20_CTRL_PIX_VCLK)
#define acornfb_default_econtrol()	(VIDC20_ECTL_DAC | VIDC20_ECTL_REG(3))


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/hardware.h
 *
 *  Copyright (C) 1996-1999 Russell King.
 *
 *  This file contains the hardware definitions of the RiscPC series machines.
 */
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H

#include <mach/memory.h>

/*
 * What hardware must be present
 */
#define HAS_IOMD
#define HAS_VIDC20

/* Hardware addresses of major areas.
 *  *_START is the physical address
 *  *_SIZE  is the size of the region
 *  *_BASE  is the virtual address
 */
#define RPC_RAM_SIZE		0x10000000
#define RPC_RAM_START		0x10000000

#define EASI_SIZE		0x08000000	/* EASI I/O */
#define EASI_START		0x08000000
#define EASI_BASE		IOMEM(0xe5000000)

#define IO_START		0x03000000	/* I/O */
#define IO_SIZE			0x01000000
#define IO_BASE			IOMEM(0xe0000000)

#define SCREEN_START		0x02000000	/* VRAM */
#define SCREEN_END		0xdfc00000
#define SCREEN_BASE		0xdf800000

#define UNCACHEABLE_ADDR	(FLUSH_BASE + 0x10000)

/*
 * IO Addresses
 */
#define ECARD_EASI_BASE		(EASI_BASE)
#define VIDC_BASE		(IO_BASE + 0x00400000)
#define EXPMASK_BASE		(IO_BASE + 0x00360000)
#define ECARD_IOC4_BASE		(IO_BASE + 0x00270000)
#define ECARD_IOC_BASE		(IO_BASE + 0x00240000)
#define IOMD_BASE		(IO_BASE + 0x00200000)
#define IOC_BASE		(IO_BASE + 0x00200000)
#define ECARD_MEMC8_BASE	(IO_BASE + 0x0002b000)
#define FLOPPYDMA_BASE		(IO_BASE + 0x0002a000)
#define PCIO_BASE		(IO_BASE + 0x00010000)
#define ECARD_MEMC_BASE		(IO_BASE + 0x00000000)

#define vidc_writel(val)	__raw_writel(val, VIDC_BASE)

#define NETSLOT_BASE		0x0302b000
#define NETSLOT_SIZE		0x00001000

#define PODSLOT_IOC0_BASE	0x03240000
#define PODSLOT_IOC4_BASE	0x03270000
#define PODSLOT_IOC_SIZE	(1 << 14)
#define PODSLOT_MEMC_BASE	0x03000000
#define PODSLOT_MEMC_SIZE	(1 << 14)
#define PODSLOT_EASI_BASE	0x08000000
#define PODSLOT_EASI_SIZE	(1 << 24)

#define	EXPMASK_STATUS		(EXPMASK_BASE + 0x00)
#define EXPMASK_ENABLE		(EXPMASK_BASE + 0x04)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/io.h
 *
 *  Copyright (C) 1997 Russell King
 *
 * Modifications:
 *  06-Dec-1997	RMK	Created.
 */
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H

#include <mach/hardware.h>

#define IO_SPACE_LIMIT 0xffff

/*
 * We need PC style IO addressing for:
 *  - floppy (at 0x3f2,0x3f4,0x3f5,0x3f7)
 *  - parport (at 0x278-0x27a, 0x27b-0x27f, 0x778-0x77a)
 *  - 8250 serial (only for compile)
 *
 * These peripherals are found in an area of MMIO which looks very much
 * like an ISA bus, but with registers at the low byte of each word.
 */
#define __io(a)		(PCIO_BASE + ((a) << 2))

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/irqs.h
 *
 *  Copyright (C) 1996 Russell King
 */

#define IRQ_PRINTER		0
#define IRQ_BATLOW		1
#define IRQ_FLOPPYINDEX		2
#define IRQ_VSYNCPULSE		3
#define IRQ_POWERON		4
#define IRQ_TIMER0		5
#define IRQ_TIMER1		6
#define IRQ_IMMEDIATE		7
#define IRQ_EXPCARDFIQ		8
#define IRQ_HARDDISK		9
#define IRQ_SERIALPORT		10
#define IRQ_FLOPPYDISK		12
#define IRQ_EXPANSIONCARD	13
#define IRQ_KEYBOARDTX		14
#define IRQ_KEYBOARDRX		15

#define IRQ_DMA0		16
#define IRQ_DMA1		17
#define IRQ_DMA2		18
#define IRQ_DMA3		19
#define IRQ_DMAS0		20
#define IRQ_DMAS1		21

#define FIQ_FLOPPYDATA		0
#define FIQ_ECONET		2
#define FIQ_SERIALPORT		4
#define FIQ_EXPANSIONCARD	6
#define FIQ_FORCE		7

/*
 * This is the offset of the FIQ "IRQ" numbers
 */
#define FIQ_START		64

#define NR_IRQS			128


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/isa-dma.h
 *
 *  Copyright (C) 1997 Russell King
 */
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H

#define MAX_DMA_CHANNELS	8

#define DMA_0			0
#define DMA_1			1
#define DMA_2			2
#define DMA_3			3
#define DMA_S0			4
#define DMA_S1			5
#define DMA_VIRTUAL_FLOPPY	6
#define DMA_VIRTUAL_SOUND	7

#define DMA_FLOPPY		DMA_VIRTUAL_FLOPPY

#define IOMD_DMA_BOUNDARY	(PAGE_SIZE - 1)

#endif /* _ASM_ARCH_DMA_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/memory.h
 *
 *  Copyright (C) 1996,1997,1998 Russell King.
 *
 *  Changelog:
 *   20-Oct-1996 RMK	Created
 *   31-Dec-1997 RMK	Fixed definitions to reduce warnings
 *   11-Jan-1998 RMK	Uninlined to reduce hits on cache
 *   08-Feb-1998 RMK	Added __virt_to_bus and __bus_to_virt
 *   21-Mar-1999 RMK	Renamed to memory.h
 *		 RMK	Added TASK_SIZE and PAGE_OFFSET
 */
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H

/*
 * Cache flushing area - ROM
 */
#define FLUSH_BASE_PHYS		0x00000000
#define FLUSH_BASE		0xdf000000

/*
 * Sparsemem support.  Each section is a maximum of 64MB.  The sections
 * are offset by 128MB and can cover 128MB, so that gives us a maximum
 * of 29 physmem bits.
 */
#define MAX_PHYSMEM_BITS	29
#define SECTION_SIZE_BITS	26

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/mach-rpc/include/mach/uncompress.h
 *
 *  Copyright (C) 1996 Russell King
 */
#define VIDMEM ((char *)SCREEN_START)

#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/setup.h>
#include <asm/page.h>

int video_size_row;
unsigned char bytes_per_char_h;
extern unsigned long con_charconvtable[256];

struct param_struct {
	unsigned long page_size;
	unsigned long nr_pages;
	unsigned long ramdisk_size;
	unsigned long mountrootrdonly;
	unsigned long rootdev;
	unsigned long video_num_cols;
	unsigned long video_num_rows;
	unsigned long video_x;
	unsigned long video_y;
	unsigned long memc_control_reg;
	unsigned char sounddefault;
	unsigned char adfsdrives;
	unsigned char bytes_per_char_h;
	unsigned char bytes_per_char_v;
	unsigned long unused[256/4-11];
};

static const unsigned long palette_4[16] = {
	0x00000000,
	0x000000cc,
	0x0000cc00,             /* Green   */
	0x0000cccc,             /* Yellow  */
	0x00cc0000,             /* Blue    */
	0x00cc00cc,             /* Magenta */
	0x00cccc00,             /* Cyan    */
	0x00cccccc,             /* White   */
	0x00000000,
	0x000000ff,
	0x0000ff00,
	0x0000ffff,
	0x00ff0000,
	0x00ff00ff,
	0x00ffff00,
	0x00ffffff
};

#define palette_setpixel(p)	*(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255)
#define palette_write(v)	*(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff)

/*
 * params_phys is a linker defined symbol - see
 * arch/arm/boot/compressed/Makefile
 */
extern __attribute__((pure)) struct param_struct *params(void);
#define params (params())

#ifndef STANDALONE_DEBUG
unsigned long video_num_cols;
unsigned long video_num_rows;
unsigned long video_x;
unsigned long video_y;
unsigned char bytes_per_char_v;
int white;

/*
 * This does not append a newline
 */
static inline void putc(int c)
{
	extern void ll_write_char(char *, char c, char white);
	int x,y;
	char *ptr;

	x = video_x;
	y = video_y;

	if (c == '\n') {
		if (++y >= video_num_rows)
			y--;
	} else if (c == '\r') {
		x = 0;
	} else {
		ptr = VIDMEM + ((y*video_num_cols*bytes_per_char_v+x)*bytes_per_char_h);
		ll_write_char(ptr, c, white);
		if (++x >= video_num_cols) {
			x = 0;
			if ( ++y >= video_num_rows ) {
				y--;
			}
		}
	}

	video_x = x;
	video_y = y;
}

static inline void flush(void)
{
}

/*
 * Setup for decompression
 */
static void arch_decomp_setup(void)
{
	int i;
	struct tag *t = (struct tag *)params;
	unsigned int nr_pages = 0, page_size = PAGE_SIZE;

	if (t->hdr.tag == ATAG_CORE) {
		for (; t->hdr.size; t = tag_next(t)) {
			if (t->hdr.tag == ATAG_VIDEOTEXT) {
				video_num_rows = t->u.videotext.video_lines;
				video_num_cols = t->u.videotext.video_cols;
				video_x = t->u.videotext.x;
				video_y = t->u.videotext.y;
			} else if (t->hdr.tag == ATAG_VIDEOLFB) {
				bytes_per_char_h = t->u.videolfb.lfb_depth;
				bytes_per_char_v = 8;
			} else if (t->hdr.tag == ATAG_MEM) {
				page_size = PAGE_SIZE;
				nr_pages += (t->u.mem.size / PAGE_SIZE);
			}
		}
	} else {
		nr_pages = params->nr_pages;
		page_size = params->page_size;
		video_num_rows = params->video_num_rows;
		video_num_cols = params->video_num_cols;
		video_x = params->video_x;
		video_y = params->video_y;
		bytes_per_char_h = params->bytes_per_char_h;
		bytes_per_char_v = params->bytes_per_char_v;
	}

	video_size_row = video_num_cols * bytes_per_char_h;

	if (bytes_per_char_h == 4)
		for (i = 0; i < 256; i++)
			con_charconvtable[i] =
				(i & 128 ? 1 << 0  : 0) |
				(i & 64  ? 1 << 4  : 0) |
				(i & 32  ? 1 << 8  : 0) |
				(i & 16  ? 1 << 12 : 0) |
				(i & 8   ? 1 << 16 : 0) |
				(i & 4   ? 1 << 20 : 0) |
				(i & 2   ? 1 << 24 : 0) |
				(i & 1   ? 1 << 28 : 0);
	else
		for (i = 0; i < 16; i++)
			con_charconvtable[i] =
				(i & 8   ? 1 << 0  : 0) |
				(i & 4   ? 1 << 8  : 0) |
				(i & 2   ? 1 << 16 : 0) |
				(i & 1   ? 1 << 24 : 0);

	palette_setpixel(0);
	if (bytes_per_char_h == 1) {
		palette_write (0);
		palette_write (0x00ffffff);
		for (i = 2; i < 256; i++)
			palette_write (0);
		white = 1;
	} else {
		for (i = 0; i < 256; i++)
			palette_write (i < 16 ? palette_4[i] : 0);
		white = 7;
	}

	if (nr_pages * page_size < 4096*1024) error("<4M of mem\n");
}
#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  linux/arch/arm/lib/io-acorn.S
 *
 *  Copyright (C) 1995, 1996 Russell King
 *
 * 27/03/03 Ian Molton Clean up CONFIG_CPU
 */
#include <linux/linkage.h>
#include <linux/kern_levels.h>
#include <asm/assembler.h>

		.text
		.align

.Liosl_warning:
		.ascii	KERN_WARNING "insl/outsl not implemented, called from %08lX\0"
		.align

/*
 * These make no sense on Acorn machines.
 * Print a warning message.
 */
ENTRY(insl)
ENTRY(outsl)
		adr	r0, .Liosl_warning
		mov	r1, lr
		b	_printk


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-rpc/riscpc.c
 *
 *  Copyright (C) 1998-2001 Russell King
 *
 *  Architecture specific fixups.
 */
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/serial_8250.h>
#include <linux/ata_platform.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/reboot.h>

#include <asm/elf.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/hardware/iomd.h>
#include <asm/page.h>
#include <asm/domain.h>
#include <asm/setup.h>
#include <asm/system_misc.h>

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

extern void rpc_init_irq(void);

unsigned int vram_size;
unsigned int memc_ctrl_reg;
unsigned int number_mfm_drives;

static int __init parse_tag_acorn(const struct tag *tag)
{
	memc_ctrl_reg = tag->u.acorn.memc_control_reg;
	number_mfm_drives = tag->u.acorn.adfsdrives;

	switch (tag->u.acorn.vram_pages) {
	case 512:
		vram_size += PAGE_SIZE * 256;
		fallthrough;	/* ??? */
	case 256:
		vram_size += PAGE_SIZE * 256;
		break;
	default:
		break;
	}
#if 0
	if (vram_size) {
		desc->video_start = 0x02000000;
		desc->video_end   = 0x02000000 + vram_size;
	}
#endif
	return 0;
}

__tagtable(ATAG_ACORN, parse_tag_acorn);

static struct map_desc rpc_io_desc[] __initdata = {
 	{	/* VRAM		*/
		.virtual	=  SCREEN_BASE,
		.pfn		= __phys_to_pfn(SCREEN_START),
		.length		= 	2*1048576,
		.type		= MT_DEVICE
	}, {	/* IO space	*/
		.virtual	=  (u32)IO_BASE,
		.pfn		= __phys_to_pfn(IO_START),
		.length		= 	IO_SIZE	 ,
		.type		= MT_DEVICE
	}, {	/* EASI space	*/
		.virtual	= (unsigned long)EASI_BASE,
		.pfn		= __phys_to_pfn(EASI_START),
		.length		= EASI_SIZE,
		.type		= MT_DEVICE
	}
};

static void __init rpc_map_io(void)
{
	iotable_init(rpc_io_desc, ARRAY_SIZE(rpc_io_desc));

	/*
	 * Turn off floppy.
	 */
	writeb(0xc, PCIO_BASE + (0x3f2 << 2));

	/*
	 * RiscPC can't handle half-word loads and stores
	 */
	elf_hwcap &= ~HWCAP_HALF;
}

static struct resource acornfb_resources[] = {
	/* VIDC */
	DEFINE_RES_MEM(0x03400000, 0x00200000),
	DEFINE_RES_IRQ(IRQ_VSYNCPULSE),
};

static struct platform_device acornfb_device = {
	.name			= "acornfb",
	.id			= -1,
	.dev			= {
		.coherent_dma_mask = 0xffffffff,
	},
	.num_resources		= ARRAY_SIZE(acornfb_resources),
	.resource		= acornfb_resources,
};

static struct resource iomd_resources[] = {
	DEFINE_RES_MEM(0x03200000, 0x10000),
};

static struct platform_device iomd_device = {
	.name			= "iomd",
	.id			= -1,
	.num_resources		= ARRAY_SIZE(iomd_resources),
	.resource		= iomd_resources,
};

static struct resource iomd_kart_resources[] = {
	DEFINE_RES_IRQ(IRQ_KEYBOARDRX),
	DEFINE_RES_IRQ(IRQ_KEYBOARDTX),
};

static struct platform_device kbd_device = {
	.name			= "kart",
	.id			= -1,
	.dev			= {
		.parent 	= &iomd_device.dev,
	},
	.num_resources		= ARRAY_SIZE(iomd_kart_resources),
	.resource		= iomd_kart_resources,
};

static struct plat_serial8250_port serial_platform_data[] = {
	{
		.mapbase	= 0x03010fe0,
		.irq		= IRQ_SERIALPORT,
		.uartclk	= 1843200,
		.regshift	= 2,
		.iotype		= UPIO_MEM,
		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST,
	},
	{ },
};

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

static struct pata_platform_info pata_platform_data = {
	.ioport_shift		= 2,
};

static struct resource pata_resources[] = {
	DEFINE_RES_MEM(0x030107c0, 0x20),
	DEFINE_RES_MEM(0x03010fd8, 0x04),
	DEFINE_RES_IRQ(IRQ_HARDDISK),
};

static struct platform_device pata_device = {
	.name			= "pata_platform",
	.id			= -1,
	.num_resources		= ARRAY_SIZE(pata_resources),
	.resource		= pata_resources,
	.dev			= {
		.platform_data	= &pata_platform_data,
		.coherent_dma_mask = ~0,	/* grumble */
	},
};

static struct platform_device *devs[] __initdata = {
	&iomd_device,
	&kbd_device,
	&serial_device,
	&acornfb_device,
	&pata_device,
};

static struct i2c_board_info i2c_rtc = {
	I2C_BOARD_INFO("pcf8583", 0x50)
};

static int __init rpc_init(void)
{
	i2c_register_board_info(0, &i2c_rtc, 1);
	return platform_add_devices(devs, ARRAY_SIZE(devs));
}

arch_initcall(rpc_init);

static void rpc_restart(enum reboot_mode mode, const char *cmd)
{
	iomd_writeb(0, IOMD_ROMCR0);

	/*
	 * Jump into the ROM
	 */
	soft_restart(0);
}

void ioc_timer_init(void);

MACHINE_START(RISCPC, "Acorn-RiscPC")
	/* Maintainer: Russell King */
	.atag_offset	= 0x100,
	.reserve_lp0	= 1,
	.reserve_lp1	= 1,
	.map_io		= rpc_map_io,
	.init_irq	= rpc_init_irq,
	.init_time	= ioc_timer_init,
	.restart	= rpc_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/common/time-acorn.c
 *
 *  Copyright (c) 1996-2000 Russell King.
 *
 *  Changelog:
 *   24-Sep-1996	RMK	Created
 *   10-Oct-1996	RMK	Brought up to date with arch-sa110eval
 *   04-Dec-1997	RMK	Updated for new arch/arm/time.c
 *   13=Jun-2004	DS	Moved to arch/arm/common b/c shared w/CLPS7500
 */
#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>

#include <mach/hardware.h>
#include <asm/hardware/ioc.h>

#include <asm/mach/time.h>

#define RPC_CLOCK_FREQ 2000000
#define RPC_LATCH DIV_ROUND_CLOSEST(RPC_CLOCK_FREQ, HZ)

static u32 ioc_time;

static u64 ioc_timer_read(struct clocksource *cs)
{
	unsigned int count1, count2, status;
	unsigned long flags;
	u32 ticks;

	local_irq_save(flags);
	ioc_writeb (0, IOC_T0LATCH);
	barrier ();
	count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
	barrier ();
	status = ioc_readb(IOC_IRQREQA);
	barrier ();
	ioc_writeb (0, IOC_T0LATCH);
	barrier ();
	count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
	ticks = ioc_time + RPC_LATCH - count2;
	local_irq_restore(flags);

	if (count2 < count1) {
		/*
		 * The timer has not reloaded between reading count1 and
		 * count2, check whether an interrupt was actually pending.
		 */
		if (status & (1 << 5))
			ticks += RPC_LATCH;
	} else if (count2 > count1) {
		/*
		 * The timer has reloaded, so count2 indicates the new
		 * count since the wrap.  The interrupt would not have
		 * been processed, so add the missed ticks.
		 */
		ticks += RPC_LATCH;
	}

	return ticks;
}

static struct clocksource ioctime_clocksource = {
	.read = ioc_timer_read,
	.mask = CLOCKSOURCE_MASK(32),
	.rating = 100,
};

void __init ioctime_init(void)
{
	ioc_writeb(RPC_LATCH & 255, IOC_T0LTCHL);
	ioc_writeb(RPC_LATCH >> 8, IOC_T0LTCHH);
	ioc_writeb(0, IOC_T0GO);
}

static irqreturn_t
ioc_timer_interrupt(int irq, void *dev_id)
{
	ioc_time += RPC_LATCH;
	legacy_timer_tick(1);
	return IRQ_HANDLED;
}

/*
 * Set up timer interrupt.
 */
void __init ioc_timer_init(void)
{
	WARN_ON(clocksource_register_hz(&ioctime_clocksource, RPC_CLOCK_FREQ));
	ioctime_init();
	if (request_irq(IRQ_TIMER0, ioc_timer_interrupt, 0, "timer", NULL))
		pr_err("Failed to request irq %d (timer)\n", IRQ_TIMER0);
}


code:
# SPDX-License-Identifier: GPL-2.0
#
# Copyright 2009 Simtec Electronics

source "arch/arm/mach-s3c/Kconfig.s3c24xx"
source "arch/arm/mach-s3c/Kconfig.s3c64xx"

config PLAT_SAMSUNG
	bool
	depends on PLAT_S3C24XX || ARCH_S3C64XX
	default y
	select GENERIC_IRQ_CHIP
	select NO_IOPORT_MAP
	select SOC_SAMSUNG
	help
	  Base platform code for all Samsung SoC based systems

config SAMSUNG_PM
	bool
	depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX)
	default y
	help
	  Base platform power management code for samsung code

if PLAT_SAMSUNG
menu "Samsung Common options"

# boot configurations

comment "Boot options"

config S3C_LOWLEVEL_UART_PORT
	int "S3C UART to use for low-level messages"
	depends on ARCH_S3C64XX
	default 0
	help
	  Choice of which UART port to use for the low-level messages,
	  such as the `Uncompressing...` at start time. The value of
	  this configuration should be between zero and two. The port
	  must have been initialised by the boot-loader before use.

config SAMSUNG_ATAGS
	def_bool n
	depends on ATAGS
	help
	  This option enables ATAGS based boot support code for
	  Samsung platforms, including static platform devices, legacy
	  clock, timer and interrupt initialization, etc.

	  Platforms that support only DT based boot need not to select
	  this option.

if SAMSUNG_ATAGS

config S3C_GPIO_SPACE
	int "Space between gpio banks"
	default 0
	help
	  Add a number of spare GPIO entries between each bank for debugging
	  purposes. This allows any problems where an counter overflows from
	  one bank to another to be caught, at the expense of using a little
	  more memory.

config S3C_GPIO_TRACK
	bool
	help
	  Internal configuration option to enable the s3c specific gpio
	  chip tracking if the platform requires it.

# ADC driver

config S3C_ADC
	bool "ADC common driver support"
	depends on !ARCH_MULTIPLATFORM
	help
	  Core support for the ADC block found in the Samsung SoC systems
	  for drivers such as the touchscreen and hwmon to use to share
	  this resource.

# device definitions to compile in

config S3C_DEV_HSMMC
	bool
	help
	  Compile in platform device definitions for HSMMC code

config S3C_DEV_HSMMC1
	bool
	help
	  Compile in platform device definitions for HSMMC channel 1

config S3C_DEV_HSMMC2
	bool
	help
	  Compile in platform device definitions for HSMMC channel 2

config S3C_DEV_HSMMC3
	bool
	help
	  Compile in platform device definitions for HSMMC channel 3

config S3C_DEV_HWMON
	bool
	help
	  Compile in platform device definitions for HWMON

config S3C_DEV_I2C1
	bool
	help
	  Compile in platform device definitions for I2C channel 1

config S3C_DEV_I2C2
	bool
	help
	  Compile in platform device definitions for I2C channel 2

config S3C_DEV_I2C3
	bool
	help
	  Compile in platform device definition for I2C controller 3

config S3C_DEV_I2C4
	bool
	help
	  Compile in platform device definition for I2C controller 4

config S3C_DEV_I2C5
	bool
	help
	  Compile in platform device definition for I2C controller 5

config S3C_DEV_I2C6
	bool
	help
	  Compile in platform device definition for I2C controller 6

config S3C_DEV_I2C7
	bool
	help
	  Compile in platform device definition for I2C controller 7

config S3C_DEV_FB
	bool
	help
	  Compile in platform device definition for framebuffer

config S3C_DEV_USB_HOST
	bool
	help
	  Compile in platform device definition for USB host.

config S3C_DEV_USB_HSOTG
	bool
	help
	  Compile in platform device definition for USB high-speed OtG

config S3C_DEV_WDT
	bool
	default y if ARCH_S3C24XX
	help
	  Compile in platform device definition for Watchdog Timer

config S3C_DEV_NAND
	bool
	help
	  Compile in platform device definition for NAND controller

config S3C_DEV_ONENAND
	bool
	help
	  Compile in platform device definition for OneNAND controller

config S3C_DEV_RTC
	bool
	help
	  Compile in platform device definition for RTC

config SAMSUNG_DEV_ADC
	bool
	help
	  Compile in platform device definition for ADC controller

config SAMSUNG_DEV_IDE
	bool
	help
	  Compile in platform device definitions for IDE

config S3C64XX_DEV_SPI0
	bool
	help
	  Compile in platform device definitions for S3C64XX's type
	  SPI controller 0

config SAMSUNG_DEV_TS
	bool
	help
	  Common in platform device definitions for touchscreen device

config SAMSUNG_DEV_KEYPAD
	bool
	help
	  Compile in platform device definitions for keypad

config SAMSUNG_DEV_PWM
	bool
	default y if ARCH_S3C24XX
	help
	  Compile in platform device definition for PWM Timer

config GPIO_SAMSUNG
	def_bool y

config SAMSUNG_PM_GPIO
	bool
	default y if GPIO_SAMSUNG && PM
	help
	  Include legacy GPIO power management code for platforms not using
	  pinctrl-samsung driver.
endif

config SAMSUNG_WAKEMASK
	bool
	depends on PM
	help
	  Compile support for wakeup-mask controls found on the S3C6400
	  and above. This code allows a set of interrupt to wakeup-mask
	  mappings. See <plat/wakeup-mask.h>

endmenu
endif


code:
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2012 Samsung Electronics Co., Ltd.
#		http://www.samsung.com/
#
# Copyright 2007 Simtec Electronics
menuconfig ARCH_S3C24XX
	bool "Samsung S3C24XX SoCs (deprecated, see help)"
	depends on ARCH_MULTI_V4T || ARCH_MULTI_V5
	depends on CPU_LITTLE_ENDIAN
	depends on ATAGS && UNUSED_BOARD_FILES
	select CLKSRC_SAMSUNG_PWM
	select GPIO_SAMSUNG
	select GPIOLIB
	select S3C2410_WATCHDOG
	select SAMSUNG_ATAGS
	select WATCHDOG
	help
	  Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443
	  and S3C2450 SoCs based systems, such as the Simtec Electronics BAST
	  (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
	  Samsung SMDK2410 development board (and derivatives).

	  The platform is deprecated and scheduled for removal. Please reach to
	  the maintainers of the platform and linux-samsung-soc@vger.kernel.org if
	  you still use it.
	  Without such feedback, the platform will be removed after 2022.

if ARCH_S3C24XX

config PLAT_S3C24XX
	def_bool y
	select GPIOLIB
	select NO_IOPORT_MAP
	select S3C_DEV_NAND
	select COMMON_CLK
	help
	  Base platform code for any Samsung S3C24XX device

menu "Samsung S3C24XX SoCs Support"

comment "S3C24XX SoCs"

config CPU_S3C2410
	bool "Samsung S3C2410"
	depends on ARCH_MULTI_V4T
	default y
	select CPU_ARM920T
	select S3C2410_COMMON_CLK
	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
	select S3C2410_PM if PM
	help
	  Support for S3C2410 and S3C2410A family from the S3C24XX line
	  of Samsung Mobile CPUs.

config CPU_S3C2412
	bool "Samsung S3C2412"
	depends on ARCH_MULTI_V5
	select CPU_ARM926T
	select S3C2412_COMMON_CLK
	select S3C2412_PM if PM_SLEEP
	help
	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line

config CPU_S3C2416
	bool "Samsung S3C2416/S3C2450"
	depends on ARCH_MULTI_V5
	select CPU_ARM926T
	select S3C2416_PM if PM_SLEEP
	select S3C2443_COMMON_CLK
	help
	  Support for the S3C2416 SoC from the S3C24XX line

config CPU_S3C2440
	bool "Samsung S3C2440"
	depends on ARCH_MULTI_V4T
	select CPU_ARM920T
	select S3C2410_COMMON_CLK
	select S3C2410_PM if PM_SLEEP
	help
	  Support for S3C2440 Samsung Mobile CPU based systems.

config CPU_S3C2442
	bool "Samsung S3C2442"
	depends on ARCH_MULTI_V4T
	select CPU_ARM920T
	select S3C2410_COMMON_CLK
	select S3C2410_PM if PM_SLEEP
	help
	  Support for S3C2442 Samsung Mobile CPU based systems.

config CPU_S3C244X
	def_bool y
	depends on CPU_S3C2440 || CPU_S3C2442

config CPU_S3C2443
	bool "Samsung S3C2443"
	depends on ARCH_MULTI_V4T
	select CPU_ARM920T
	select S3C2443_COMMON_CLK
	help
	  Support for the S3C2443 SoC from the S3C24XX line

# common code

config S3C24XX_SMDK
	bool
	help
	  Common machine code for SMDK2410 and SMDK2440

config S3C24XX_SIMTEC_AUDIO
	bool
	depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS)
	default y
	help
	  Add audio devices for common Simtec S3C24XX boards

config S3C24XX_SIMTEC_PM
	bool
	help
	  Common power management code for systems that are
	  compatible with the Simtec style of power management

config S3C24XX_SIMTEC_USB
	bool
	help
	  USB management code for common Simtec S3C24XX boards

config S3C24XX_SETUP_TS
	bool
	help
	  Compile in platform device definition for Samsung TouchScreen.

config S3C2410_PM
	bool
	help
	  Power Management code common to S3C2410 and better

config S3C24XX_PLL
	bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
	depends on ARM_S3C24XX_CPUFREQ
	help
	  Compile in support for changing the PLL frequency from the
	  S3C24XX series CPUfreq driver. The PLL takes time to settle
	  after a frequency change, so by default it is not enabled.

	  This also means that the PLL tables for the selected CPU(s) will
	  be built which may increase the size of the kernel image.

# cpu frequency items common between s3c2410 and s3c2440/s3c2442

config S3C2410_IOTIMING
	bool
	depends on ARM_S3C24XX_CPUFREQ
	help
	  Internal node to select io timing code that is common to the s3c2410
	  and s3c2440/s3c2442 cpu frequency support.

# cpu frequency support common to s3c2412, s3c2413 and s3c2442

config S3C2412_IOTIMING
	bool
	depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2412 || CPU_S3C2443)
	help
	  Intel node to select io timing code that is common to the s3c2412
	  and the s3c2443.

# cpu-specific sections

if CPU_S3C2410

config S3C2410_PLL
	bool
	depends on ARM_S3C2410_CPUFREQ && S3C24XX_PLL
	default y
	help
	  Select the PLL table for the S3C2410

config S3C24XX_SIMTEC_NOR
	bool
	help
	  Internal node to specify machine has simtec NOR mapping

config MACH_BAST_IDE
	bool
	select HAVE_PATA_PLATFORM
	help
	  Internal node for machines with an BAST style IDE
	  interface

comment "S3C2410 Boards"

#
# The "S3C2410 Boards" list is ordered alphabetically by option text.
# (without ARCH_ or MACH_)
#

config MACH_AML_M5900
	bool "AML M5900 Series"
	select S3C24XX_SIMTEC_PM if PM
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the American Microsystems M5900 Series
	  <http://www.amltd.com>

config ARCH_BAST
	bool "Simtec Electronics BAST (EB2410ITX)"
	select MACH_BAST_IDE
	select S3C2410_COMMON_DCLK
	select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
	select S3C24XX_SIMTEC_NOR
	select S3C24XX_SIMTEC_PM if PM
	select S3C24XX_SIMTEC_USB
	select S3C_DEV_HWMON
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Simtec Electronics EB2410ITX
	  development board (also known as BAST)

config BAST_PC104_IRQ
	bool "BAST PC104 IRQ support"
	depends on ARCH_BAST
	default y
	help
	  Say Y	here to enable the PC104 IRQ routing on the
	  Simtec BAST (EB2410ITX)

config ARCH_H1940
	bool "IPAQ H1940"
	select PM_H1940 if PM
	select S3C24XX_SETUP_TS
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the HP IPAQ H1940

config H1940BT
	tristate "Control the state of H1940 bluetooth chip"
	depends on ARCH_H1940
	depends on RFKILL
	help
	  This is a simple driver that is able to control
	  the state of built in bluetooth chip on h1940.

config MACH_N30
	bool "Acer N30 family"
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you want suppt for the Acer N30, Acer N35,
	  Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.

config MACH_OTOM
	bool "NexVision OTOM Board"
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Nex Vision OTOM board

config MACH_QT2410
	bool "QT2410"
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Armzone QT2410

config ARCH_SMDK2410
	bool "SMDK2410/A9M2410"
	select S3C24XX_SMDK
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the SMDK2410 or the derived module A9M2410
	  <http://www.fsforth.de>

config MACH_TCT_HAMMER
	bool "TCT Hammer Board"
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the TinCanTools Hammer Board
	  <https://www.tincantools.com>

config MACH_VR1000
	bool "Thorcom VR1000"
	select MACH_BAST_IDE
	select S3C2410_COMMON_DCLK
	select S3C24XX_SIMTEC_NOR
	select S3C24XX_SIMTEC_PM if PM
	select S3C24XX_SIMTEC_USB
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Thorcom VR1000 board.

endif # CPU_S3C2410

config S3C2412_PM_SLEEP
	bool
	help
	  Internal config node to apply sleep for S3C2412 power management.
	  Can be selected by another SoCs such as S3C2416 with similar
	  sleep procedure.

if CPU_S3C2412

config CPU_S3C2412_ONLY
	bool
	depends on !CPU_S3C2410 && !CPU_S3C2416 && !CPU_S3C2440 && \
		   !CPU_S3C2442 && !CPU_S3C2443
	default y

config S3C2412_PM
	bool
	select S3C2412_PM_SLEEP
	select SAMSUNG_WAKEMASK
	help
	  Internal config node to apply S3C2412 power management

comment "S3C2412 Boards"

#
# The "S3C2412 Boards" list is ordered alphabetically by option text.
# (without ARCH_ or MACH_)
#

config MACH_JIVE
	bool "Logitech Jive"
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Logitech Jive.

config MACH_JIVE_SHOW_BOOTLOADER
	bool "Allow access to bootloader partitions in MTD"
	depends on MACH_JIVE

config MACH_S3C2413
	bool
	help
	  Internal node for S3C2413 version of SMDK2413, so that
	  machine_is_s3c2413() will work when MACH_SMDK2413 is
	  selected

config MACH_SMDK2412
	bool "SMDK2412"
	select MACH_SMDK2413
	help
	  Say Y here if you are using an SMDK2412

	  Note, this shares support with SMDK2413, so will automatically
	  select MACH_SMDK2413.

config MACH_SMDK2413
	bool "SMDK2413"
	select MACH_S3C2413
	select S3C24XX_SMDK
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using an SMDK2413

config MACH_VSTMS
	bool "VMSTMS"
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using an VSTMS board

endif # CPU_S3C2412

if CPU_S3C2416

config S3C2416_PM
	bool
	select S3C2412_PM_SLEEP
	select SAMSUNG_WAKEMASK
	help
	  Internal config node to apply S3C2416 power management

config S3C2416_SETUP_SDHCI
	bool
	select S3C2416_SETUP_SDHCI_GPIO
	help
	  Internal helper functions for S3C2416 based SDHCI systems

config S3C2416_SETUP_SDHCI_GPIO
	bool
	help
	  Common setup code for SDHCI gpio.

comment "S3C2416 Boards"

config MACH_SMDK2416
	bool "SMDK2416"
	select S3C2416_SETUP_SDHCI
	select S3C24XX_SMDK
	select S3C_DEV_FB
	select S3C_DEV_HSMMC
	select S3C_DEV_HSMMC1
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using an SMDK2416

config MACH_S3C2416_DT
	bool "Samsung S3C2416 machine using devicetree"
	select TIMER_OF
	select USE_OF
	select PINCTRL
	select PINCTRL_S3C24XX
	help
	  Machine support for Samsung S3C2416 machines with device tree enabled.
	  Select this if a fdt blob is available for the S3C2416 SoC based board.
	  Note: This is under development and not all peripherals can be supported
	  with this machine file.

endif # CPU_S3C2416

if CPU_S3C2440 || CPU_S3C2442

config S3C2440_XTAL_12000000
	bool
	help
	  Indicate that the build needs to support 12MHz system
	  crystal.

config S3C2440_XTAL_16934400
	bool
	help
	  Indicate that the build needs to support 16.9344MHz system
	  crystal.

config S3C2440_PLL_12000000
	bool
	depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_12000000
	default y if S3C24XX_PLL
	help
	  PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.

config S3C2440_PLL_16934400
	bool
	depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_16934400
	default y if S3C24XX_PLL
	help
	  PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
endif # CPU_S3C2440 || CPU_S3C2442

if CPU_S3C2440

comment "S3C2440 Boards"

#
# The "S3C2440 Boards" list is ordered alphabetically by option text.
# (without ARCH_ or MACH_)
#

config MACH_ANUBIS
	bool "Simtec Electronics ANUBIS"
	select HAVE_PATA_PLATFORM
	select S3C2410_COMMON_DCLK
	select S3C2440_XTAL_12000000
	select S3C24XX_SIMTEC_PM if PM
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Simtec Electronics ANUBIS
	  development system

config MACH_AT2440EVB
	bool "Avantech AT2440EVB development board"
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the AT2440EVB development board

config MACH_MINI2440
	bool "MINI2440 development board"
	select LEDS_CLASS
	select LEDS_TRIGGERS
	select LEDS_TRIGGER_BACKLIGHT
	select NEW_LEDS
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
	  available via various sources. It can come with a 3.5" or 7" touch LCD.

config MACH_NEXCODER_2440
	bool "NexVision NEXCODER 2440 Light Board"
	select S3C2440_XTAL_12000000
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board

config MACH_OSIRIS
	bool "Simtec IM2440D20 (OSIRIS) module"
	select S3C2410_COMMON_DCLK
	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
	select S3C2440_XTAL_12000000
	select S3C24XX_SIMTEC_PM if PM
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Simtec IM2440D20 module, also
	  known as the Osiris.

config MACH_OSIRIS_DVS
	tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver"
	depends on MACH_OSIRIS
	depends on TPS65010
	help
	  Say Y/M here if you want to have dynamic voltage scaling support
	  on the Simtec IM2440D20 (OSIRIS) module via the TPS65011.

	  The DVS driver alters the voltage supplied to the ARM core
	  depending on the frequency it is running at. The driver itself
	  does not do any of the frequency alteration, which is left up
	  to the cpufreq driver.

config MACH_RX3715
	bool "HP iPAQ rx3715"
	select PM_H1940 if PM
	select S3C2440_XTAL_16934400
	select S3C_DEV_NAND
	help
	  Say Y here if you are using the HP iPAQ rx3715.

config ARCH_S3C2440
	bool "SMDK2440"
	select S3C2440_XTAL_16934400
	select S3C24XX_SMDK
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the SMDK2440.

config SMDK2440_CPU2440
	bool "SMDK2440 with S3C2440 CPU module"
	default y if ARCH_S3C2440
	select S3C2440_XTAL_16934400

endif # CPU_S3C2440

if CPU_S3C2442

comment "S3C2442 Boards"

#
# The "S3C2442 Boards" list is ordered alphabetically by option text.
# (without ARCH_ or MACH_)
#

config MACH_NEO1973_GTA02
	bool "Openmoko GTA02 / Freerunner phone"
	select I2C
	select MFD_PCF50633
	select PCF50633_GPIO
	select POWER_SUPPLY
	select S3C_DEV_USB_HOST
	help
	  Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone

config MACH_RX1950
	bool "HP iPAQ rx1950"
	select I2C
	select PM_H1940 if PM
	select S3C2410_COMMON_DCLK
	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
	select S3C2440_XTAL_16934400
	select S3C_DEV_NAND
	help
	  Say Y here if you're using HP iPAQ rx1950

endif # CPU_S3C2442

if CPU_S3C2443 || CPU_S3C2416

config S3C2443_SETUP_SPI
	bool
	help
	  Common setup code for SPI GPIO configurations

endif # CPU_S3C2443 || CPU_S3C2416

if CPU_S3C2443

comment "S3C2443 Boards"

config MACH_SMDK2443
	bool "SMDK2443"
	select S3C24XX_SMDK
	select S3C_DEV_HSMMC1
	help
	  Say Y here if you are using an SMDK2443

endif # CPU_S3C2443

config PM_H1940
	bool
	help
	  Internal node for H1940 and related PM

endmenu # "Samsung S3C24XX SoCs Support"

endif # ARCH_S3C24XX


code:
# SPDX-License-Identifier: GPL-2.0
#
# Copyright 2008 Openmoko, Inc.
#	Simtec Electronics, Ben Dooks <ben@simtec.co.uk>

menuconfig ARCH_S3C64XX
	bool "Samsung S3C64XX (deprecated, see help)"
	depends on ARCH_MULTI_V6
	select ARM_AMBA
	select ARM_VIC
	select CLKSRC_SAMSUNG_PWM
	select COMMON_CLK_SAMSUNG
	select GPIO_SAMSUNG if ATAGS
	select GPIOLIB
	select HAVE_TCM
	select PLAT_SAMSUNG
	select PM_GENERIC_DOMAINS if PM
	select S3C_DEV_NAND if ATAGS
	select S3C_GPIO_TRACK if ATAGS
	select S3C2410_WATCHDOG
	select SAMSUNG_ATAGS if ATAGS
	select SAMSUNG_WAKEMASK if PM
	select WATCHDOG
	help
	  Samsung S3C64XX series based systems

	  The platform is deprecated and scheduled for removal. Please reach to
	  the maintainers of the platform and linux-samsung-soc@vger.kernel.org if
	  you still use it.
	  Without such feedback, the platform will be removed after 2024.

if ARCH_S3C64XX

# Configuration options for the S3C6410 CPU

config CPU_S3C6400
	bool
	help
	  Enable S3C6400 CPU support

config CPU_S3C6410
	bool
	help
	  Enable S3C6410 CPU support

config S3C64XX_PL080
	def_bool DMADEVICES
	select AMBA_PL08X

config S3C64XX_SETUP_SDHCI
	bool
	select S3C64XX_SETUP_SDHCI_GPIO
	help
	  Internal configuration for default SDHCI setup for S3C6400 and
	  S3C6410 SoCs.

config S3C64XX_DEV_ONENAND1
	bool
	help
	  Compile in platform device definition for OneNAND1 controller

config SAMSUNG_DEV_BACKLIGHT
	bool
	depends on SAMSUNG_DEV_PWM
	help
	  Compile in platform device definition LCD backlight with PWM Timer

# platform specific device setup

config S3C64XX_SETUP_I2C0
	bool
	default y
	help
	  Common setup code for i2c bus 0.

	  Note, currently since i2c0 is always compiled, this setup helper
	  is always compiled with it.

config S3C64XX_SETUP_I2C1
	bool
	help
	  Common setup code for i2c bus 1.

config S3C64XX_SETUP_IDE
	bool
	help
	  Common setup code for S3C64XX IDE.

config S3C64XX_SETUP_FB_24BPP
	bool
	help
	  Common setup code for S3C64XX with an 24bpp RGB display helper.

config S3C64XX_SETUP_KEYPAD
	bool
	help
	  Common setup code for S3C64XX KEYPAD GPIO configurations

config S3C64XX_SETUP_SDHCI_GPIO
	bool
	help
	  Common setup code for S3C64XX SDHCI GPIO configurations

config S3C64XX_SETUP_SPI
	bool
	help
	  Common setup code for SPI GPIO configurations

config S3C64XX_SETUP_USB_PHY
	bool
	help
	  Common setup code for USB PHY controller

# S36400 Macchine support

config MACH_SMDK6400
	bool "SMDK6400"
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_S3C6400
	select S3C64XX_SETUP_SDHCI
	select S3C_DEV_HSMMC1
	help
	  Machine support for the Samsung SMDK6400

# S3C6410 machine support

config MACH_ANW6410
	bool "A&W6410"
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_S3C6410
	select S3C64XX_SETUP_FB_24BPP
	select S3C_DEV_FB
	help
	  Machine support for the A&W6410

config MACH_MINI6410
	bool "MINI6410"
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_S3C6410
	select S3C64XX_SETUP_FB_24BPP
	select S3C64XX_SETUP_SDHCI
	select S3C_DEV_FB
	select S3C_DEV_HSMMC
	select S3C_DEV_HSMMC1
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	select SAMSUNG_DEV_ADC
	select SAMSUNG_DEV_TS
	help
	  Machine support for the FriendlyARM MINI6410

config MACH_REAL6410
	bool "REAL6410"
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_S3C6410
	select S3C64XX_SETUP_FB_24BPP
	select S3C64XX_SETUP_SDHCI
	select S3C_DEV_FB
	select S3C_DEV_HSMMC
	select S3C_DEV_HSMMC1
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	select SAMSUNG_DEV_ADC
	select SAMSUNG_DEV_TS
	help
	  Machine support for the CoreWind REAL6410

config MACH_SMDK6410
	bool "SMDK6410"
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_S3C6410
	select S3C64XX_SETUP_FB_24BPP
	select S3C64XX_SETUP_I2C1
	select S3C64XX_SETUP_IDE
	select S3C64XX_SETUP_KEYPAD
	select S3C64XX_SETUP_SDHCI
	select S3C64XX_SETUP_USB_PHY
	select S3C_DEV_FB
	select S3C_DEV_HSMMC
	select S3C_DEV_HSMMC1
	select S3C_DEV_I2C1
	select S3C_DEV_RTC
	select S3C_DEV_USB_HOST
	select S3C_DEV_USB_HSOTG
	select S3C_DEV_WDT
	select SAMSUNG_DEV_ADC
	select SAMSUNG_DEV_BACKLIGHT
	select SAMSUNG_DEV_IDE
	select SAMSUNG_DEV_KEYPAD
	select SAMSUNG_DEV_PWM
	select SAMSUNG_DEV_TS
	help
	  Machine support for the Samsung SMDK6410

# At least some of the SMDK6410s were shipped with the card detect
# for the MMC/SD slots connected to the same input. This means that
# either the boards need to be altered to have channel0 to an alternate
# configuration or that only one slot can be used.

choice
	prompt "SMDK6410 MMC/SD slot setup"
	depends on MACH_SMDK6410

config SMDK6410_SD_CH0
	bool "Use channel 0 only"
	depends on MACH_SMDK6410
	help
	  Select CON7 (channel 0) as the MMC/SD slot, as
	  at least some SMDK6410 boards come with the
	  resistors fitted so that the card detects for
	  channels 0 and 1 are the same.

config SMDK6410_SD_CH1
	bool "Use channel 1 only"
	depends on MACH_SMDK6410
	help
	  Select CON6 (channel 1) as the MMC/SD slot, as
	  at least some SMDK6410 boards come with the
	  resistors fitted so that the card detects for
	  channels 0 and 1 are the same.

endchoice

config SMDK6410_WM1190_EV1
	bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
	depends on MACH_SMDK6410
	depends on I2C=y
	select MFD_WM8350_I2C
	select REGULATOR
	select REGULATOR_WM8350
	help
	  The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
	  and audio daughtercard for the Samsung SMDK6410 reference
	  platform.  Enabling this option will build support for this
	  module into the kernel.  The presence of the module will be
	  detected at runtime so the resulting kernel can be used
	  with or without the 1190-EV1 fitted.

config SMDK6410_WM1192_EV1
	bool "Support Wolfson Microelectronics 1192-EV1 PMIC card"
	depends on MACH_SMDK6410
	depends on I2C=y
	select MFD_WM831X
	select MFD_WM831X_I2C
	select REGULATOR
	select REGULATOR_WM831X
	help
	  The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
	  daughtercard for the Samsung SMDK6410 reference platform.
	  Enabling this option will build support for this module into
	  the kernel.  The presence of the daughtercard will be
	  detected at runtime so the resulting kernel can be used
	  with or without the 1192-EV1 fitted.

config MACH_NCP
	bool "NCP"
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_S3C6410
	select S3C64XX_SETUP_I2C1
	select S3C_DEV_HSMMC1
	select S3C_DEV_I2C1
	help
	  Machine support for the Samsung NCP

config MACH_HMT
	bool "Airgoo HMT"
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_S3C6410
	select S3C64XX_SETUP_FB_24BPP
	select S3C_DEV_FB
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	select SAMSUNG_DEV_PWM
	help
	  Machine support for the Airgoo HMT

config MACH_SMARTQ
	bool
	select CPU_S3C6410
	select S3C64XX_SETUP_FB_24BPP
	select S3C64XX_SETUP_SDHCI
	select S3C64XX_SETUP_USB_PHY
	select S3C_DEV_FB
	select S3C_DEV_HSMMC
	select S3C_DEV_HSMMC1
	select S3C_DEV_HSMMC2
	select S3C_DEV_HWMON
	select S3C_DEV_RTC
	select S3C_DEV_USB_HOST
	select S3C_DEV_USB_HSOTG
	select SAMSUNG_DEV_ADC
	select SAMSUNG_DEV_PWM
	select SAMSUNG_DEV_TS
	help
	  Shared machine support for SmartQ 5/7

config MACH_SMARTQ5
	bool "SmartQ 5"
	depends on ATAGS && UNUSED_BOARD_FILES
	select MACH_SMARTQ
	help
	  Machine support for the SmartQ 5

config MACH_SMARTQ7
	bool "SmartQ 7"
	depends on ATAGS && UNUSED_BOARD_FILES
	select MACH_SMARTQ
	help
	  Machine support for the SmartQ 7

config MACH_WLF_CRAGG_6410
	bool "Wolfson Cragganmore 6410"
	depends on ATAGS
	depends on I2C=y
	select CPU_S3C6410
	select LEDS_GPIO_REGISTER
	select S3C64XX_DEV_SPI0
	select S3C64XX_SETUP_FB_24BPP
	select S3C64XX_SETUP_I2C1
	select S3C64XX_SETUP_IDE
	select S3C64XX_SETUP_KEYPAD
	select S3C64XX_SETUP_SDHCI
	select S3C64XX_SETUP_SPI
	select S3C64XX_SETUP_USB_PHY
	select S3C_DEV_FB
	select S3C_DEV_HSMMC
	select S3C_DEV_HSMMC1
	select S3C_DEV_HSMMC2
	select S3C_DEV_I2C1
	select S3C_DEV_RTC
	select S3C_DEV_USB_HOST
	select S3C_DEV_USB_HSOTG
	select S3C_DEV_WDT
	select SAMSUNG_DEV_ADC
	select SAMSUNG_DEV_KEYPAD
	select SAMSUNG_DEV_PWM
	help
	  Machine support for the Wolfson Cragganmore S3C6410 variant.

config MACH_S3C64XX_DT
	bool "Samsung S3C6400/S3C6410 machine using Device Tree"
	select CPU_S3C6400
	select CPU_S3C6410
	select PINCTRL
	select PINCTRL_S3C64XX
	help
	  Machine support for Samsung S3C6400/S3C6410 machines with Device Tree
	  enabled.
	  Select this if a fdt blob is available for your S3C64XX SoC based
	  board.
	  Note: This is under development and not all peripherals can be
	  supported with this machine file.

endif


code:
# SPDX-License-Identifier: GPL-2.0
#
# Copyright 2009 Simtec Electronics

ifdef CONFIG_ARCH_S3C24XX
include $(src)/Makefile.s3c24xx
endif

ifdef CONFIG_ARCH_S3C64XX
include $(src)/Makefile.s3c64xx
endif

# Objects we always build independent of SoC choice

obj-y				+= init.o cpu.o

# ADC

obj-$(CONFIG_S3C_ADC)	+= adc.o

# devices

obj-$(CONFIG_SAMSUNG_ATAGS)	+= platformdata.o

obj-$(CONFIG_SAMSUNG_ATAGS)	+= devs.o
obj-$(CONFIG_SAMSUNG_ATAGS)	+= dev-uart.o

obj-$(CONFIG_GPIO_SAMSUNG)     += gpio-samsung.o

# PM support

obj-$(CONFIG_SAMSUNG_PM)	+= pm.o pm-common.o
obj-$(CONFIG_SAMSUNG_PM_GPIO)	+= pm-gpio.o

obj-$(CONFIG_SAMSUNG_WAKEMASK)	+= wakeup-mask.o


code:
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2012 Samsung Electronics Co., Ltd.
#		http://www.samsung.com/
#
# Copyright 2007 Simtec Electronics

# core

obj-y				+= s3c24xx.o
obj-y				+= irq-s3c24xx.o
obj-$(CONFIG_SPI_S3C24XX_FIQ)	+= irq-s3c24xx-fiq.o
obj-$(CONFIG_SPI_S3C24XX_FIQ)	+= irq-s3c24xx-fiq-exports.o

obj-$(CONFIG_CPU_S3C2410)	+= s3c2410.o
obj-$(CONFIG_S3C2410_PLL)	+= pll-s3c2410.o
obj-$(CONFIG_S3C2410_PM)	+= pm-s3c2410.o sleep-s3c2410.o

obj-$(CONFIG_CPU_S3C2412)	+= s3c2412.o
obj-$(CONFIG_S3C2412_PM)	+= pm-s3c2412.o
obj-$(CONFIG_S3C2412_PM_SLEEP)	+= sleep-s3c2412.o

obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o
obj-$(CONFIG_S3C2416_PM)	+= pm-s3c2416.o

obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o
obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o

obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o

# PM

obj-$(CONFIG_PM)		+= pm-s3c24xx.o
obj-$(CONFIG_PM_SLEEP)		+= irq-pm-s3c24xx.o sleep-s3c24xx.o

# common code

obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += cpufreq-utils-s3c24xx.o

obj-$(CONFIG_S3C2410_IOTIMING)	+= iotiming-s3c2410.o
obj-$(CONFIG_S3C2412_IOTIMING)	+= iotiming-s3c2412.o

#
# machine support
# following is ordered alphabetically by option text.
#

obj-$(CONFIG_MACH_AML_M5900)		+= mach-amlm5900.o
obj-$(CONFIG_ARCH_BAST)			+= mach-bast.o
obj-$(CONFIG_BAST_PC104_IRQ)		+= bast-irq.o
obj-$(CONFIG_ARCH_H1940)		+= mach-h1940.o
obj-$(CONFIG_H1940BT)			+= h1940-bluetooth.o
obj-$(CONFIG_PM_H1940)			+= pm-h1940.o
obj-$(CONFIG_MACH_N30)			+= mach-n30.o
obj-$(CONFIG_MACH_OTOM)			+= mach-otom.o
obj-$(CONFIG_MACH_QT2410)		+= mach-qt2410.o
obj-$(CONFIG_ARCH_SMDK2410)		+= mach-smdk2410.o
obj-$(CONFIG_MACH_TCT_HAMMER)		+= mach-tct_hammer.o
obj-$(CONFIG_MACH_VR1000)		+= mach-vr1000.o

obj-$(CONFIG_MACH_JIVE)			+= mach-jive.o
obj-$(CONFIG_MACH_SMDK2413)		+= mach-smdk2413.o
obj-$(CONFIG_MACH_VSTMS)		+= mach-vstms.o

obj-$(CONFIG_MACH_SMDK2416)		+= mach-smdk2416.o
obj-$(CONFIG_MACH_S3C2416_DT)		+= mach-s3c2416-dt.o

obj-$(CONFIG_MACH_ANUBIS)		+= mach-anubis.o
obj-$(CONFIG_MACH_AT2440EVB)		+= mach-at2440evb.o
obj-$(CONFIG_MACH_MINI2440)		+= mach-mini2440.o
obj-$(CONFIG_MACH_NEXCODER_2440)	+= mach-nexcoder.o
obj-$(CONFIG_MACH_OSIRIS)		+= mach-osiris.o
obj-$(CONFIG_MACH_RX3715)		+= mach-rx3715.o
obj-$(CONFIG_ARCH_S3C2440)		+= mach-smdk2440.o

obj-$(CONFIG_MACH_NEO1973_GTA02)	+= mach-gta02.o
obj-$(CONFIG_MACH_RX1950)		+= mach-rx1950.o

obj-$(CONFIG_MACH_SMDK2443)		+= mach-smdk2443.o

# common bits of machine support

obj-$(CONFIG_S3C24XX_SMDK)		+= common-smdk-s3c24xx.o
obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO)	+= simtec-audio.o
obj-$(CONFIG_S3C24XX_SIMTEC_NOR)	+= simtec-nor.o
obj-$(CONFIG_S3C24XX_SIMTEC_PM)		+= simtec-pm.o
obj-$(CONFIG_S3C24XX_SIMTEC_USB)	+= simtec-usb.o

# machine additions

obj-$(CONFIG_MACH_BAST_IDE)		+= bast-ide.o
obj-$(CONFIG_MACH_OSIRIS_DVS)		+= mach-osiris-dvs.o

# device setup

obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio-s3c24xx.o
obj-$(CONFIG_S3C2443_SETUP_SPI)		+= setup-spi-s3c24xx.o
obj-$(CONFIG_ARCH_S3C24XX)		+= setup-i2c-s3c24xx.o
obj-$(CONFIG_S3C24XX_SETUP_TS)		+= setup-ts-s3c24xx.o


code:
# SPDX-License-Identifier: GPL-2.0
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics

# PM

obj-$(CONFIG_PM)		+= pm-s3c64xx.o
obj-$(CONFIG_PM_SLEEP)		+= sleep-s3c64xx.o
obj-$(CONFIG_CPU_IDLE)		+= cpuidle-s3c64xx.o

ifdef CONFIG_SAMSUNG_ATAGS

obj-$(CONFIG_PM_SLEEP)          += irq-pm-s3c64xx.o

# Core

obj-y				+= s3c64xx.o
obj-$(CONFIG_CPU_S3C6400)	+= s3c6400.o
obj-$(CONFIG_CPU_S3C6410)	+= s3c6410.o

# DMA support

obj-$(CONFIG_S3C64XX_PL080)	+= pl080.o

# Device support

obj-y				+= dev-uart-s3c64xx.o
obj-y				+= dev-audio-s3c64xx.o

# Device setup

obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP)	+= setup-fb-24bpp-s3c64xx.o
obj-$(CONFIG_S3C64XX_SETUP_I2C0)	+= setup-i2c0-s3c64xx.o
obj-$(CONFIG_S3C64XX_SETUP_I2C1)	+= setup-i2c1-s3c64xx.o
obj-$(CONFIG_S3C64XX_SETUP_IDE)		+= setup-ide-s3c64xx.o
obj-$(CONFIG_S3C64XX_SETUP_KEYPAD)	+= setup-keypad-s3c64xx.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio-s3c64xx.o
obj-$(CONFIG_S3C64XX_SETUP_SPI)		+= setup-spi-s3c64xx.o
obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy-s3c64xx.o

obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT)	+= dev-backlight-s3c64xx.o

# Machine support

obj-$(CONFIG_MACH_ANW6410)		+= mach-anw6410.o
obj-$(CONFIG_MACH_HMT)			+= mach-hmt.o
obj-$(CONFIG_MACH_MINI6410)		+= mach-mini6410.o
obj-$(CONFIG_MACH_NCP)			+= mach-ncp.o
obj-$(CONFIG_MACH_REAL6410)		+= mach-real6410.o
obj-$(CONFIG_MACH_SMARTQ)		+= mach-smartq.o
obj-$(CONFIG_MACH_SMARTQ5)		+= mach-smartq5.o
obj-$(CONFIG_MACH_SMARTQ7)		+= mach-smartq7.o
obj-$(CONFIG_MACH_SMDK6400)		+= mach-smdk6400.o
obj-$(CONFIG_MACH_SMDK6410)		+= mach-smdk6410.o
obj-$(CONFIG_MACH_WLF_CRAGG_6410)	+= mach-crag6410.o mach-crag6410-module.o
endif

obj-$(CONFIG_MACH_S3C64XX_DT)		+= mach-s3c64xx-dt.o


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com/
 *
 * Samsung ADC Controller core functions
 */

#ifndef __ASM_PLAT_ADC_CORE_H
#define __ASM_PLAT_ADC_CORE_H __FILE__

/* These functions are only for use with the core support code, such as
 * the cpu specific initialisation code
 */

/* re-define device name depending on support. */
static inline void s3c_adc_setname(char *name)
{
#if defined(CONFIG_SAMSUNG_DEV_ADC) || defined(CONFIG_PLAT_S3C24XX)
	s3c_device_adc.name = name;
#endif
}

#endif /* __ASM_PLAT_ADC_CORE_H */


code:
// SPDX-License-Identifier: GPL-1.0+
//
// Copyright (c) 2008 Simtec Electronics
//	http://armlinux.simtec.co.uk/
//	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
//
// Samsung ADC device core

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/regulator/consumer.h>

#include "regs-adc.h"
#include <linux/soc/samsung/s3c-adc.h>

/* This driver is designed to control the usage of the ADC block between
 * the touchscreen and any other drivers that may need to use it, such as
 * the hwmon driver.
 *
 * Priority will be given to the touchscreen driver, but as this itself is
 * rate limited it should not starve other requests which are processed in
 * order that they are received.
 *
 * Each user registers to get a client block which uniquely identifies it
 * and stores information such as the necessary functions to callback when
 * action is required.
 */

enum s3c_cpu_type {
	TYPE_ADCV1, /* S3C24XX */
	TYPE_ADCV11, /* S3C2443 */
	TYPE_ADCV12, /* S3C2416, S3C2450 */
	TYPE_ADCV2, /* S3C64XX */
	TYPE_ADCV3, /* S5PV210, S5PC110, Exynos4210 */
};

struct s3c_adc_client {
	struct platform_device	*pdev;
	struct list_head	 pend;
	wait_queue_head_t	*wait;

	unsigned int		 nr_samples;
	int			 result;
	unsigned char		 is_ts;
	unsigned char		 channel;

	void	(*select_cb)(struct s3c_adc_client *c, unsigned selected);
	void	(*convert_cb)(struct s3c_adc_client *c,
			      unsigned val1, unsigned val2,
			      unsigned *samples_left);
};

struct adc_device {
	struct platform_device	*pdev;
	struct platform_device	*owner;
	struct clk		*clk;
	struct s3c_adc_client	*cur;
	struct s3c_adc_client	*ts_pend;
	void __iomem		*regs;
	spinlock_t		 lock;

	unsigned int		 prescale;

	int			 irq;
	struct regulator	*vdd;
};

static struct adc_device *adc_dev;

static LIST_HEAD(adc_pending);	/* protected by adc_device.lock */

#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg)

static inline void s3c_adc_convert(struct adc_device *adc)
{
	unsigned con = readl(adc->regs + S3C2410_ADCCON);

	con |= S3C2410_ADCCON_ENABLE_START;
	writel(con, adc->regs + S3C2410_ADCCON);
}

static inline void s3c_adc_select(struct adc_device *adc,
				  struct s3c_adc_client *client)
{
	unsigned con = readl(adc->regs + S3C2410_ADCCON);
	enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;

	client->select_cb(client, 1);

	if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV2)
		con &= ~S3C2410_ADCCON_MUXMASK;
	con &= ~S3C2410_ADCCON_STDBM;
	con &= ~S3C2410_ADCCON_STARTMASK;

	if (!client->is_ts) {
		if (cpu == TYPE_ADCV3)
			writel(client->channel & 0xf, adc->regs + S5P_ADCMUX);
		else if (cpu == TYPE_ADCV11 || cpu == TYPE_ADCV12)
			writel(client->channel & 0xf,
						adc->regs + S3C2443_ADCMUX);
		else
			con |= S3C2410_ADCCON_SELMUX(client->channel);
	}

	writel(con, adc->regs + S3C2410_ADCCON);
}

static void s3c_adc_dbgshow(struct adc_device *adc)
{
	adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
		readl(adc->regs + S3C2410_ADCCON),
		readl(adc->regs + S3C2410_ADCTSC),
		readl(adc->regs + S3C2410_ADCDLY));
}

static void s3c_adc_try(struct adc_device *adc)
{
	struct s3c_adc_client *next = adc->ts_pend;

	if (!next && !list_empty(&adc_pending)) {
		next = list_first_entry(&adc_pending,
					struct s3c_adc_client, pend);
		list_del(&next->pend);
	} else
		adc->ts_pend = NULL;

	if (next) {
		adc_dbg(adc, "new client is %p\n", next);
		adc->cur = next;
		s3c_adc_select(adc, next);
		s3c_adc_convert(adc);
		s3c_adc_dbgshow(adc);
	}
}

int s3c_adc_start(struct s3c_adc_client *client,
		  unsigned int channel, unsigned int nr_samples)
{
	struct adc_device *adc = adc_dev;
	unsigned long flags;

	if (!adc) {
		printk(KERN_ERR "%s: failed to find adc\n", __func__);
		return -EINVAL;
	}

	spin_lock_irqsave(&adc->lock, flags);

	if (client->is_ts && adc->ts_pend) {
		spin_unlock_irqrestore(&adc->lock, flags);
		return -EAGAIN;
	}

	client->channel = channel;
	client->nr_samples = nr_samples;

	if (client->is_ts)
		adc->ts_pend = client;
	else
		list_add_tail(&client->pend, &adc_pending);

	if (!adc->cur)
		s3c_adc_try(adc);

	spin_unlock_irqrestore(&adc->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(s3c_adc_start);

static void s3c_convert_done(struct s3c_adc_client *client,
			     unsigned v, unsigned u, unsigned *left)
{
	client->result = v;
	wake_up(client->wait);
}

int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
{
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
	int ret;

	client->convert_cb = s3c_convert_done;
	client->wait = &wake;
	client->result = -1;

	ret = s3c_adc_start(client, ch, 1);
	if (ret < 0)
		goto err;

	ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
	if (client->result < 0) {
		ret = -ETIMEDOUT;
		goto err;
	}

	client->convert_cb = NULL;
	return client->result;

err:
	return ret;
}
EXPORT_SYMBOL_GPL(s3c_adc_read);

static void s3c_adc_default_select(struct s3c_adc_client *client,
				   unsigned select)
{
}

struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
					void (*select)(struct s3c_adc_client *client,
						       unsigned int selected),
					void (*conv)(struct s3c_adc_client *client,
						     unsigned d0, unsigned d1,
						     unsigned *samples_left),
					unsigned int is_ts)
{
	struct s3c_adc_client *client;

	WARN_ON(!pdev);

	if (!select)
		select = s3c_adc_default_select;

	if (!pdev)
		return ERR_PTR(-EINVAL);

	client = kzalloc(sizeof(*client), GFP_KERNEL);
	if (!client)
		return ERR_PTR(-ENOMEM);

	client->pdev = pdev;
	client->is_ts = is_ts;
	client->select_cb = select;
	client->convert_cb = conv;

	return client;
}
EXPORT_SYMBOL_GPL(s3c_adc_register);

void s3c_adc_release(struct s3c_adc_client *client)
{
	unsigned long flags;

	spin_lock_irqsave(&adc_dev->lock, flags);

	/* We should really check that nothing is in progress. */
	if (adc_dev->cur == client)
		adc_dev->cur = NULL;
	if (adc_dev->ts_pend == client)
		adc_dev->ts_pend = NULL;
	else {
		struct list_head *p, *n;
		struct s3c_adc_client *tmp;

		list_for_each_safe(p, n, &adc_pending) {
			tmp = list_entry(p, struct s3c_adc_client, pend);
			if (tmp == client)
				list_del(&tmp->pend);
		}
	}

	if (adc_dev->cur == NULL)
		s3c_adc_try(adc_dev);

	spin_unlock_irqrestore(&adc_dev->lock, flags);
	kfree(client);
}
EXPORT_SYMBOL_GPL(s3c_adc_release);

static irqreturn_t s3c_adc_irq(int irq, void *pw)
{
	struct adc_device *adc = pw;
	struct s3c_adc_client *client = adc->cur;
	enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
	unsigned data0, data1;

	if (!client) {
		dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
		goto exit;
	}

	data0 = readl(adc->regs + S3C2410_ADCDAT0);
	data1 = readl(adc->regs + S3C2410_ADCDAT1);
	adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);

	client->nr_samples--;

	if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV11) {
		data0 &= 0x3ff;
		data1 &= 0x3ff;
	} else {
		/* S3C2416/S3C64XX/S5P ADC resolution is 12-bit */
		data0 &= 0xfff;
		data1 &= 0xfff;
	}

	if (client->convert_cb)
		(client->convert_cb)(client, data0, data1, &client->nr_samples);

	if (client->nr_samples > 0) {
		/* fire another conversion for this */

		client->select_cb(client, 1);
		s3c_adc_convert(adc);
	} else {
		spin_lock(&adc->lock);
		(client->select_cb)(client, 0);
		adc->cur = NULL;

		s3c_adc_try(adc);
		spin_unlock(&adc->lock);
	}

exit:
	if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) {
		/* Clear ADC interrupt */
		writel(0, adc->regs + S3C64XX_ADCCLRINT);
	}
	return IRQ_HANDLED;
}

static int s3c_adc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct adc_device *adc;
	enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
	int ret;
	unsigned tmp;

	adc = devm_kzalloc(dev, sizeof(*adc), GFP_KERNEL);
	if (!adc)
		return -ENOMEM;

	spin_lock_init(&adc->lock);

	adc->pdev = pdev;
	adc->prescale = S3C2410_ADCCON_PRSCVL(49);

	adc->vdd = devm_regulator_get(dev, "vdd");
	if (IS_ERR(adc->vdd)) {
		dev_err(dev, "operating without regulator \"vdd\" .\n");
		return PTR_ERR(adc->vdd);
	}

	adc->irq = platform_get_irq(pdev, 1);
	if (adc->irq <= 0)
		return -ENOENT;

	ret = devm_request_irq(dev, adc->irq, s3c_adc_irq, 0, dev_name(dev),
				adc);
	if (ret < 0) {
		dev_err(dev, "failed to attach adc irq\n");
		return ret;
	}

	adc->clk = devm_clk_get(dev, "adc");
	if (IS_ERR(adc->clk)) {
		dev_err(dev, "failed to get adc clock\n");
		return PTR_ERR(adc->clk);
	}

	adc->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(adc->regs))
		return PTR_ERR(adc->regs);

	ret = regulator_enable(adc->vdd);
	if (ret)
		return ret;

	clk_prepare_enable(adc->clk);

	tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;

	/* Enable 12-bit ADC resolution */
	if (cpu == TYPE_ADCV12)
		tmp |= S3C2416_ADCCON_RESSEL;
	if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
		tmp |= S3C64XX_ADCCON_RESSEL;

	writel(tmp, adc->regs + S3C2410_ADCCON);

	dev_info(dev, "attached adc driver\n");

	platform_set_drvdata(pdev, adc);
	adc_dev = adc;

	return 0;
}

static int s3c_adc_remove(struct platform_device *pdev)
{
	struct adc_device *adc = platform_get_drvdata(pdev);

	clk_disable_unprepare(adc->clk);
	regulator_disable(adc->vdd);

	return 0;
}

#ifdef CONFIG_PM
static int s3c_adc_suspend(struct device *dev)
{
	struct adc_device *adc = dev_get_drvdata(dev);
	unsigned long flags;
	u32 con;

	spin_lock_irqsave(&adc->lock, flags);

	con = readl(adc->regs + S3C2410_ADCCON);
	con |= S3C2410_ADCCON_STDBM;
	writel(con, adc->regs + S3C2410_ADCCON);

	disable_irq(adc->irq);
	spin_unlock_irqrestore(&adc->lock, flags);
	clk_disable(adc->clk);
	regulator_disable(adc->vdd);

	return 0;
}

static int s3c_adc_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct adc_device *adc = platform_get_drvdata(pdev);
	enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
	int ret;
	unsigned long tmp;

	ret = regulator_enable(adc->vdd);
	if (ret)
		return ret;
	clk_enable(adc->clk);
	enable_irq(adc->irq);

	tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;

	/* Enable 12-bit ADC resolution */
	if (cpu == TYPE_ADCV12)
		tmp |= S3C2416_ADCCON_RESSEL;
	if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
		tmp |= S3C64XX_ADCCON_RESSEL;

	writel(tmp, adc->regs + S3C2410_ADCCON);

	return 0;
}

#else
#define s3c_adc_suspend NULL
#define s3c_adc_resume NULL
#endif

static const struct platform_device_id s3c_adc_driver_ids[] = {
	{
		.name           = "s3c24xx-adc",
		.driver_data    = TYPE_ADCV1,
	}, {
		.name		= "s3c2443-adc",
		.driver_data	= TYPE_ADCV11,
	}, {
		.name		= "s3c2416-adc",
		.driver_data	= TYPE_ADCV12,
	}, {
		.name           = "s3c64xx-adc",
		.driver_data    = TYPE_ADCV2,
	}, {
		.name		= "samsung-adc-v3",
		.driver_data	= TYPE_ADCV3,
	},
	{ }
};
MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids);

static const struct dev_pm_ops adc_pm_ops = {
	.suspend	= s3c_adc_suspend,
	.resume		= s3c_adc_resume,
};

static struct platform_driver s3c_adc_driver = {
	.id_table	= s3c_adc_driver_ids,
	.driver		= {
		.name	= "s3c-adc",
		.pm	= &adc_pm_ops,
	},
	.probe		= s3c_adc_probe,
	.remove		= s3c_adc_remove,
};

static int __init adc_init(void)
{
	int ret;

	ret = platform_driver_register(&s3c_adc_driver);
	if (ret)
		printk(KERN_ERR "%s: failed to add adc driver\n", __func__);

	return ret;
}

module_init(adc_init);


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2005 Simtec Electronics
 *	http://www.simtec.co.uk/products/
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * ANUBIS - CPLD control constants
 * ANUBIS - IRQ Number definitions
 * ANUBIS - Memory map definitions
 */

#ifndef __MACH_S3C24XX_ANUBIS_H
#define __MACH_S3C24XX_ANUBIS_H __FILE__

/* CTRL2 - NAND WP control, IDE Reset assert/check */

#define ANUBIS_CTRL1_NANDSEL		(0x3)

/* IDREG - revision */

#define ANUBIS_IDREG_REVMASK		(0x7)

/* irq */

#define ANUBIS_IRQ_IDE0			IRQ_EINT2
#define ANUBIS_IRQ_IDE1			IRQ_EINT3
#define ANUBIS_IRQ_ASIX			IRQ_EINT1

/* map */

/* start peripherals off after the S3C2410 */

#define ANUBIS_IOADDR(x)		(S3C2410_ADDR((x) + 0x01800000))

#define ANUBIS_PA_CPLD			(S3C2410_CS1 | (1<<26))

/* we put the CPLD registers next, to get them out of the way */

#define ANUBIS_VA_CTRL1			ANUBIS_IOADDR(0x00000000)
#define ANUBIS_PA_CTRL1			ANUBIS_PA_CPLD

#define ANUBIS_VA_IDREG			ANUBIS_IOADDR(0x00300000)
#define ANUBIS_PA_IDREG			(ANUBIS_PA_CPLD + (3 << 23))

#define ANUBIS_IDEPRI			ANUBIS_IOADDR(0x01000000)
#define ANUBIS_IDEPRIAUX		ANUBIS_IOADDR(0x01100000)
#define ANUBIS_IDESEC			ANUBIS_IOADDR(0x01200000)
#define ANUBIS_IDESECAUX		ANUBIS_IOADDR(0x01300000)

#endif /* __MACH_S3C24XX_ANUBIS_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * Samsung CF-ATA Controller core functions
 */

#ifndef __ASM_PLAT_ATA_CORE_S3C64XX_H
#define __ASM_PLAT_ATA_CORE_S3C64XX_H __FILE__

/* These functions are only for use with the core support code, such as
 * the cpu specific initialisation code
*/

/* re-define device name depending on support. */
static inline void s3c_cfcon_setname(char *name)
{
#ifdef CONFIG_SAMSUNG_DEV_IDE
	s3c_device_cfcon.name = name;
#endif
}

#endif /* __ASM_PLAT_ATA_CORE_S3C64XX_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
 *              http://www.samsung.com
 */

#ifndef __ASM_PLAT_BACKLIGHT_S3C64XX_H
#define __ASM_PLAT_BACKLIGHT_S3C64XX_H __FILE__

/* samsung_bl_gpio_info - GPIO info for PWM Backlight control
 * @no:		GPIO number for PWM timer out
 * @func:	Special function of GPIO line for PWM timer
 */
struct samsung_bl_gpio_info {
	int no;
	int func;
};

extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
	struct platform_pwm_backlight_data *bl_data);

#endif /* __ASM_PLAT_BACKLIGHT_S3C64XX_H */


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright 2007 Simtec Electronics
//	http://www.simtec.co.uk/products/EB2410ITX/
//	http://armlinux.simtec.co.uk/
//	Ben Dooks <ben@simtec.co.uk>

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/interrupt.h>

#include <linux/platform_device.h>
#include <linux/ata_platform.h>

#include <asm/mach-types.h>

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

#include "map.h"
#include "irqs.h"

#include "bast.h"

/* IDE ports */

static struct pata_platform_info bast_ide_platdata = {
	.ioport_shift	= 5,
};

static struct resource bast_ide0_resource[] = {
	[0] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRI, 8 * 0x20),
	[1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20), 0x20),
	[2] = DEFINE_RES_IRQ(BAST_IRQ_IDE0),
};

static struct platform_device bast_device_ide0 = {
	.name		= "pata_platform",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(bast_ide0_resource),
	.resource	= bast_ide0_resource,
	.dev		= {
		.platform_data = &bast_ide_platdata,
		.coherent_dma_mask = ~0,
	}

};

static struct resource bast_ide1_resource[] = {
	[0] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESEC, 8 * 0x20),
	[1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20), 0x20),
	[2] = DEFINE_RES_IRQ(BAST_IRQ_IDE1),
};

static struct platform_device bast_device_ide1 = {
	.name		= "pata_platform",
	.id		= 1,
	.num_resources	= ARRAY_SIZE(bast_ide1_resource),
	.resource	= bast_ide1_resource,
	.dev		= {
		.platform_data = &bast_ide_platdata,
		.coherent_dma_mask = ~0,
	}
};

static struct platform_device *bast_ide_devices[] __initdata = {
	&bast_device_ide0,
	&bast_device_ide1,
};

static __init int bast_ide_init(void)
{
	if (machine_is_bast() || machine_is_vr1000())
		return platform_add_devices(bast_ide_devices,
					    ARRAY_SIZE(bast_ide_devices));

	return 0;
}

fs_initcall(bast_ide_init);


code:
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright 2003-2005 Simtec Electronics
//   Ben Dooks <ben@simtec.co.uk>
//
// http://www.simtec.co.uk/products/EB2410ITX/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/io.h>

#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/mach/irq.h>

#include "regs-irq.h"
#include "irqs.h"

#include "bast.h"

#define irqdbf(x...)
#define irqdbf2(x...)

/* handle PC104 ISA interrupts from the system CPLD */

/* table of ISA irq nos to the relevant mask... zero means
 * the irq is not implemented
*/
static const unsigned char bast_pc104_irqmasks[] = {
	0,   /* 0 */
	0,   /* 1 */
	0,   /* 2 */
	1,   /* 3 */
	0,   /* 4 */
	2,   /* 5 */
	0,   /* 6 */
	4,   /* 7 */
	0,   /* 8 */
	0,   /* 9 */
	8,   /* 10 */
	0,   /* 11 */
	0,   /* 12 */
	0,   /* 13 */
	0,   /* 14 */
	0,   /* 15 */
};

static const unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };

static void
bast_pc104_mask(struct irq_data *data)
{
	unsigned long temp;

	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
	temp &= ~bast_pc104_irqmasks[data->irq];
	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}

static void
bast_pc104_maskack(struct irq_data *data)
{
	struct irq_desc *desc = irq_to_desc(BAST_IRQ_ISA);

	bast_pc104_mask(data);
	desc->irq_data.chip->irq_ack(&desc->irq_data);
}

static void
bast_pc104_unmask(struct irq_data *data)
{
	unsigned long temp;

	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
	temp |= bast_pc104_irqmasks[data->irq];
	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}

static struct irq_chip  bast_pc104_chip = {
	.irq_mask	= bast_pc104_mask,
	.irq_unmask	= bast_pc104_unmask,
	.irq_ack	= bast_pc104_maskack
};

static void bast_irq_pc104_demux(struct irq_desc *desc)
{
	unsigned int stat;
	unsigned int irqno;
	int i;

	stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;

	if (unlikely(stat == 0)) {
		/* ack if we get an irq with nothing (ie, startup) */
		desc->irq_data.chip->irq_ack(&desc->irq_data);
	} else {
		/* handle the IRQ */

		for (i = 0; stat != 0; i++, stat >>= 1) {
			if (stat & 1) {
				irqno = bast_pc104_irqs[i];
				generic_handle_irq(irqno);
			}
		}
	}
}

static __init int bast_irq_init(void)
{
	unsigned int i;

	if (machine_is_bast()) {
		printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");

		/* zap all the IRQs */

		__raw_writeb(0x0, BAST_VA_PC104_IRQMASK);

		irq_set_chained_handler(BAST_IRQ_ISA, bast_irq_pc104_demux);

		/* register our IRQs */

		for (i = 0; i < 4; i++) {
			unsigned int irqno = bast_pc104_irqs[i];

			irq_set_chip_and_handler(irqno, &bast_pc104_chip,
						 handle_level_irq);
			irq_clear_status_flags(irqno, IRQ_NOREQUEST);
		}
	}

	return 0;
}

arch_initcall(bast_irq_init);


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2003-2004 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * BAST - CPLD control constants
 * BAST - IRQ Number definitions
 * BAST - Memory map definitions
 */

#ifndef __MACH_S3C24XX_BAST_H
#define __MACH_S3C24XX_BAST_H __FILE__

/* CTRL1 - Audio LR routing */

#define BAST_CPLD_CTRL1_LRCOFF		(0x00)
#define BAST_CPLD_CTRL1_LRCADC		(0x01)
#define BAST_CPLD_CTRL1_LRCDAC		(0x02)
#define BAST_CPLD_CTRL1_LRCARM		(0x03)
#define BAST_CPLD_CTRL1_LRMASK		(0x03)

/* CTRL2 - NAND WP control, IDE Reset assert/check */

#define BAST_CPLD_CTRL2_WNAND		(0x04)
#define BAST_CPLD_CTLR2_IDERST		(0x08)

/* CTRL3 - rom write control, CPLD identity */

#define BAST_CPLD_CTRL3_IDMASK		(0x0e)
#define BAST_CPLD_CTRL3_ROMWEN		(0x01)

/* CTRL4 - 8bit LCD interface control/status */

#define BAST_CPLD_CTRL4_LLAT		(0x01)
#define BAST_CPLD_CTRL4_LCDRW		(0x02)
#define BAST_CPLD_CTRL4_LCDCMD		(0x04)
#define BAST_CPLD_CTRL4_LCDE2		(0x01)

/* CTRL5 - DMA routing */

#define BAST_CPLD_DMA0_PRIIDE		(0)
#define BAST_CPLD_DMA0_SECIDE		(1)
#define BAST_CPLD_DMA0_ISA15		(2)
#define BAST_CPLD_DMA0_ISA36		(3)

#define BAST_CPLD_DMA1_PRIIDE		(0 << 2)
#define BAST_CPLD_DMA1_SECIDE		(1 << 2)
#define BAST_CPLD_DMA1_ISA15		(2 << 2)
#define BAST_CPLD_DMA1_ISA36		(3 << 2)

/* irq numbers to onboard peripherals */

#define BAST_IRQ_USBOC			IRQ_EINT18
#define BAST_IRQ_IDE0			IRQ_EINT16
#define BAST_IRQ_IDE1			IRQ_EINT17
#define BAST_IRQ_PCSERIAL1		IRQ_EINT15
#define BAST_IRQ_PCSERIAL2		IRQ_EINT14
#define BAST_IRQ_PCPARALLEL		IRQ_EINT13
#define BAST_IRQ_ASIX			IRQ_EINT11
#define BAST_IRQ_DM9000			IRQ_EINT10
#define BAST_IRQ_ISA			IRQ_EINT9
#define BAST_IRQ_SMALERT		IRQ_EINT8

/* map */

/*
 * ok, we've used up to 0x13000000, now we need to find space for the
 * peripherals that live in the nGCS[x] areas, which are quite numerous
 * in their space. We also have the board's CPLD to find register space
 * for.
 */

#define BAST_IOADDR(x)			(S3C2410_ADDR((x) + 0x01300000))

/* we put the CPLD registers next, to get them out of the way */

#define BAST_VA_CTRL1			BAST_IOADDR(0x00000000)
#define BAST_PA_CTRL1			(S3C2410_CS5 | 0x7800000)

#define BAST_VA_CTRL2			BAST_IOADDR(0x00100000)
#define BAST_PA_CTRL2			(S3C2410_CS1 | 0x6000000)

#define BAST_VA_CTRL3			BAST_IOADDR(0x00200000)
#define BAST_PA_CTRL3			(S3C2410_CS1 | 0x6800000)

#define BAST_VA_CTRL4			BAST_IOADDR(0x00300000)
#define BAST_PA_CTRL4			(S3C2410_CS1 | 0x7000000)

/* next, we have the PC104 ISA interrupt registers */

#define BAST_PA_PC104_IRQREQ		(S3C2410_CS5 | 0x6000000)
#define BAST_VA_PC104_IRQREQ		BAST_IOADDR(0x00400000)

#define BAST_PA_PC104_IRQRAW		(S3C2410_CS5 | 0x6800000)
#define BAST_VA_PC104_IRQRAW		BAST_IOADDR(0x00500000)

#define BAST_PA_PC104_IRQMASK		(S3C2410_CS5 | 0x7000000)
#define BAST_VA_PC104_IRQMASK		BAST_IOADDR(0x00600000)

#define BAST_PA_LCD_RCMD1		(0x8800000)
#define BAST_VA_LCD_RCMD1		BAST_IOADDR(0x00700000)

#define BAST_PA_LCD_WCMD1		(0x8000000)
#define BAST_VA_LCD_WCMD1		BAST_IOADDR(0x00800000)

#define BAST_PA_LCD_RDATA1		(0x9800000)
#define BAST_VA_LCD_RDATA1		BAST_IOADDR(0x00900000)

#define BAST_PA_LCD_WDATA1		(0x9000000)
#define BAST_VA_LCD_WDATA1		BAST_IOADDR(0x00A00000)

#define BAST_PA_LCD_RCMD2		(0xA800000)
#define BAST_VA_LCD_RCMD2		BAST_IOADDR(0x00B00000)

#define BAST_PA_LCD_WCMD2		(0xA000000)
#define BAST_VA_LCD_WCMD2		BAST_IOADDR(0x00C00000)

#define BAST_PA_LCD_RDATA2		(0xB800000)
#define BAST_VA_LCD_RDATA2		BAST_IOADDR(0x00D00000)

#define BAST_PA_LCD_WDATA2		(0xB000000)
#define BAST_VA_LCD_WDATA2		BAST_IOADDR(0x00E00000)

/*
 * 0xE0000000 contains the IO space that is split by speed and
 * whether the access is for 8 or 16bit IO... this ensures that
 * the correct access is made
 *
 * 0x10000000 of space, partitioned as so:
 *
 * 0x00000000 to 0x04000000  8bit,  slow
 * 0x04000000 to 0x08000000  16bit, slow
 * 0x08000000 to 0x0C000000  16bit, net
 * 0x0C000000 to 0x10000000  16bit, fast
 *
 * each of these spaces has the following in:
 *
 * 0x00000000 to 0x01000000 16MB ISA IO space
 * 0x01000000 to 0x02000000 16MB ISA memory space
 * 0x02000000 to 0x02100000 1MB  IDE primary channel
 * 0x02100000 to 0x02200000 1MB  IDE primary channel aux
 * 0x02200000 to 0x02400000 1MB  IDE secondary channel
 * 0x02300000 to 0x02400000 1MB  IDE secondary channel aux
 * 0x02400000 to 0x02500000 1MB  ASIX ethernet controller
 * 0x02500000 to 0x02600000 1MB  Davicom DM9000 ethernet controller
 * 0x02600000 to 0x02700000 1MB  PC SuperIO controller
 *
 * the phyiscal layout of the zones are:
 *  nGCS2 - 8bit, slow
 *  nGCS3 - 16bit, slow
 *  nGCS4 - 16bit, net
 *  nGCS5 - 16bit, fast
 */

#define BAST_VA_MULTISPACE		(0xE0000000)

#define BAST_VA_ISAIO			(BAST_VA_MULTISPACE + 0x00000000)
#define BAST_VA_ISAMEM			(BAST_VA_MULTISPACE + 0x01000000)
#define BAST_VA_IDEPRI			(BAST_VA_MULTISPACE + 0x02000000)
#define BAST_VA_IDEPRIAUX		(BAST_VA_MULTISPACE + 0x02100000)
#define BAST_VA_IDESEC			(BAST_VA_MULTISPACE + 0x02200000)
#define BAST_VA_IDESECAUX		(BAST_VA_MULTISPACE + 0x02300000)
#define BAST_VA_ASIXNET			(BAST_VA_MULTISPACE + 0x02400000)
#define BAST_VA_DM9000			(BAST_VA_MULTISPACE + 0x02500000)
#define BAST_VA_SUPERIO			(BAST_VA_MULTISPACE + 0x02600000)

#define BAST_VAM_CS2			(0x00000000)
#define BAST_VAM_CS3			(0x04000000)
#define BAST_VAM_CS4			(0x08000000)
#define BAST_VAM_CS5			(0x0C000000)

/* physical offset addresses for the peripherals */

#define BAST_PA_ISAIO			(0x00000000)
#define BAST_PA_ASIXNET			(0x01000000)
#define BAST_PA_SUPERIO			(0x01800000)
#define BAST_PA_IDEPRI			(0x02000000)
#define BAST_PA_IDEPRIAUX		(0x02800000)
#define BAST_PA_IDESEC			(0x03000000)
#define BAST_PA_IDESECAUX		(0x03800000)
#define BAST_PA_ISAMEM			(0x04000000)
#define BAST_PA_DM9000			(0x05000000)

/* some configurations for the peripherals */

#define BAST_PCSIO			(BAST_VA_SUPERIO + BAST_VAM_CS2)

#define BAST_ASIXNET_CS			BAST_VAM_CS5
#define BAST_DM9000_CS			BAST_VAM_CS4

#define BAST_IDE_CS	S3C2410_CS5

#endif /* __MACH_S3C24XX_BAST_H */


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2006 Simtec Electronics
//	Ben Dooks <ben@simtec.co.uk>
//
// Common code for SMDK2410 and SMDK2440 boards
//
// http://www.fluff.org/ben/smdk2440/

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/device.h>
#include <linux/platform_device.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand-ecc-sw-hamming.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>

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

#include <asm/mach-types.h>
#include <asm/irq.h>

#include "regs-gpio.h"
#include "gpio-samsung.h"
#include <linux/platform_data/leds-s3c24xx.h>
#include <linux/platform_data/mtd-nand-s3c2410.h>

#include "gpio-cfg.h"
#include "devs.h"
#include "pm.h"

#include "common-smdk-s3c24xx.h"

/* LED devices */

static struct gpiod_lookup_table smdk_led4_gpio_table = {
	.dev_id = "s3c24xx_led.0",
	.table = {
		GPIO_LOOKUP("GPF", 4, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN),
		{ },
	},
};

static struct gpiod_lookup_table smdk_led5_gpio_table = {
	.dev_id = "s3c24xx_led.1",
	.table = {
		GPIO_LOOKUP("GPF", 5, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN),
		{ },
	},
};

static struct gpiod_lookup_table smdk_led6_gpio_table = {
	.dev_id = "s3c24xx_led.2",
	.table = {
		GPIO_LOOKUP("GPF", 6, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN),
		{ },
	},
};

static struct gpiod_lookup_table smdk_led7_gpio_table = {
	.dev_id = "s3c24xx_led.3",
	.table = {
		GPIO_LOOKUP("GPF", 7, NULL, GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN),
		{ },
	},
};

static struct s3c24xx_led_platdata smdk_pdata_led4 = {
	.name		= "led4",
	.def_trigger	= "timer",
};

static struct s3c24xx_led_platdata smdk_pdata_led5 = {
	.name		= "led5",
	.def_trigger	= "nand-disk",
};

static struct s3c24xx_led_platdata smdk_pdata_led6 = {
	.name		= "led6",
};

static struct s3c24xx_led_platdata smdk_pdata_led7 = {
	.name		= "led7",
};

static struct platform_device smdk_led4 = {
	.name		= "s3c24xx_led",
	.id		= 0,
	.dev		= {
		.platform_data = &smdk_pdata_led4,
	},
};

static struct platform_device smdk_led5 = {
	.name		= "s3c24xx_led",
	.id		= 1,
	.dev		= {
		.platform_data = &smdk_pdata_led5,
	},
};

static struct platform_device smdk_led6 = {
	.name		= "s3c24xx_led",
	.id		= 2,
	.dev		= {
		.platform_data = &smdk_pdata_led6,
	},
};

static struct platform_device smdk_led7 = {
	.name		= "s3c24xx_led",
	.id		= 3,
	.dev		= {
		.platform_data = &smdk_pdata_led7,
	},
};

/* NAND parititon from 2.4.18-swl5 */

static struct mtd_partition smdk_default_nand_part[] = {
	[0] = {
		.name	= "Boot Agent",
		.size	= SZ_16K,
		.offset	= 0,
	},
	[1] = {
		.name	= "S3C2410 flash partition 1",
		.offset = 0,
		.size	= SZ_2M,
	},
	[2] = {
		.name	= "S3C2410 flash partition 2",
		.offset = SZ_4M,
		.size	= SZ_4M,
	},
	[3] = {
		.name	= "S3C2410 flash partition 3",
		.offset	= SZ_8M,
		.size	= SZ_2M,
	},
	[4] = {
		.name	= "S3C2410 flash partition 4",
		.offset = SZ_1M * 10,
		.size	= SZ_4M,
	},
	[5] = {
		.name	= "S3C2410 flash partition 5",
		.offset	= SZ_1M * 14,
		.size	= SZ_1M * 10,
	},
	[6] = {
		.name	= "S3C2410 flash partition 6",
		.offset	= SZ_1M * 24,
		.size	= SZ_1M * 24,
	},
	[7] = {
		.name	= "S3C2410 flash partition 7",
		.offset = SZ_1M * 48,
		.size	= MTDPART_SIZ_FULL,
	}
};

static struct s3c2410_nand_set smdk_nand_sets[] = {
	[0] = {
		.name		= "NAND",
		.nr_chips	= 1,
		.nr_partitions	= ARRAY_SIZE(smdk_default_nand_part),
		.partitions	= smdk_default_nand_part,
	},
};

/* choose a set of timings which should suit most 512Mbit
 * chips and beyond.
*/

static struct s3c2410_platform_nand smdk_nand_info = {
	.tacls		= 20,
	.twrph0		= 60,
	.twrph1		= 20,
	.nr_sets	= ARRAY_SIZE(smdk_nand_sets),
	.sets		= smdk_nand_sets,
	.engine_type	= NAND_ECC_ENGINE_TYPE_SOFT,
};

/* devices we initialise */

static struct platform_device __initdata *smdk_devs[] = {
	&s3c_device_nand,
	&smdk_led4,
	&smdk_led5,
	&smdk_led6,
	&smdk_led7,
};

void __init smdk_machine_init(void)
{
	if (machine_is_smdk2443())
		smdk_nand_info.twrph0 = 50;

	s3c_nand_set_platdata(&smdk_nand_info);

	/* Disable pull-up on the LED lines */
	s3c_gpio_setpull(S3C2410_GPF(4), S3C_GPIO_PULL_NONE);
	s3c_gpio_setpull(S3C2410_GPF(5), S3C_GPIO_PULL_NONE);
	s3c_gpio_setpull(S3C2410_GPF(6), S3C_GPIO_PULL_NONE);
	s3c_gpio_setpull(S3C2410_GPF(7), S3C_GPIO_PULL_NONE);

	/* Add lookups for the lines */
	gpiod_add_lookup_table(&smdk_led4_gpio_table);
	gpiod_add_lookup_table(&smdk_led5_gpio_table);
	gpiod_add_lookup_table(&smdk_led6_gpio_table);
	gpiod_add_lookup_table(&smdk_led7_gpio_table);

	platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));

	s3c_pm_init();
}


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2006 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * Common code for SMDK2410 and SMDK2440 boards
 *
 * http://www.fluff.org/ben/smdk2440/
 */

extern void smdk_machine_init(void);


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
//		http://www.samsung.com
//
// Samsung CPU Support

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>

#include "map-base.h"
#include "cpu.h"

unsigned long samsung_cpu_id;

void __init s3c64xx_init_cpu(void)
{
	samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0x118);
	if (!samsung_cpu_id) {
		/*
		 * S3C6400 has the ID register in a different place,
		 * and needs a write before it can be read.
		 */
		writel_relaxed(0x0, S3C_VA_SYS + 0xA1C);
		samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0xA1C);
	}

	pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
	pr_err("The platform is deprecated and scheduled for removal. Please reach to the maintainers of the platform and linux-samsung-soc@vger.kernel.org if you still use it.  Without such feedback, the platform will be removed after 2022.\n");
}


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com/
 *
 * Copyright (c) 2004-2005 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * Header file for Samsung CPU support
 */

/* todo - fix when rmk changes iodescs to use `void __iomem *` */

#ifndef __SAMSUNG_PLAT_CPU_H
#define __SAMSUNG_PLAT_CPU_H

extern unsigned long samsung_cpu_id;

#define S3C2410_CPU_ID		0x32410000
#define S3C2410_CPU_MASK	0xFFFFFFFF

#define S3C24XX_CPU_ID		0x32400000
#define S3C24XX_CPU_MASK	0xFFF00000

#define S3C2412_CPU_ID		0x32412000
#define S3C2412_CPU_MASK	0xFFFFF000

#define S3C6400_CPU_ID		0x36400000
#define S3C6410_CPU_ID		0x36410000
#define S3C64XX_CPU_MASK	0xFFFFF000

#define S5PV210_CPU_ID		0x43110000
#define S5PV210_CPU_MASK	0xFFFFF000

#define IS_SAMSUNG_CPU(name, id, mask)		\
static inline int is_samsung_##name(void)	\
{						\
	return ((samsung_cpu_id & mask) == (id & mask));	\
}

IS_SAMSUNG_CPU(s3c2410, S3C2410_CPU_ID, S3C2410_CPU_MASK)
IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK)
IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK)
IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK)

#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
    defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
    defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
    defined(CONFIG_CPU_S3C2443)
# define soc_is_s3c24xx()	is_samsung_s3c24xx()
# define soc_is_s3c2410()	is_samsung_s3c2410()
#else
# define soc_is_s3c24xx()	0
# define soc_is_s3c2410()	0
#endif

#if defined(CONFIG_CPU_S3C2412)
# define soc_is_s3c2412()	is_samsung_s3c2412()
#else
# define soc_is_s3c2412()	0
#endif

#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
# define soc_is_s3c6400()	is_samsung_s3c6400()
# define soc_is_s3c6410()	is_samsung_s3c6410()
# define soc_is_s3c64xx()	(is_samsung_s3c6400() || is_samsung_s3c6410())
#else
# define soc_is_s3c6400()	0
# define soc_is_s3c6410()	0
# define soc_is_s3c64xx()	0
#endif

#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }

#ifndef KHZ
#define KHZ (1000)
#endif

#ifndef MHZ
#define MHZ (1000*1000)
#endif

#define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000)

/* forward declaration */
struct s3c24xx_uart_resources;
struct platform_device;
struct s3c2410_uartcfg;
struct map_desc;

/* per-cpu initialisation function table. */

struct cpu_table {
	unsigned long	idcode;
	unsigned long	idmask;
	void		(*map_io)(void);
	void		(*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
	void		(*init_clocks)(int xtal);
	int		(*init)(void);
	const char	*name;
};

extern void s3c_init_cpu(unsigned long idcode,
			 struct cpu_table *cpus, unsigned int cputab_size);

/* core initialisation functions */

extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);

extern void s3c64xx_init_cpu(void);

extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);

extern void s3c24xx_init_clocks(int xtal);

extern void s3c24xx_init_uartdevs(char *name,
				  struct s3c24xx_uart_resources *res,
				  struct s3c2410_uartcfg *cfg, int no);

extern struct syscore_ops s3c2410_pm_syscore_ops;
extern struct syscore_ops s3c2412_pm_syscore_ops;
extern struct syscore_ops s3c2416_pm_syscore_ops;
extern struct syscore_ops s3c244x_pm_syscore_ops;

extern struct bus_type s3c6410_subsys;

#endif


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2009 Simtec Electronics
//	http://armlinux.simtec.co.uk/
//	Ben Dooks <ben@simtec.co.uk>
//
// S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/cpufreq.h>
#include <linux/io.h>
#include <linux/clk.h>

#include "map.h"
#include "regs-clock.h"

#include <linux/soc/samsung/s3c-cpufreq-core.h>

#include "regs-mem-s3c24xx.h"

/**
 * s3c2410_cpufreq_setrefresh - set SDRAM refresh value
 * @cfg: The frequency configuration
 *
 * Set the SDRAM refresh value appropriately for the configured
 * frequency.
 */
void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
{
	struct s3c_cpufreq_board *board = cfg->board;
	unsigned long refresh;
	unsigned long refval;

	/* Reduce both the refresh time (in ns) and the frequency (in MHz)
	 * down to ensure that we do not overflow 32 bit numbers.
	 *
	 * This should work for HCLK up to 133MHz and refresh period up
	 * to 30usec.
	 */

	refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
	refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale  */
	refresh = (1 << 11) + 1 - refresh;

	s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh);

	refval = __raw_readl(S3C2410_REFRESH);
	refval &= ~((1 << 12) - 1);
	refval |= refresh;
	__raw_writel(refval, S3C2410_REFRESH);
}

/**
 * s3c2410_set_fvco - set the PLL value
 * @cfg: The frequency configuration
 */
void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
{
	if (!IS_ERR(cfg->mpll))
		clk_set_rate(cfg->mpll, cfg->pll.frequency);
}

#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
u32 s3c2440_read_camdivn(void)
{
	return __raw_readl(S3C2440_CAMDIVN);
}

void s3c2440_write_camdivn(u32 camdiv)
{
	__raw_writel(camdiv, S3C2440_CAMDIVN);
}
#endif

u32 s3c24xx_read_clkdivn(void)
{
	return __raw_readl(S3C2410_CLKDIVN);
}

void s3c24xx_write_clkdivn(u32 clkdiv)
{
	__raw_writel(clkdiv, S3C2410_CLKDIVN);
}

u32 s3c24xx_read_mpllcon(void)
{
	return __raw_readl(S3C2410_MPLLCON);
}

void s3c24xx_write_locktime(u32 locktime)
{
	return __raw_writel(locktime, S3C2410_LOCKTIME);
}


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2011 Wolfson Microelectronics, plc
// Copyright (c) 2011 Samsung Electronics Co., Ltd.
//		http://www.samsung.com

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cpuidle.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/time.h>

#include <asm/cpuidle.h>

#include "cpu.h"
#include "map.h"

#include "regs-sys-s3c64xx.h"
#include "regs-syscon-power-s3c64xx.h"

static int s3c64xx_enter_idle(struct cpuidle_device *dev,
			      struct cpuidle_driver *drv,
			      int index)
{
	unsigned long tmp;

	/* Setup PWRCFG to enter idle mode */
	tmp = __raw_readl(S3C64XX_PWR_CFG);
	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
	tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
	__raw_writel(tmp, S3C64XX_PWR_CFG);

	cpu_do_idle();

	return index;
}

static struct cpuidle_driver s3c64xx_cpuidle_driver = {
	.name	= "s3c64xx_cpuidle",
	.owner  = THIS_MODULE,
	.states = {
		{
			.enter            = s3c64xx_enter_idle,
			.exit_latency     = 1,
			.target_residency = 1,
			.name             = "IDLE",
			.desc             = "System active, ARM gated",
		},
	},
	.state_count = 1,
};

static int __init s3c64xx_init_cpuidle(void)
{
	if (soc_is_s3c64xx())
		return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
	return 0;
}
device_initcall(s3c64xx_init_cpuidle);


code:
/* SPDX-License-Identifier: GPL-2.0 */
/* Cragganmore 6410 shared definitions
 *
 * Copyright 2011 Wolfson Microelectronics plc
 *	Mark Brown <broonie@opensource.wolfsonmicro.com>
 */

#ifndef MACH_CRAG6410_H
#define MACH_CRAG6410_H

#include "gpio-samsung.h"

#define GLENFARCLAS_PMIC_IRQ_BASE	IRQ_BOARD_START
#define BANFF_PMIC_IRQ_BASE		(IRQ_BOARD_START + 64)

#define PCA935X_GPIO_BASE		GPIO_BOARD_START
#define CODEC_GPIO_BASE			(GPIO_BOARD_START + 8)
#define GLENFARCLAS_PMIC_GPIO_BASE	(GPIO_BOARD_START + 32)
#define BANFF_PMIC_GPIO_BASE		(GPIO_BOARD_START + 64)
#define MMGPIO_GPIO_BASE		(GPIO_BOARD_START + 96)

#endif


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright 2009 Wolfson Microelectronics
//      Mark Brown <broonie@opensource.wolfsonmicro.com>

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/export.h>

#include "irqs.h"
#include "map.h"

#include "devs.h"
#include <linux/platform_data/asoc-s3c.h>
#include "gpio-cfg.h"
#include "gpio-samsung.h"

static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
{
	unsigned int base;

	switch (pdev->id) {
	case 0:
		base = S3C64XX_GPD(0);
		break;
	case 1:
		base = S3C64XX_GPE(0);
		break;
	case 2:
		s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
		s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
		s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
		s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
		return 0;
	default:
		printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
			pdev->id);
		return -EINVAL;
	}

	s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));

	return 0;
}

static struct resource s3c64xx_iis0_resource[] = {
	[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
};

static struct s3c_audio_pdata i2s0_pdata = {
	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
};

struct platform_device s3c64xx_device_iis0 = {
	.name		  = "samsung-i2s",
	.id		  = 0,
	.num_resources	  = ARRAY_SIZE(s3c64xx_iis0_resource),
	.resource	  = s3c64xx_iis0_resource,
	.dev = {
		.platform_data = &i2s0_pdata,
	},
};
EXPORT_SYMBOL(s3c64xx_device_iis0);

static struct resource s3c64xx_iis1_resource[] = {
	[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
};

static struct s3c_audio_pdata i2s1_pdata = {
	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
};

struct platform_device s3c64xx_device_iis1 = {
	.name		  = "samsung-i2s",
	.id		  = 1,
	.num_resources	  = ARRAY_SIZE(s3c64xx_iis1_resource),
	.resource	  = s3c64xx_iis1_resource,
	.dev = {
		.platform_data = &i2s1_pdata,
	},
};
EXPORT_SYMBOL(s3c64xx_device_iis1);

static struct resource s3c64xx_iisv4_resource[] = {
	[0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
};

static struct s3c_audio_pdata i2sv4_pdata = {
	.cfg_gpio = s3c64xx_i2s_cfg_gpio,
	.type = {
		.quirks = QUIRK_PRI_6CHAN,
	},
};

struct platform_device s3c64xx_device_iisv4 = {
	.name = "samsung-i2s",
	.id = 2,
	.num_resources	  = ARRAY_SIZE(s3c64xx_iisv4_resource),
	.resource	  = s3c64xx_iisv4_resource,
	.dev = {
		.platform_data = &i2sv4_pdata,
	},
};
EXPORT_SYMBOL(s3c64xx_device_iisv4);

/* PCM Controller platform_devices */

static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
{
	unsigned int base;

	switch (pdev->id) {
	case 0:
		base = S3C64XX_GPD(0);
		break;
	case 1:
		base = S3C64XX_GPE(0);
		break;
	default:
		printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
			pdev->id);
		return -EINVAL;
	}

	s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
	return 0;
}

static struct resource s3c64xx_pcm0_resource[] = {
	[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
};

static struct s3c_audio_pdata s3c_pcm0_pdata = {
	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
};

struct platform_device s3c64xx_device_pcm0 = {
	.name		  = "samsung-pcm",
	.id		  = 0,
	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm0_resource),
	.resource	  = s3c64xx_pcm0_resource,
	.dev = {
		.platform_data = &s3c_pcm0_pdata,
	},
};
EXPORT_SYMBOL(s3c64xx_device_pcm0);

static struct resource s3c64xx_pcm1_resource[] = {
	[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
};

static struct s3c_audio_pdata s3c_pcm1_pdata = {
	.cfg_gpio = s3c64xx_pcm_cfg_gpio,
};

struct platform_device s3c64xx_device_pcm1 = {
	.name		  = "samsung-pcm",
	.id		  = 1,
	.num_resources	  = ARRAY_SIZE(s3c64xx_pcm1_resource),
	.resource	  = s3c64xx_pcm1_resource,
	.dev = {
		.platform_data = &s3c_pcm1_pdata,
	},
};
EXPORT_SYMBOL(s3c64xx_device_pcm1);

/* AC97 Controller platform devices */

static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
{
	return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
}

static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
{
	return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
}

static struct resource s3c64xx_ac97_resource[] = {
	[0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
	[1] = DEFINE_RES_IRQ(IRQ_AC97),
};

static struct s3c_audio_pdata s3c_ac97_pdata = {
};

static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);

struct platform_device s3c64xx_device_ac97 = {
	.name		  = "samsung-ac97",
	.id		  = -1,
	.num_resources	  = ARRAY_SIZE(s3c64xx_ac97_resource),
	.resource	  = s3c64xx_ac97_resource,
	.dev = {
		.platform_data = &s3c_ac97_pdata,
		.dma_mask = &s3c64xx_ac97_dmamask,
		.coherent_dma_mask = DMA_BIT_MASK(32),
	},
};
EXPORT_SYMBOL(s3c64xx_device_ac97);

void __init s3c64xx_ac97_setup_gpio(int num)
{
	if (num == S3C64XX_AC97_GPD)
		s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
	else
		s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
}