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

#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/serial_core.h>
#include <linux/serial_s3c.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/io.h>

#include <asm/mach-types.h>

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

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

#include "devs.h"
#include "cpu.h"
#include <linux/platform_data/i2c-s3c2410.h>
#include "gpio-samsung.h"

#include "s3c64xx.h"

#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE

static struct s3c2410_uartcfg smdk6400_uartcfgs[] __initdata = {
	[0] = {
		.hwport	     = 0,
		.flags	     = 0,
		.ucon	     = 0x3c5,
		.ulcon	     = 0x03,
		.ufcon	     = 0x51,
	},
	[1] = {
		.hwport	     = 1,
		.flags	     = 0,
		.ucon	     = 0x3c5,
		.ulcon	     = 0x03,
		.ufcon	     = 0x51,
	},
};

static struct map_desc smdk6400_iodesc[] = {};

static void __init smdk6400_map_io(void)
{
	s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
	s3c64xx_set_xtal_freq(12000000);
	s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
	s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4);
}

static struct platform_device *smdk6400_devices[] __initdata = {
	&s3c_device_hsmmc1,
	&s3c_device_i2c0,
};

static struct i2c_board_info i2c_devs[] __initdata = {
	{ I2C_BOARD_INFO("wm8753", 0x1A), },
	{ I2C_BOARD_INFO("24c08", 0x50), },
};

static void __init smdk6400_machine_init(void)
{
	i2c_register_board_info(0, i2c_devs, ARRAY_SIZE(i2c_devs));
	platform_add_devices(smdk6400_devices, ARRAY_SIZE(smdk6400_devices));
}

MACHINE_START(SMDK6400, "SMDK6400")
	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
	.atag_offset	= 0x100,
	.nr_irqs	= S3C64XX_NR_IRQS,
	.init_irq	= s3c6400_init_irq,
	.map_io		= smdk6400_map_io,
	.init_machine	= smdk6400_machine_init,
	.init_time	= s3c64xx_timer_init,
MACHINE_END


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

#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/input.h>
#include <linux/serial_core.h>
#include <linux/serial_s3c.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/leds.h>
#include <linux/fb.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/smsc911x.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/platform_data/s3c-hsotg.h>

#ifdef CONFIG_SMDK6410_WM1190_EV1
#include <linux/mfd/wm8350/core.h>
#include <linux/mfd/wm8350/pmic.h>
#endif

#ifdef CONFIG_SMDK6410_WM1192_EV1
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/pdata.h>
#endif

#include <video/platform_lcd.h>
#include <video/samsung_fimd.h>

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

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

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

#include "regs-gpio.h"
#include "gpio-samsung.h"
#include <linux/platform_data/ata-samsung_cf.h>
#include <linux/platform_data/i2c-s3c2410.h>
#include "fb.h"
#include "gpio-cfg.h"

#include "devs.h"
#include "cpu.h"
#include <linux/soc/samsung/s3c-adc.h>
#include <linux/platform_data/touchscreen-s3c2410.h>
#include "keypad.h"

#include "backlight-s3c64xx.h"
#include "s3c64xx.h"
#include "regs-modem-s3c64xx.h"
#include "regs-srom-s3c64xx.h"
#include "regs-sys-s3c64xx.h"

#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE

static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
	[0] = {
		.hwport	     = 0,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
	[1] = {
		.hwport	     = 1,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
	[2] = {
		.hwport	     = 2,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
	[3] = {
		.hwport	     = 3,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
};

/* framebuffer and LCD setup. */

/* GPF15 = LCD backlight control
 * GPF13 => Panel power
 * GPN5 = LCD nRESET signal
 * PWM_TOUT1 => backlight brightness
 */

static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
				   unsigned int power)
{
	if (power) {
		gpio_direction_output(S3C64XX_GPF(13), 1);

		/* fire nRESET on power up */
		gpio_direction_output(S3C64XX_GPN(5), 0);
		msleep(10);
		gpio_direction_output(S3C64XX_GPN(5), 1);
		msleep(1);
	} else {
		gpio_direction_output(S3C64XX_GPF(13), 0);
	}
}

static struct plat_lcd_data smdk6410_lcd_power_data = {
	.set_power	= smdk6410_lcd_power_set,
};

static struct platform_device smdk6410_lcd_powerdev = {
	.name			= "platform-lcd",
	.dev.parent		= &s3c_device_fb.dev,
	.dev.platform_data	= &smdk6410_lcd_power_data,
};

static struct s3c_fb_pd_win smdk6410_fb_win0 = {
	.max_bpp	= 32,
	.default_bpp	= 16,
	.xres		= 800,
	.yres		= 480,
	.virtual_y	= 480 * 2,
	.virtual_x	= 800,
};

static struct fb_videomode smdk6410_lcd_timing = {
	.left_margin	= 8,
	.right_margin	= 13,
	.upper_margin	= 7,
	.lower_margin	= 5,
	.hsync_len	= 3,
	.vsync_len	= 1,
	.xres		= 800,
	.yres		= 480,
};

/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = {
	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
	.vtiming	= &smdk6410_lcd_timing,
	.win[0]		= &smdk6410_fb_win0,
	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
};

/*
 * Configuring Ethernet on SMDK6410
 *
 * Both CS8900A and LAN9115 chips share one chip select mediated by CFG6.
 * The constant address below corresponds to nCS1
 *
 *  1) Set CFGB2 p3 ON others off, no other CFGB selects "ethernet"
 *  2) CFG6 needs to be switched to "LAN9115" side
 */

static struct resource smdk6410_smsc911x_resources[] = {
	[0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, SZ_64K),
	[1] = DEFINE_RES_NAMED(S3C_EINT(10), 1, NULL, IORESOURCE_IRQ \
					| IRQ_TYPE_LEVEL_LOW),
};

static struct smsc911x_platform_config smdk6410_smsc911x_pdata = {
	.irq_polarity  = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
	.irq_type      = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
	.flags         = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
	.phy_interface = PHY_INTERFACE_MODE_MII,
};

static struct platform_device smdk6410_smsc911x = {
	.name          = "smsc911x",
	.id            = -1,
	.num_resources = ARRAY_SIZE(smdk6410_smsc911x_resources),
	.resource      = &smdk6410_smsc911x_resources[0],
	.dev = {
		.platform_data = &smdk6410_smsc911x_pdata,
	},
};

#ifdef CONFIG_REGULATOR
static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
	REGULATOR_SUPPLY("PVDD", "0-001b"),
	REGULATOR_SUPPLY("AVDD", "0-001b"),
};

static struct regulator_init_data __maybe_unused smdk6410_b_pwr_5v_data = {
	.constraints = {
		.always_on = 1,
	},
	.num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
	.consumer_supplies = smdk6410_b_pwr_5v_consumers,
};

static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
	.supply_name = "B_PWR_5V",
	.microvolts = 5000000,
	.init_data = &smdk6410_b_pwr_5v_data,
};

static struct platform_device smdk6410_b_pwr_5v = {
	.name          = "reg-fixed-voltage",
	.id            = -1,
	.dev = {
		.platform_data = &smdk6410_b_pwr_5v_pdata,
	},
};
#endif

static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = {
	.setup_gpio	= s3c64xx_ide_setup_gpio,
};

static uint32_t smdk6410_keymap[] __initdata = {
	/* KEY(row, col, keycode) */
	KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
	KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
	KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
	KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
};

static struct matrix_keymap_data smdk6410_keymap_data __initdata = {
	.keymap		= smdk6410_keymap,
	.keymap_size	= ARRAY_SIZE(smdk6410_keymap),
};

static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
	.keymap_data	= &smdk6410_keymap_data,
	.rows		= 2,
	.cols		= 8,
};

static struct map_desc smdk6410_iodesc[] = {};

static struct platform_device *smdk6410_devices[] __initdata = {
#ifdef CONFIG_SMDK6410_SD_CH0
	&s3c_device_hsmmc0,
#endif
#ifdef CONFIG_SMDK6410_SD_CH1
	&s3c_device_hsmmc1,
#endif
	&s3c_device_i2c0,
	&s3c_device_i2c1,
	&s3c_device_fb,
	&s3c_device_ohci,
	&samsung_device_pwm,
	&s3c_device_usb_hsotg,
	&s3c64xx_device_iisv4,
	&samsung_device_keypad,

#ifdef CONFIG_REGULATOR
	&smdk6410_b_pwr_5v,
#endif
	&smdk6410_lcd_powerdev,

	&smdk6410_smsc911x,
	&s3c_device_adc,
	&s3c_device_cfcon,
	&s3c_device_rtc,
	&s3c_device_wdt,
};

#ifdef CONFIG_REGULATOR
/* ARM core */
static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = {
	REGULATOR_SUPPLY("vddarm", NULL),
};

/* VDDARM, BUCK1 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddarm = {
	.constraints = {
		.name = "PVDD_ARM",
		.min_uV = 1000000,
		.max_uV = 1300000,
		.always_on = 1,
		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies = ARRAY_SIZE(smdk6410_vddarm_consumers),
	.consumer_supplies = smdk6410_vddarm_consumers,
};

/* VDD_INT, BUCK2 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddint = {
	.constraints = {
		.name = "PVDD_INT",
		.min_uV = 1000000,
		.max_uV = 1200000,
		.always_on = 1,
		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
	},
};

/* VDD_HI, LDO3 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddhi = {
	.constraints = {
		.name = "PVDD_HI",
		.always_on = 1,
	},
};

/* VDD_PLL, LDO2 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddpll = {
	.constraints = {
		.name = "PVDD_PLL",
		.always_on = 1,
	},
};

/* VDD_UH_MMC, LDO5 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vdduh_mmc = {
	.constraints = {
		.name = "PVDD_UH+PVDD_MMC",
		.always_on = 1,
	},
};

/* VCCM3BT, LDO8 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vccmc3bt = {
	.constraints = {
		.name = "PVCCM3BT",
		.always_on = 1,
	},
};

/* VCCM2MTV, LDO11 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vccm2mtv = {
	.constraints = {
		.name = "PVCCM2MTV",
		.always_on = 1,
	},
};

/* VDD_LCD, LDO12 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddlcd = {
	.constraints = {
		.name = "PVDD_LCD",
		.always_on = 1,
	},
};

/* VDD_OTGI, LDO9 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddotgi = {
	.constraints = {
		.name = "PVDD_OTGI",
		.always_on = 1,
	},
};

/* VDD_OTG, LDO14 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddotg = {
	.constraints = {
		.name = "PVDD_OTG",
		.always_on = 1,
	},
};

/* VDD_ALIVE, LDO15 on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddalive = {
	.constraints = {
		.name = "PVDD_ALIVE",
		.always_on = 1,
	},
};

/* VDD_AUDIO, VLDO_AUDIO on J5 */
static struct regulator_init_data __maybe_unused smdk6410_vddaudio = {
	.constraints = {
		.name = "PVDD_AUDIO",
		.always_on = 1,
	},
};
#endif

#ifdef CONFIG_SMDK6410_WM1190_EV1
/* S3C64xx internal logic & PLL */
static struct regulator_init_data __maybe_unused wm8350_dcdc1_data = {
	.constraints = {
		.name = "PVDD_INT+PVDD_PLL",
		.min_uV = 1200000,
		.max_uV = 1200000,
		.always_on = 1,
		.apply_uV = 1,
	},
};

/* Memory */
static struct regulator_init_data __maybe_unused wm8350_dcdc3_data = {
	.constraints = {
		.name = "PVDD_MEM",
		.min_uV = 1800000,
		.max_uV = 1800000,
		.always_on = 1,
		.state_mem = {
			 .uV = 1800000,
			 .mode = REGULATOR_MODE_NORMAL,
			 .enabled = 1,
		},
		.initial_state = PM_SUSPEND_MEM,
	},
};

/* USB, EXT, PCM, ADC/DAC, USB, MMC */
static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
	REGULATOR_SUPPLY("DVDD", "0-001b"),
};

static struct regulator_init_data __maybe_unused wm8350_dcdc4_data = {
	.constraints = {
		.name = "PVDD_HI+PVDD_EXT+PVDD_SYS+PVCCM2MTV",
		.min_uV = 3000000,
		.max_uV = 3000000,
		.always_on = 1,
	},
	.num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
	.consumer_supplies = wm8350_dcdc4_consumers,
};

/* OTGi/1190-EV1 HPVDD & AVDD */
static struct regulator_init_data __maybe_unused wm8350_ldo4_data = {
	.constraints = {
		.name = "PVDD_OTGI+HPVDD+AVDD",
		.min_uV = 1200000,
		.max_uV = 1200000,
		.apply_uV = 1,
		.always_on = 1,
	},
};

static struct {
	int regulator;
	struct regulator_init_data *initdata;
} wm1190_regulators[] = {
	{ WM8350_DCDC_1, &wm8350_dcdc1_data },
	{ WM8350_DCDC_3, &wm8350_dcdc3_data },
	{ WM8350_DCDC_4, &wm8350_dcdc4_data },
	{ WM8350_DCDC_6, &smdk6410_vddarm },
	{ WM8350_LDO_1, &smdk6410_vddalive },
	{ WM8350_LDO_2, &smdk6410_vddotg },
	{ WM8350_LDO_3, &smdk6410_vddlcd },
	{ WM8350_LDO_4, &wm8350_ldo4_data },
};

static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
{
	int i;

	/* Configure the IRQ line */
	s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);

	/* Instantiate the regulators */
	for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
		wm8350_register_regulator(wm8350,
					  wm1190_regulators[i].regulator,
					  wm1190_regulators[i].initdata);

	return 0;
}

static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = {
	.init = smdk6410_wm8350_init,
	.irq_high = 1,
	.irq_base = IRQ_BOARD_START,
};
#endif

#ifdef CONFIG_SMDK6410_WM1192_EV1
static struct gpio_led wm1192_pmic_leds[] = {
	{
		.name = "PMIC:red:power",
		.gpio = GPIO_BOARD_START + 3,
		.default_state = LEDS_GPIO_DEFSTATE_ON,
	},
};

static struct gpio_led_platform_data wm1192_pmic_led = {
	.num_leds = ARRAY_SIZE(wm1192_pmic_leds),
	.leds = wm1192_pmic_leds,
};

static struct platform_device wm1192_pmic_led_dev = {
	.name          = "leds-gpio",
	.id            = -1,
	.dev = {
		.platform_data = &wm1192_pmic_led,
	},
};

static int wm1192_pre_init(struct wm831x *wm831x)
{
	int ret;

	/* Configure the IRQ line */
	s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);

	ret = platform_device_register(&wm1192_pmic_led_dev);
	if (ret != 0)
		dev_err(wm831x->dev, "Failed to add PMIC LED: %d\n", ret);

	return 0;
}

static struct wm831x_backlight_pdata wm1192_backlight_pdata = {
	.isink = 1,
	.max_uA = 27554,
};

static struct regulator_init_data __maybe_unused wm1192_dcdc3 = {
	.constraints = {
		.name = "PVDD_MEM+PVDD_GPS",
		.always_on = 1,
	},
};

static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
	REGULATOR_SUPPLY("DVDD", "0-001b"),   /* WM8580 */
};

static struct regulator_init_data __maybe_unused wm1192_ldo1 = {
	.constraints = {
		.name = "PVDD_LCD+PVDD_EXT",
		.always_on = 1,
	},
	.consumer_supplies = wm1192_ldo1_consumers,
	.num_consumer_supplies = ARRAY_SIZE(wm1192_ldo1_consumers),
};

static struct wm831x_status_pdata wm1192_led7_pdata = {
	.name = "LED7:green:",
};

static struct wm831x_status_pdata wm1192_led8_pdata = {
	.name = "LED8:green:",
};

static struct wm831x_pdata smdk6410_wm1192_pdata = {
	.pre_init = wm1192_pre_init,

	.backlight = &wm1192_backlight_pdata,
	.dcdc = {
		&smdk6410_vddarm,  /* DCDC1 */
		&smdk6410_vddint,  /* DCDC2 */
		&wm1192_dcdc3,
	},
	.gpio_base = GPIO_BOARD_START,
	.ldo = {
		 &wm1192_ldo1,        /* LDO1 */
		 &smdk6410_vdduh_mmc, /* LDO2 */
		 NULL,                /* LDO3 NC */
		 &smdk6410_vddotgi,   /* LDO4 */
		 &smdk6410_vddotg,    /* LDO5 */
		 &smdk6410_vddhi,     /* LDO6 */
		 &smdk6410_vddaudio,  /* LDO7 */
		 &smdk6410_vccm2mtv,  /* LDO8 */
		 &smdk6410_vddpll,    /* LDO9 */
		 &smdk6410_vccmc3bt,  /* LDO10 */
		 &smdk6410_vddalive,  /* LDO11 */
	},
	.status = {
		&wm1192_led7_pdata,
		&wm1192_led8_pdata,
	},
};
#endif

static struct i2c_board_info i2c_devs0[] __initdata = {
	{ I2C_BOARD_INFO("24c08", 0x50), },
	{ I2C_BOARD_INFO("wm8580", 0x1b), },

#ifdef CONFIG_SMDK6410_WM1192_EV1
	{ I2C_BOARD_INFO("wm8312", 0x34),
	  .platform_data = &smdk6410_wm1192_pdata,
	  .irq = S3C_EINT(12),
	},
#endif

#ifdef CONFIG_SMDK6410_WM1190_EV1
	{ I2C_BOARD_INFO("wm8350", 0x1a),
	  .platform_data = &smdk6410_wm8350_pdata,
	  .irq = S3C_EINT(12),
	},
#endif
};

static struct i2c_board_info i2c_devs1[] __initdata = {
	{ I2C_BOARD_INFO("24c128", 0x57), },	/* Samsung S524AD0XD1 */
};

/* LCD Backlight data */
static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
	.no = S3C64XX_GPF(15),
	.func = S3C_GPIO_SFN(2),
};

static struct pwm_lookup smdk6410_pwm_lookup[] = {
	PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL, 78770,
		   PWM_POLARITY_NORMAL),
};

static struct platform_pwm_backlight_data smdk6410_bl_data = {
	/* Intentionally blank */
};

static struct dwc2_hsotg_plat smdk6410_hsotg_pdata;

static void __init smdk6410_map_io(void)
{
	u32 tmp;

	s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
	s3c64xx_set_xtal_freq(12000000);
	s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
	s3c64xx_set_timer_source(S3C64XX_PWM3, S3C64XX_PWM4);

	/* set the LCD type */

	tmp = __raw_readl(S3C64XX_SPCON);
	tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
	tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
	__raw_writel(tmp, S3C64XX_SPCON);

	/* remove the lcd bypass */
	tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
	tmp &= ~MIFPCON_LCD_BYPASS;
	__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
}

static void __init smdk6410_machine_init(void)
{
	u32 cs1;

	s3c_i2c0_set_platdata(NULL);
	s3c_i2c1_set_platdata(NULL);
	s3c_fb_set_platdata(&smdk6410_lcd_pdata);
	dwc2_hsotg_set_platdata(&smdk6410_hsotg_pdata);

	samsung_keypad_set_platdata(&smdk6410_keypad_data);

	s3c64xx_ts_set_platdata(NULL);

	/* configure nCS1 width to 16 bits */

	cs1 = __raw_readl(S3C64XX_SROM_BW) &
		    ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
	cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
		(1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
		(1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
						   S3C64XX_SROM_BW__NCS1__SHIFT;
	__raw_writel(cs1, S3C64XX_SROM_BW);

	/* set timing for nCS1 suitable for ethernet chip */

	__raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
		     (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
		     (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
		     (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
		     (0xe << S3C64XX_SROM_BCX__TACC__SHIFT) |
		     (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
		     (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);

	gpio_request(S3C64XX_GPN(5), "LCD power");
	gpio_request(S3C64XX_GPF(13), "LCD power");

	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));

	s3c_ide_set_platdata(&smdk6410_ide_pdata);

	platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));

	pwm_add_table(smdk6410_pwm_lookup, ARRAY_SIZE(smdk6410_pwm_lookup));
	samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
}

MACHINE_START(SMDK6410, "SMDK6410")
	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
	.atag_offset	= 0x100,
	.nr_irqs	= S3C64XX_NR_IRQS,
	.init_irq	= s3c6410_init_irq,
	.map_io		= smdk6410_map_io,
	.init_machine	= smdk6410_machine_init,
	.init_time	= s3c64xx_timer_init,
MACHINE_END

repo_name: angery/linux


code:
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2007 TinCanTools
//	David Anders <danders@amltd.com>
//
// @History:
// derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
// Ben Dooks <ben@simtec.co.uk>

#include <linux/gpio/machine.h>
#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/device.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_s3c.h>
#include <linux/io.h>

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

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

#include <linux/platform_data/i2c-s3c2410.h>
#include "devs.h"
#include "cpu.h"

#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/map.h>
#include <linux/mtd/physmap.h>

#include "s3c24xx.h"

static struct resource tct_hammer_nor_resource =
			DEFINE_RES_MEM(0x00000000, SZ_16M);

static struct mtd_partition tct_hammer_mtd_partitions[] = {
	{
		.name		= "System",
		.size		= 0x240000,
		.offset		= 0,
		.mask_flags 	= MTD_WRITEABLE,  /* force read-only */
	}, {
		.name		= "JFFS2",
		.size		= MTDPART_SIZ_FULL,
		.offset		= MTDPART_OFS_APPEND,
	}
};

static struct physmap_flash_data tct_hammer_flash_data = {
	.width		= 2,
	.parts		= tct_hammer_mtd_partitions,
	.nr_parts	= ARRAY_SIZE(tct_hammer_mtd_partitions),
};

static struct platform_device tct_hammer_device_nor = {
	.name		= "physmap-flash",
	.id		= 0,
	.dev = {
			.platform_data = &tct_hammer_flash_data,
		},
	.num_resources	= 1,
	.resource	= &tct_hammer_nor_resource,
};

static struct map_desc tct_hammer_iodesc[] __initdata = {
};

#define UCON S3C2410_UCON_DEFAULT
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE

static struct s3c2410_uartcfg tct_hammer_uartcfgs[] = {
	[0] = {
		.hwport	     = 0,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
	[1] = {
		.hwport	     = 1,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
	[2] = {
		.hwport	     = 2,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	}
};

static struct gpiod_lookup_table tct_hammer_mmc_gpio_table = {
	.dev_id = "s3c2410-sdi",
	.table = {
		/* bus pins */
		GPIO_LOOKUP_IDX("GPIOE",  5, "bus", 0, GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP_IDX("GPIOE",  6, "bus", 1, GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP_IDX("GPIOE",  7, "bus", 2, GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP_IDX("GPIOE",  8, "bus", 3, GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP_IDX("GPIOE",  9, "bus", 4, GPIO_ACTIVE_HIGH),
		GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct platform_device *tct_hammer_devices[] __initdata = {
	&s3c_device_adc,
	&s3c_device_wdt,
	&s3c_device_i2c0,
	&s3c_device_ohci,
	&s3c_device_rtc,
	&s3c_device_usbgadget,
	&s3c_device_sdi,
	&tct_hammer_device_nor,
};

static void __init tct_hammer_map_io(void)
{
	s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc));
	s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
	s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
}

static void __init tct_hammer_init_time(void)
{
	s3c2410_init_clocks(12000000);
	s3c24xx_timer_init();
}

static void __init tct_hammer_init(void)
{
	s3c_i2c0_set_platdata(NULL);
	gpiod_add_lookup_table(&tct_hammer_mmc_gpio_table);
	platform_add_devices(tct_hammer_devices, ARRAY_SIZE(tct_hammer_devices));
}

MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
	.atag_offset	= 0x100,
	.nr_irqs	= NR_IRQS_S3C2410,
	.map_io		= tct_hammer_map_io,
	.init_irq	= s3c2410_init_irq,
	.init_machine	= tct_hammer_init,
	.init_time	= tct_hammer_init_time,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2003-2008 Simtec Electronics
//   Ben Dooks <ben@simtec.co.uk>
//
// Machine support for Thorcom VR1000 board. Designed for Thorcom by
// Simtec Electronics, http://www.simtec.co.uk/

#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/dm9000.h>
#include <linux/i2c.h>

#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/serial_s3c.h>
#include <linux/io.h>

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

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

#include <linux/platform_data/leds-s3c24xx.h>
#include <linux/platform_data/i2c-s3c2410.h>
#include <linux/platform_data/asoc-s3c24xx_simtec.h>

#include "regs-gpio.h"
#include "gpio-samsung.h"
#include "gpio-cfg.h"

#include "cpu.h"
#include "devs.h"

#include "bast.h"
#include "s3c24xx.h"
#include "simtec.h"
#include "vr1000.h"

/* macros for virtual address mods for the io space entries */
#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)

/* macros to modify the physical addresses for io space */

#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))

static struct map_desc vr1000_iodesc[] __initdata = {
  /* ISA IO areas */
  {
	  .virtual	= (u32)S3C24XX_VA_ISA_BYTE,
	  .pfn		= PA_CS2(BAST_PA_ISAIO),
	  .length	= SZ_16M,
	  .type		= MT_DEVICE,
  },

  /*  CPLD control registers, and external interrupt controls */
  {
	  .virtual	= (u32)VR1000_VA_CTRL1,
	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL1),
	  .length	= SZ_1M,
	  .type		= MT_DEVICE,
  }, {
	  .virtual	= (u32)VR1000_VA_CTRL2,
	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL2),
	  .length	= SZ_1M,
	  .type		= MT_DEVICE,
  }, {
	  .virtual	= (u32)VR1000_VA_CTRL3,
	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL3),
	  .length	= SZ_1M,
	  .type		= MT_DEVICE,
  }, {
	  .virtual	= (u32)VR1000_VA_CTRL4,
	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL4),
	  .length	= SZ_1M,
	  .type		= MT_DEVICE,
  },
};

#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE

static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
	[0] = {
		.hwport	     = 0,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
	[1] = {
		.hwport	     = 1,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	},
	/* port 2 is not actually used */
	[2] = {
		.hwport	     = 2,
		.flags	     = 0,
		.ucon	     = UCON,
		.ulcon	     = ULCON,
		.ufcon	     = UFCON,
	}
};

/* definitions for the vr1000 extra 16550 serial ports */

#define VR1000_BAUDBASE (3692307)

#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))

static struct plat_serial8250_port serial_platform_data[] = {
	[0] = {
		.mapbase	= VR1000_SERIAL_MAPBASE(0),
		.irq		= VR1000_IRQ_SERIAL + 0,
		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
		.iotype		= UPIO_MEM,
		.regshift	= 0,
		.uartclk	= VR1000_BAUDBASE,
	},
	[1] = {
		.mapbase	= VR1000_SERIAL_MAPBASE(1),
		.irq		= VR1000_IRQ_SERIAL + 1,
		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
		.iotype		= UPIO_MEM,
		.regshift	= 0,
		.uartclk	= VR1000_BAUDBASE,
	},
	[2] = {
		.mapbase	= VR1000_SERIAL_MAPBASE(2),
		.irq		= VR1000_IRQ_SERIAL + 2,
		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
		.iotype		= UPIO_MEM,
		.regshift	= 0,
		.uartclk	= VR1000_BAUDBASE,
	},
	[3] = {
		.mapbase	= VR1000_SERIAL_MAPBASE(3),
		.irq		= VR1000_IRQ_SERIAL + 3,
		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
		.iotype		= UPIO_MEM,
		.regshift	= 0,
		.uartclk	= VR1000_BAUDBASE,
	},
	{ },
};

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

/* DM9000 ethernet devices */

static struct resource vr1000_dm9k0_resource[] = {
	[0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000, 4),
	[1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x40, 0x40),
	[2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000A, 1, NULL, IORESOURCE_IRQ \
						| IORESOURCE_IRQ_HIGHLEVEL),
};

static struct resource vr1000_dm9k1_resource[] = {
	[0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x80, 4),
	[1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0, 0x40),
	[2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000N, 1, NULL, IORESOURCE_IRQ \
						| IORESOURCE_IRQ_HIGHLEVEL),
};

/* for the moment we limit ourselves to 16bit IO until some
 * better IO routines can be written and tested
*/

static struct dm9000_plat_data vr1000_dm9k_platdata = {
	.flags		= DM9000_PLATF_16BITONLY,
};

static struct platform_device vr1000_dm9k0 = {
	.name		= "dm9000",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(vr1000_dm9k0_resource),
	.resource	= vr1000_dm9k0_resource,
	.dev		= {
		.platform_data = &vr1000_dm9k_platdata,
	}
};

static struct platform_device vr1000_dm9k1 = {
	.name		= "dm9000",
	.id		= 1,
	.num_resources	= ARRAY_SIZE(vr1000_dm9k1_resource),
	.resource	= vr1000_dm9k1_resource,
	.dev		= {
		.platform_data = &vr1000_dm9k_platdata,
	}
};

/* LEDS */

static struct gpiod_lookup_table vr1000_led1_gpio_table = {
	.dev_id = "s3c24xx_led.1",
	.table = {
		GPIO_LOOKUP("GPB", 0, NULL, GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct gpiod_lookup_table vr1000_led2_gpio_table = {
	.dev_id = "s3c24xx_led.2",
	.table = {
		GPIO_LOOKUP("GPB", 1, NULL, GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct gpiod_lookup_table vr1000_led3_gpio_table = {
	.dev_id = "s3c24xx_led.3",
	.table = {
		GPIO_LOOKUP("GPB", 2, NULL, GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct s3c24xx_led_platdata vr1000_led1_pdata = {
	.name		= "led1",
	.def_trigger	= "",
};

static struct s3c24xx_led_platdata vr1000_led2_pdata = {
	.name		= "led2",
	.def_trigger	= "",
};

static struct s3c24xx_led_platdata vr1000_led3_pdata = {
	.name		= "led3",
	.def_trigger	= "",
};

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

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

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

/* I2C devices. */

static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
	{
		I2C_BOARD_INFO("tlv320aic23", 0x1a),
	}, {
		I2C_BOARD_INFO("tmp101", 0x48),
	}, {
		I2C_BOARD_INFO("m41st87", 0x68),
	},
};

/* devices for this board */

static struct platform_device *vr1000_devices[] __initdata = {
	&s3c2410_device_dclk,
	&s3c_device_ohci,
	&s3c_device_lcd,
	&s3c_device_wdt,
	&s3c_device_i2c0,
	&s3c_device_adc,
	&serial_device,
	&vr1000_dm9k0,
	&vr1000_dm9k1,
	&vr1000_led1,
	&vr1000_led2,
	&vr1000_led3,
};

static void vr1000_power_off(void)
{
	gpio_direction_output(S3C2410_GPB(9), 1);
}

static void __init vr1000_map_io(void)
{
	pm_power_off = vr1000_power_off;

	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
	s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
}

static void __init vr1000_init_time(void)
{
	s3c2410_init_clocks(12000000);
	s3c24xx_timer_init();
}

static void __init vr1000_init(void)
{
	s3c_i2c0_set_platdata(NULL);

	/* Disable pull-up on LED lines and register GPIO lookups */
	s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
	s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_NONE);
	s3c_gpio_setpull(S3C2410_GPB(2), S3C_GPIO_PULL_NONE);
	gpiod_add_lookup_table(&vr1000_led1_gpio_table);
	gpiod_add_lookup_table(&vr1000_led2_gpio_table);
	gpiod_add_lookup_table(&vr1000_led3_gpio_table);

	platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));

	i2c_register_board_info(0, vr1000_i2c_devs,
				ARRAY_SIZE(vr1000_i2c_devs));

	nor_simtec_init();
	simtec_audio_add(NULL, true, NULL);

	WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
}

MACHINE_START(VR1000, "Thorcom-VR1000")
	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
	.atag_offset	= 0x100,
	.nr_irqs	= NR_IRQS_S3C2410,
	.map_io		= vr1000_map_io,
	.init_machine	= vr1000_init,
	.init_irq	= s3c2410_init_irq,
	.init_time	= vr1000_init_time,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0
//
// (C) 2006 Thomas Gleixner <tglx@linutronix.de>
//
// Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics

#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/serial_core.h>
#include <linux/serial_s3c.h>
#include <linux/platform_device.h>
#include <linux/io.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/memblock.h>

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

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

#include "regs-gpio.h"
#include "gpio-samsung.h"
#include "gpio-cfg.h"

#include <linux/platform_data/fb-s3c2410.h>

#include <linux/platform_data/i2c-s3c2410.h>
#include <linux/platform_data/mtd-nand-s3c2410.h>

#include "devs.h"
#include "cpu.h"

#include "s3c24xx.h"

static struct map_desc vstms_iodesc[] __initdata = {
};

static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
	[0] = {
		.hwport	     = 0,
		.flags	     = 0,
		.ucon	     = 0x3c5,
		.ulcon	     = 0x03,
		.ufcon	     = 0x51,
	},
	[1] = {
		.hwport	     = 1,
		.flags	     = 0,
		.ucon	     = 0x3c5,
		.ulcon	     = 0x03,
		.ufcon	     = 0x51,
	},
	[2] = {
		.hwport	     = 2,
		.flags	     = 0,
		.ucon	     = 0x3c5,
		.ulcon	     = 0x03,
		.ufcon	     = 0x51,
	}
};

static struct mtd_partition __initdata vstms_nand_part[] = {
	[0] = {
		.name	= "Boot Agent",
		.size	= 0x7C000,
		.offset	= 0,
	},
	[1] = {
		.name	= "UBoot Config",
		.offset = 0x7C000,
		.size	= 0x4000,
	},
	[2] = {
		.name	= "Kernel",
		.offset = 0x80000,
		.size	= 0x200000,
	},
	[3] = {
		.name	= "RFS",
		.offset	= 0x280000,
		.size	= 0x3d80000,
	},
};

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

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

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

static struct platform_device *vstms_devices[] __initdata = {
	&s3c_device_ohci,
	&s3c_device_wdt,
	&s3c_device_i2c0,
	&s3c_device_iis,
	&s3c_device_rtc,
	&s3c_device_nand,
	&s3c2412_device_dma,
};

static void __init vstms_fixup(struct tag *tags, char **cmdline)
{
	if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
		memblock_add(0x30000000, SZ_64M);
	}
}

static void __init vstms_map_io(void)
{
	s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
	s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
	s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
}

static void __init vstms_init_time(void)
{
	s3c2412_init_clocks(12000000);
	s3c24xx_timer_init();
}

static void __init vstms_init(void)
{
	s3c_i2c0_set_platdata(NULL);
	s3c_nand_set_platdata(&vstms_nand_info);
	/* Configure the I2S pins (GPE0...GPE4) in correct mode */
	s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
			      S3C_GPIO_PULL_NONE);
	platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
}

MACHINE_START(VSTMS, "VSTMS")
	.atag_offset	= 0x100,
	.nr_irqs	= NR_IRQS_S3C2412,

	.fixup		= vstms_fixup,
	.init_irq	= s3c2412_init_irq,
	.init_machine	= vstms_init,
	.map_io		= vstms_map_io,
	.init_time	= vstms_init_time,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2003, 2007 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * S3C - Memory map definitions (virtual addresses)
 */

#ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__

/* Fit all our registers in at 0xF6000000 upwards, trying to use as
 * little of the VA space as possible so vmalloc and friends have a
 * better chance of getting memory.
 *
 * we try to ensure stuff like the IRQ registers are available for
 * an single MOVS instruction (ie, only 8 bits of set data)
 */

#define S3C_ADDR_BASE	0xF6000000

#ifndef __ASSEMBLY__
#define S3C_ADDR(x)	((void __iomem __force *)S3C_ADDR_BASE + (x))
#else
#define S3C_ADDR(x)	(S3C_ADDR_BASE + (x))
#endif

#define S3C_VA_IRQ	S3C_ADDR(0x00000000)	/* irq controller(s) */
#define S3C_VA_SYS	S3C_ADDR(0x00100000)	/* system control */
#define S3C_VA_MEM	S3C_ADDR(0x00200000)	/* memory control */
#define S3C_VA_TIMER	S3C_ADDR(0x00300000)	/* timer block */
#define S3C_VA_WATCHDOG	S3C_ADDR(0x00400000)	/* watchdog */
#define S3C_VA_UART	S3C_ADDR(0x01000000)	/* UART */

/* ISA device mapping for BAST to use with inb()/outb() on 8-bit I/O.
 * 16-bit I/O on BAST now requires driver modifications to manually
 * ioremap CS3.
 */
#define S3C24XX_VA_ISA_BYTE	PCI_IOBASE

/* This is used for the CPU specific mappings that may be needed, so that
 * they do not need to directly used S3C_ADDR() and thus make it easier to
 * modify the space for mapping.
 */
#define S3C_ADDR_CPU(x)	S3C_ADDR(0x00500000 + (x))

#endif /* __ASM_PLAT_MAP_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2008 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * S3C24XX - Memory map definitions
 */

#ifndef __ASM_PLAT_MAP_S3C_H
#define __ASM_PLAT_MAP_S3C_H __FILE__

#include "map.h"

#define S3C24XX_VA_IRQ		S3C_VA_IRQ
#define S3C24XX_VA_MEMCTRL	S3C_VA_MEM
#define S3C24XX_VA_UART		S3C_VA_UART

#define S3C24XX_VA_TIMER	S3C_VA_TIMER
#define S3C24XX_VA_CLKPWR	S3C_VA_SYS
#define S3C24XX_VA_WATCHDOG	S3C_VA_WATCHDOG

#define S3C2412_VA_SSMC		S3C_ADDR_CPU(0x00000000)
#define S3C2412_VA_EBI		S3C_ADDR_CPU(0x00100000)

#define S3C2410_PA_UART		(0x50000000)
#define S3C24XX_PA_UART		S3C2410_PA_UART

/*
 * GPIO ports
 *
 * the calculation for the VA of this must ensure that
 * it is the same distance apart from the UART in the
 * phsyical address space, as the initial mapping for the IO
 * is done as a 1:1 mapping. This puts it (currently) at
 * 0xFA800000, which is not in the way of any current mapping
 * by the base system.
*/

#define S3C2410_PA_GPIO		(0x56000000)
#define S3C24XX_PA_GPIO		S3C2410_PA_GPIO

#define S3C24XX_VA_GPIO		((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
#define S3C64XX_VA_GPIO		S3C_ADDR_CPU(0x00000000)

#define S3C64XX_VA_MODEM	S3C_ADDR_CPU(0x00100000)
#define S3C64XX_VA_USB_HSPHY	S3C_ADDR_CPU(0x00200000)

#define S3C_VA_USB_HSPHY	S3C64XX_VA_USB_HSPHY

#define S3C2410_ADDR(x)		S3C_ADDR(x)

/* deal with the registers that move under the 2412/2413 */

#if defined(CONFIG_CPU_S3C2412)
#ifndef __ASSEMBLY__
extern void __iomem *s3c24xx_va_gpio2;
#endif
#ifdef CONFIG_CPU_S3C2412_ONLY
#define S3C24XX_VA_GPIO2	(S3C24XX_VA_GPIO + 0x10)
#else
#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2
#endif
#else
#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO
#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO
#endif

#include "map-s5p.h"

#endif /* __ASM_PLAT_MAP_S3C_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2003 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * S3C2410 - Memory map definitions
 */

#ifndef __ASM_ARCH_MAP_H
#define __ASM_ARCH_MAP_H

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

/*
 * interrupt controller is the first thing we put in, to make
 * the assembly code for the irq detection easier
 */
#define S3C2410_PA_IRQ		(0x4A000000)
#define S3C24XX_SZ_IRQ		SZ_1M

/* memory controller registers */
#define S3C2410_PA_MEMCTRL	(0x48000000)
#define S3C24XX_SZ_MEMCTRL	SZ_1M

/* Timers */
#define S3C2410_PA_TIMER	(0x51000000)
#define S3C24XX_SZ_TIMER	SZ_1M

/* Clock and Power management */
#define S3C24XX_SZ_CLKPWR	SZ_1M

/* USB Device port */
#define S3C2410_PA_USBDEV	(0x52000000)
#define S3C24XX_SZ_USBDEV	SZ_1M

/* Watchdog */
#define S3C2410_PA_WATCHDOG	(0x53000000)
#define S3C24XX_SZ_WATCHDOG	SZ_1M

/* Standard size definitions for peripheral blocks. */

#define S3C24XX_SZ_UART		SZ_1M
#define S3C24XX_SZ_IIS		SZ_1M
#define S3C24XX_SZ_ADC		SZ_1M
#define S3C24XX_SZ_SPI		SZ_1M
#define S3C24XX_SZ_SDI		SZ_1M
#define S3C24XX_SZ_NAND		SZ_1M
#define S3C24XX_SZ_GPIO		SZ_1M

/* USB host controller */
#define S3C2410_PA_USBHOST (0x49000000)

/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */
#define S3C2416_PA_HSUDC	(0x49800000)
#define S3C2416_SZ_HSUDC	(SZ_4K)

/* DMA controller */
#define S3C2410_PA_DMA	   (0x4B000000)
#define S3C24XX_SZ_DMA	   SZ_1M

/* Clock and Power management */
#define S3C2410_PA_CLKPWR  (0x4C000000)

/* LCD controller */
#define S3C2410_PA_LCD	   (0x4D000000)
#define S3C24XX_SZ_LCD	   SZ_1M

/* NAND flash controller */
#define S3C2410_PA_NAND	   (0x4E000000)

/* IIC hardware controller */
#define S3C2410_PA_IIC	   (0x54000000)

/* IIS controller */
#define S3C2410_PA_IIS	   (0x55000000)

/* RTC */
#define S3C2410_PA_RTC	   (0x57000000)
#define S3C24XX_SZ_RTC	   SZ_1M

/* ADC */
#define S3C2410_PA_ADC	   (0x58000000)

/* SPI */
#define S3C2410_PA_SPI	   (0x59000000)
#define S3C2443_PA_SPI0		(0x52000000)
#define S3C2443_PA_SPI1		S3C2410_PA_SPI
#define S3C2410_SPI1		(0x20)
#define S3C2412_SPI1		(0x100)

/* SDI */
#define S3C2410_PA_SDI	   (0x5A000000)

/* CAMIF */
#define S3C2440_PA_CAMIF   (0x4F000000)
#define S3C2440_SZ_CAMIF   SZ_1M

/* AC97 */

#define S3C2440_PA_AC97	   (0x5B000000)
#define S3C2440_SZ_AC97	   SZ_1M

/* S3C2443/S3C2416 High-speed SD/MMC */
#define S3C2443_PA_HSMMC   (0x4A800000)
#define S3C2416_PA_HSMMC0  (0x4AC00000)

#define	S3C2443_PA_FB	(0x4C800000)

/* S3C2412 memory and IO controls */
#define S3C2412_PA_SSMC	(0x4F000000)

#define S3C2412_PA_EBI	(0x48800000)

/* physical addresses of all the chip-select areas */

#define S3C2410_CS0 (0x00000000)
#define S3C2410_CS1 (0x08000000)
#define S3C2410_CS2 (0x10000000)
#define S3C2410_CS3 (0x18000000)
#define S3C2410_CS4 (0x20000000)
#define S3C2410_CS5 (0x28000000)
#define S3C2410_CS6 (0x30000000)
#define S3C2410_CS7 (0x38000000)

#define S3C2410_SDRAM_PA    (S3C2410_CS6)

/* Use a single interface for common resources between S3C24XX cpus */

#define S3C24XX_PA_IRQ      S3C2410_PA_IRQ
#define S3C24XX_PA_MEMCTRL  S3C2410_PA_MEMCTRL
#define S3C24XX_PA_DMA      S3C2410_PA_DMA
#define S3C24XX_PA_CLKPWR   S3C2410_PA_CLKPWR
#define S3C24XX_PA_LCD      S3C2410_PA_LCD
#define S3C24XX_PA_TIMER    S3C2410_PA_TIMER
#define S3C24XX_PA_USBDEV   S3C2410_PA_USBDEV
#define S3C24XX_PA_WATCHDOG S3C2410_PA_WATCHDOG
#define S3C24XX_PA_IIS      S3C2410_PA_IIS
#define S3C24XX_PA_RTC      S3C2410_PA_RTC
#define S3C24XX_PA_ADC      S3C2410_PA_ADC
#define S3C24XX_PA_SPI      S3C2410_PA_SPI
#define S3C24XX_PA_SPI1		(S3C2410_PA_SPI + S3C2410_SPI1)
#define S3C24XX_PA_SDI      S3C2410_PA_SDI
#define S3C24XX_PA_NAND	    S3C2410_PA_NAND

#define S3C_PA_FB	    S3C2443_PA_FB
#define S3C_PA_IIC          S3C2410_PA_IIC
#define S3C_PA_USBHOST	S3C2410_PA_USBHOST
#define S3C_PA_HSMMC0	    S3C2416_PA_HSMMC0
#define S3C_PA_HSMMC1	    S3C2443_PA_HSMMC
#define S3C_PA_WDT	    S3C2410_PA_WATCHDOG
#define S3C_PA_NAND	    S3C24XX_PA_NAND

#define S3C_PA_SPI0		S3C2443_PA_SPI0
#define S3C_PA_SPI1		S3C2443_PA_SPI1

#define SAMSUNG_PA_TIMER	S3C2410_PA_TIMER

#endif /* __ASM_ARCH_MAP_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2008 Openmoko, Inc.
 * Copyright 2008 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * S3C64XX - Memory map definitions
 */

#ifndef __ASM_ARCH_MAP_H
#define __ASM_ARCH_MAP_H __FILE__

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

/*
 * Post-mux Chip Select Regions Xm0CSn_
 * These may be used by SROM, NAND or CF depending on settings
 */

#define S3C64XX_PA_XM0CSN0 (0x10000000)
#define S3C64XX_PA_XM0CSN1 (0x18000000)
#define S3C64XX_PA_XM0CSN2 (0x20000000)
#define S3C64XX_PA_XM0CSN3 (0x28000000)
#define S3C64XX_PA_XM0CSN4 (0x30000000)
#define S3C64XX_PA_XM0CSN5 (0x38000000)

/* HSMMC units */
#define S3C64XX_PA_HSMMC(x)	(0x7C200000 + ((x) * 0x100000))
#define S3C64XX_PA_HSMMC0	S3C64XX_PA_HSMMC(0)
#define S3C64XX_PA_HSMMC1	S3C64XX_PA_HSMMC(1)
#define S3C64XX_PA_HSMMC2	S3C64XX_PA_HSMMC(2)

#define S3C_PA_UART		(0x7F005000)
#define S3C_PA_UART0		(S3C_PA_UART + 0x00)
#define S3C_PA_UART1		(S3C_PA_UART + 0x400)
#define S3C_PA_UART2		(S3C_PA_UART + 0x800)
#define S3C_PA_UART3		(S3C_PA_UART + 0xC00)
#define S3C_UART_OFFSET		(0x400)

/* See notes on UART VA mapping in debug-macro.S */
#define S3C_VA_UARTx(x)	(S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))

#define S3C_VA_UART0		S3C_VA_UARTx(0)
#define S3C_VA_UART1		S3C_VA_UARTx(1)
#define S3C_VA_UART2		S3C_VA_UARTx(2)
#define S3C_VA_UART3		S3C_VA_UARTx(3)

#define S3C64XX_PA_SROM		(0x70000000)

#define S3C64XX_PA_ONENAND0	(0x70100000)
#define S3C64XX_PA_ONENAND0_BUF	(0x20000000)
#define S3C64XX_SZ_ONENAND0_BUF (SZ_64M)

/* NAND and OneNAND1 controllers occupy the same register region
   (depending on SoC POP version) */
#define S3C64XX_PA_ONENAND1	(0x70200000)
#define S3C64XX_PA_ONENAND1_BUF	(0x28000000)
#define S3C64XX_SZ_ONENAND1_BUF	(SZ_64M)

#define S3C64XX_PA_NAND		(0x70200000)
#define S3C64XX_PA_FB		(0x77100000)
#define S3C64XX_PA_USB_HSOTG	(0x7C000000)
#define S3C64XX_PA_WATCHDOG	(0x7E004000)
#define S3C64XX_PA_RTC		(0x7E005000)
#define S3C64XX_PA_KEYPAD	(0x7E00A000)
#define S3C64XX_PA_ADC		(0x7E00B000)
#define S3C64XX_PA_SYSCON	(0x7E00F000)
#define S3C64XX_PA_AC97		(0x7F001000)
#define S3C64XX_PA_IIS0		(0x7F002000)
#define S3C64XX_PA_IIS1		(0x7F003000)
#define S3C64XX_PA_TIMER	(0x7F006000)
#define S3C64XX_PA_IIC0		(0x7F004000)
#define S3C64XX_PA_SPI0		(0x7F00B000)
#define S3C64XX_PA_SPI1		(0x7F00C000)
#define S3C64XX_PA_PCM0		(0x7F009000)
#define S3C64XX_PA_PCM1		(0x7F00A000)
#define S3C64XX_PA_IISV4	(0x7F00D000)
#define S3C64XX_PA_IIC1		(0x7F00F000)

#define S3C64XX_PA_GPIO		(0x7F008000)
#define S3C64XX_SZ_GPIO		SZ_4K

#define S3C64XX_PA_SDRAM	(0x50000000)

#define S3C64XX_PA_CFCON	(0x70300000)

#define S3C64XX_PA_VIC0		(0x71200000)
#define S3C64XX_PA_VIC1		(0x71300000)

#define S3C64XX_PA_MODEM	(0x74108000)

#define S3C64XX_PA_USBHOST	(0x74300000)

#define S3C64XX_PA_USB_HSPHY	(0x7C100000)

/* compatibility defines. */
#define S3C_PA_TIMER		S3C64XX_PA_TIMER
#define S3C_PA_HSMMC0		S3C64XX_PA_HSMMC0
#define S3C_PA_HSMMC1		S3C64XX_PA_HSMMC1
#define S3C_PA_HSMMC2		S3C64XX_PA_HSMMC2
#define S3C_PA_IIC		S3C64XX_PA_IIC0
#define S3C_PA_IIC1		S3C64XX_PA_IIC1
#define S3C_PA_NAND		S3C64XX_PA_NAND
#define S3C_PA_ONENAND		S3C64XX_PA_ONENAND0
#define S3C_PA_ONENAND_BUF	S3C64XX_PA_ONENAND0_BUF
#define S3C_SZ_ONENAND_BUF	S3C64XX_SZ_ONENAND0_BUF
#define S3C_PA_FB		S3C64XX_PA_FB
#define S3C_PA_USBHOST		S3C64XX_PA_USBHOST
#define S3C_PA_USB_HSOTG	S3C64XX_PA_USB_HSOTG
#define S3C_PA_RTC		S3C64XX_PA_RTC
#define S3C_PA_WDT		S3C64XX_PA_WATCHDOG
#define S3C_PA_SPI0		S3C64XX_PA_SPI0
#define S3C_PA_SPI1		S3C64XX_PA_SPI1

#define SAMSUNG_PA_ADC		S3C64XX_PA_ADC
#define SAMSUNG_PA_CFCON	S3C64XX_PA_CFCON
#define SAMSUNG_PA_KEYPAD	S3C64XX_PA_KEYPAD
#define SAMSUNG_PA_TIMER	S3C64XX_PA_TIMER

#endif /* __ASM_ARCH_6400_MAP_H */


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

#ifndef __ASM_PLAT_MAP_S5P_H
#define __ASM_PLAT_MAP_S5P_H __FILE__

#define VA_VIC(x)		(S3C_VA_IRQ + ((x) * 0x10000))
#define VA_VIC0			VA_VIC(0)
#define VA_VIC1			VA_VIC(1)
#define VA_VIC2			VA_VIC(2)
#define VA_VIC3			VA_VIC(3)

#include "map-s3c.h"

#endif /* __ASM_PLAT_MAP_S5P_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */

#ifdef CONFIG_ARCH_S3C24XX
#include "map-s3c24xx.h"
#endif

#ifdef CONFIG_ARCH_S3C64XX
#include "map-s3c64xx.h"
#endif


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

#ifndef __ASM_ARCH_NAND_CORE_S3C24XX_H
#define __ASM_ARCH_NAND_CORE_S3C24XX_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_nand_setname(char *name)
{
#ifdef CONFIG_S3C_DEV_NAND
	s3c_device_nand.name = name;
#endif
}

#endif /* __ASM_ARCH_NAND_CORE_S3C24XX_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 *  Copyright (c) 2010 Samsung Electronics
 *  Kyungmin Park <kyungmin.park@samsung.com>
 *  Marek Szyprowski <m.szyprowski@samsung.com>
 *
 * Samsung OneNAD Controller core functions
 */

#ifndef __ASM_ARCH_ONENAND_CORE_S3C64XX_H
#define __ASM_ARCH_ONENAND_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_onenand_setname(char *name)
{
#ifdef CONFIG_S3C_DEV_ONENAND
	s3c_device_onenand.name = name;
#endif
}

static inline void s3c64xx_onenand1_setname(char *name)
{
#ifdef CONFIG_S3C64XX_DEV_ONENAND1
	s3c64xx_device_onenand1.name = name;
#endif
}

#endif /* __ASM_ARCH_ONENAND_CORE_S3C64XX_H */


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

#ifndef __MACH_S3C24XX_OSIRIS_H
#define __MACH_S3C24XX_OSIRIS_H __FILE__

/* CTRL0 - NAND WP control */

#define OSIRIS_CTRL0_NANDSEL		(0x3)
#define OSIRIS_CTRL0_BOOT_INT		(1<<3)
#define OSIRIS_CTRL0_PCMCIA		(1<<4)
#define OSIRIS_CTRL0_FIX8		(1<<5)
#define OSIRIS_CTRL0_PCMCIA_nWAIT	(1<<6)
#define OSIRIS_CTRL0_PCMCIA_nIOIS16	(1<<7)

#define OSIRIS_CTRL1_FIX8		(1<<0)

#define OSIRIS_ID_REVMASK		(0x7)

/* start peripherals off after the S3C2410 */

#define OSIRIS_IOADDR(x)	(S3C2410_ADDR((x) + 0x04000000))

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

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

#define OSIRIS_VA_CTRL0		OSIRIS_IOADDR(0x00000000)
#define OSIRIS_PA_CTRL0		(OSIRIS_PA_CPLD)

#define OSIRIS_VA_CTRL1		OSIRIS_IOADDR(0x00100000)
#define OSIRIS_PA_CTRL1		(OSIRIS_PA_CPLD + (1<<23))

#define OSIRIS_VA_CTRL2		OSIRIS_IOADDR(0x00200000)
#define OSIRIS_PA_CTRL2		(OSIRIS_PA_CPLD + (2<<23))

#define OSIRIS_VA_CTRL3		OSIRIS_IOADDR(0x00300000)
#define OSIRIS_PA_CTRL3		(OSIRIS_PA_CPLD + (2<<23))

#define OSIRIS_VA_IDREG		OSIRIS_IOADDR(0x00700000)
#define OSIRIS_PA_IDREG		(OSIRIS_PA_CPLD + (7<<23))

#endif /* __MACH_S3C24XX_OSIRIS_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * (c) 2005 Guillaume GOURAT / NexVision
 *          guillaume.gourat@nexvision.fr
 *
 * NexVision OTOM board memory map definitions
 */

/*
 * ok, we've used up to 0x01300000, now we need to find space for the
 * peripherals that live in the nGCS[x] areas, which are quite numerous
 * in their space.
 */

#ifndef __MACH_S3C24XX_OTOM_H
#define __MACH_S3C24XX_OTOM_H __FILE__

#define OTOM_PA_CS8900A_BASE	(S3C2410_CS3 + 0x01000000)	/* nGCS3 +0x01000000 */
#define OTOM_VA_CS8900A_BASE	S3C2410_ADDR(0x04000000)	/* 0xF4000000 */

/* physical offset addresses for the peripherals */

#define OTOM_PA_FLASH0_BASE	(S3C2410_CS0)

#endif /* __MACH_S3C24XX_OTOM_H */


code:
// SPDX-License-Identifier: GPL-2.0
//
// Samsung's S3C64XX generic DMA support using amba-pl08x driver.
//
// Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>

#include <linux/kernel.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl080.h>
#include <linux/amba/pl08x.h>
#include <linux/of.h>

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

#include "regs-sys-s3c64xx.h"

static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
{
	return cd->min_signal;
}

static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
{
}

/*
 * DMA0
 */

static struct pl08x_channel_data s3c64xx_dma0_info[] = {
	{
		.bus_id = "uart0_tx",
		.min_signal = 0,
		.max_signal = 0,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "uart0_rx",
		.min_signal = 1,
		.max_signal = 1,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "uart1_tx",
		.min_signal = 2,
		.max_signal = 2,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "uart1_rx",
		.min_signal = 3,
		.max_signal = 3,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "uart2_tx",
		.min_signal = 4,
		.max_signal = 4,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "uart2_rx",
		.min_signal = 5,
		.max_signal = 5,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "uart3_tx",
		.min_signal = 6,
		.max_signal = 6,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "uart3_rx",
		.min_signal = 7,
		.max_signal = 7,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "pcm0_tx",
		.min_signal = 8,
		.max_signal = 8,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "pcm0_rx",
		.min_signal = 9,
		.max_signal = 9,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "i2s0_tx",
		.min_signal = 10,
		.max_signal = 10,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "i2s0_rx",
		.min_signal = 11,
		.max_signal = 11,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "spi0_tx",
		.min_signal = 12,
		.max_signal = 12,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "spi0_rx",
		.min_signal = 13,
		.max_signal = 13,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "i2s2_tx",
		.min_signal = 14,
		.max_signal = 14,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "i2s2_rx",
		.min_signal = 15,
		.max_signal = 15,
		.periph_buses = PL08X_AHB2,
	}
};

static const struct dma_slave_map s3c64xx_dma0_slave_map[] = {
	{ "s3c6400-uart.0", "tx", &s3c64xx_dma0_info[0] },
	{ "s3c6400-uart.0", "rx", &s3c64xx_dma0_info[1] },
	{ "s3c6400-uart.1", "tx", &s3c64xx_dma0_info[2] },
	{ "s3c6400-uart.1", "rx", &s3c64xx_dma0_info[3] },
	{ "s3c6400-uart.2", "tx", &s3c64xx_dma0_info[4] },
	{ "s3c6400-uart.2", "rx", &s3c64xx_dma0_info[5] },
	{ "s3c6400-uart.3", "tx", &s3c64xx_dma0_info[6] },
	{ "s3c6400-uart.3", "rx", &s3c64xx_dma0_info[7] },
	{ "samsung-pcm.0", "tx", &s3c64xx_dma0_info[8] },
	{ "samsung-pcm.0", "rx", &s3c64xx_dma0_info[9] },
	{ "samsung-i2s.0", "tx", &s3c64xx_dma0_info[10] },
	{ "samsung-i2s.0", "rx", &s3c64xx_dma0_info[11] },
	{ "s3c6410-spi.0", "tx", &s3c64xx_dma0_info[12] },
	{ "s3c6410-spi.0", "rx", &s3c64xx_dma0_info[13] },
	{ "samsung-i2s.2", "tx", &s3c64xx_dma0_info[14] },
	{ "samsung-i2s.2", "rx", &s3c64xx_dma0_info[15] },
};

struct pl08x_platform_data s3c64xx_dma0_plat_data = {
	.memcpy_burst_size = PL08X_BURST_SZ_4,
	.memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
	.memcpy_prot_buff = true,
	.memcpy_prot_cache = true,
	.lli_buses = PL08X_AHB1,
	.mem_buses = PL08X_AHB1,
	.get_xfer_signal = pl08x_get_xfer_signal,
	.put_xfer_signal = pl08x_put_xfer_signal,
	.slave_channels = s3c64xx_dma0_info,
	.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
	.slave_map = s3c64xx_dma0_slave_map,
	.slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map),
};

static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
			0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);

/*
 * DMA1
 */

static struct pl08x_channel_data s3c64xx_dma1_info[] = {
	{
		.bus_id = "pcm1_tx",
		.min_signal = 0,
		.max_signal = 0,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "pcm1_rx",
		.min_signal = 1,
		.max_signal = 1,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "i2s1_tx",
		.min_signal = 2,
		.max_signal = 2,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "i2s1_rx",
		.min_signal = 3,
		.max_signal = 3,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "spi1_tx",
		.min_signal = 4,
		.max_signal = 4,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "spi1_rx",
		.min_signal = 5,
		.max_signal = 5,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "ac97_out",
		.min_signal = 6,
		.max_signal = 6,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "ac97_in",
		.min_signal = 7,
		.max_signal = 7,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "ac97_mic",
		.min_signal = 8,
		.max_signal = 8,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "pwm",
		.min_signal = 9,
		.max_signal = 9,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "irda",
		.min_signal = 10,
		.max_signal = 10,
		.periph_buses = PL08X_AHB2,
	}, {
		.bus_id = "external",
		.min_signal = 11,
		.max_signal = 11,
		.periph_buses = PL08X_AHB2,
	},
};

static const struct dma_slave_map s3c64xx_dma1_slave_map[] = {
	{ "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] },
	{ "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] },
	{ "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] },
	{ "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] },
	{ "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] },
	{ "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] },
};

struct pl08x_platform_data s3c64xx_dma1_plat_data = {
	.memcpy_burst_size = PL08X_BURST_SZ_4,
	.memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
	.memcpy_prot_buff = true,
	.memcpy_prot_cache = true,
	.lli_buses = PL08X_AHB1,
	.mem_buses = PL08X_AHB1,
	.get_xfer_signal = pl08x_get_xfer_signal,
	.put_xfer_signal = pl08x_put_xfer_signal,
	.slave_channels = s3c64xx_dma1_info,
	.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
	.slave_map = s3c64xx_dma1_slave_map,
	.slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map),
};

static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
			0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);

static int __init s3c64xx_pl080_init(void)
{
	if (!soc_is_s3c64xx())
		return 0;

	/* Set all DMA configuration to be DMA, not SDMA */
	writel(0xffffff, S3C64XX_SDMA_SEL);

	if (of_have_populated_dt())
		return 0;

	amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
	amba_device_register(&s3c64xx_dma1_device, &iomem_resource);

	return 0;
}
arch_initcall(s3c64xx_pl080_init);


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright 2010 Ben Dooks <ben-linux <at> fluff.org>
//
// Helper for platform data setting

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/platform_device.h>

#include "devs.h"
#include "sdhci.h"

void __init *s3c_set_platdata(void *pd, size_t pdsize,
			      struct platform_device *pdev)
{
	void *npd;

	if (!pd) {
		/* too early to use dev_name(), may not be registered */
		printk(KERN_ERR "%s: no platform data supplied\n", pdev->name);
		return NULL;
	}

	npd = kmemdup(pd, pdsize, GFP_KERNEL);
	if (!npd)
		return NULL;

	pdev->dev.platform_data = npd;
	return npd;
}

void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
			     struct s3c_sdhci_platdata *set)
{
	set->cd_type = pd->cd_type;
	set->ext_cd_init = pd->ext_cd_init;
	set->ext_cd_cleanup = pd->ext_cd_cleanup;
	set->ext_cd_gpio = pd->ext_cd_gpio;
	set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;

	if (pd->max_width)
		set->max_width = pd->max_width;
	if (pd->cfg_gpio)
		set->cfg_gpio = pd->cfg_gpio;
	if (pd->host_caps)
		set->host_caps |= pd->host_caps;
	if (pd->host_caps2)
		set->host_caps2 |= pd->host_caps2;
	if (pd->pm_caps)
		set->pm_caps |= pd->pm_caps;
}


code:
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2006-2007 Simtec Electronics
//	http://armlinux.simtec.co.uk/
//	Ben Dooks <ben@simtec.co.uk>
//	Vincent Sanders <vince@arm.linux.org.uk>
//
// S3C2410 CPU PLL tables

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/err.h>

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

/* This array should be sorted in ascending order of the frequencies */
static struct cpufreq_frequency_table pll_vals_12MHz[] = {
    { .frequency = 34000000,  .driver_data = PLLVAL(82, 2, 3),   },
    { .frequency = 45000000,  .driver_data = PLLVAL(82, 1, 3),   },
    { .frequency = 48000000,  .driver_data = PLLVAL(120, 2, 3),  },
    { .frequency = 51000000,  .driver_data = PLLVAL(161, 3, 3),  },
    { .frequency = 56000000,  .driver_data = PLLVAL(142, 2, 3),  },
    { .frequency = 68000000,  .driver_data = PLLVAL(82, 2, 2),   },
    { .frequency = 79000000,  .driver_data = PLLVAL(71, 1, 2),   },
    { .frequency = 85000000,  .driver_data = PLLVAL(105, 2, 2),  },
    { .frequency = 90000000,  .driver_data = PLLVAL(112, 2, 2),  },
    { .frequency = 101000000, .driver_data = PLLVAL(127, 2, 2),  },
    { .frequency = 113000000, .driver_data = PLLVAL(105, 1, 2),  },
    { .frequency = 118000000, .driver_data = PLLVAL(150, 2, 2),  },
    { .frequency = 124000000, .driver_data = PLLVAL(116, 1, 2),  },
    { .frequency = 135000000, .driver_data = PLLVAL(82, 2, 1),   },
    { .frequency = 147000000, .driver_data = PLLVAL(90, 2, 1),   },
    { .frequency = 152000000, .driver_data = PLLVAL(68, 1, 1),   },
    { .frequency = 158000000, .driver_data = PLLVAL(71, 1, 1),   },
    { .frequency = 170000000, .driver_data = PLLVAL(77, 1, 1),   },
    { .frequency = 180000000, .driver_data = PLLVAL(82, 1, 1),   },
    { .frequency = 186000000, .driver_data = PLLVAL(85, 1, 1),   },
    { .frequency = 192000000, .driver_data = PLLVAL(88, 1, 1),   },
    { .frequency = 203000000, .driver_data = PLLVAL(161, 3, 1),  },

    /* 2410A extras */

    { .frequency = 210000000, .driver_data = PLLVAL(132, 2, 1),  },
    { .frequency = 226000000, .driver_data = PLLVAL(105, 1, 1),  },
    { .frequency = 266000000, .driver_data = PLLVAL(125, 1, 1),  },
    { .frequency = 268000000, .driver_data = PLLVAL(126, 1, 1),  },
    { .frequency = 270000000, .driver_data = PLLVAL(127, 1, 1),  },
};

static int s3c2410_plls_add(struct device *dev, struct subsys_interface *sif)
{
	return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz));
}

static struct subsys_interface s3c2410_plls_interface = {
	.name		= "s3c2410_plls",
	.subsys		= &s3c2410_subsys,
	.add_dev	= s3c2410_plls_add,
};

static int __init s3c2410_pll_init(void)
{
	return subsys_interface_register(&s3c2410_plls_interface);

}
arch_initcall(s3c2410_pll_init);

static struct subsys_interface s3c2410a_plls_interface = {
	.name		= "s3c2410a_plls",
	.subsys		= &s3c2410a_subsys,
	.add_dev	= s3c2410_plls_add,
};

static int __init s3c2410a_pll_init(void)
{
	return subsys_interface_register(&s3c2410a_plls_interface);
}
arch_initcall(s3c2410a_pll_init);


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2006-2007 Simtec Electronics
//	http://armlinux.simtec.co.uk/
//	Ben Dooks <ben@simtec.co.uk>
//	Vincent Sanders <vince@arm.linux.org.uk>
//
// S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/clk.h>
#include <linux/err.h>

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

/* This array should be sorted in ascending order of the frequencies */
static struct cpufreq_frequency_table s3c2440_plls_12[] = {
	{ .frequency = 75000000,	.driver_data = PLLVAL(0x75, 3, 3),  }, 	/* FVco 600.000000 */
	{ .frequency = 80000000,	.driver_data = PLLVAL(0x98, 4, 3),  }, 	/* FVco 640.000000 */
	{ .frequency = 90000000,	.driver_data = PLLVAL(0x70, 2, 3),  }, 	/* FVco 720.000000 */
	{ .frequency = 100000000,	.driver_data = PLLVAL(0x5c, 1, 3),  }, 	/* FVco 800.000000 */
	{ .frequency = 110000000,	.driver_data = PLLVAL(0x66, 1, 3),  }, 	/* FVco 880.000000 */
	{ .frequency = 120000000,	.driver_data = PLLVAL(0x70, 1, 3),  }, 	/* FVco 960.000000 */
	{ .frequency = 150000000,	.driver_data = PLLVAL(0x75, 3, 2),  }, 	/* FVco 600.000000 */
	{ .frequency = 160000000,	.driver_data = PLLVAL(0x98, 4, 2),  }, 	/* FVco 640.000000 */
	{ .frequency = 170000000,	.driver_data = PLLVAL(0x4d, 1, 2),  }, 	/* FVco 680.000000 */
	{ .frequency = 180000000,	.driver_data = PLLVAL(0x70, 2, 2),  }, 	/* FVco 720.000000 */
	{ .frequency = 190000000,	.driver_data = PLLVAL(0x57, 1, 2),  }, 	/* FVco 760.000000 */
	{ .frequency = 200000000,	.driver_data = PLLVAL(0x5c, 1, 2),  }, 	/* FVco 800.000000 */
	{ .frequency = 210000000,	.driver_data = PLLVAL(0x84, 2, 2),  }, 	/* FVco 840.000000 */
	{ .frequency = 220000000,	.driver_data = PLLVAL(0x66, 1, 2),  }, 	/* FVco 880.000000 */
	{ .frequency = 230000000,	.driver_data = PLLVAL(0x6b, 1, 2),  }, 	/* FVco 920.000000 */
	{ .frequency = 240000000,	.driver_data = PLLVAL(0x70, 1, 2),  }, 	/* FVco 960.000000 */
	{ .frequency = 300000000,	.driver_data = PLLVAL(0x75, 3, 1),  }, 	/* FVco 600.000000 */
	{ .frequency = 310000000,	.driver_data = PLLVAL(0x93, 4, 1),  }, 	/* FVco 620.000000 */
	{ .frequency = 320000000,	.driver_data = PLLVAL(0x98, 4, 1),  }, 	/* FVco 640.000000 */
	{ .frequency = 330000000,	.driver_data = PLLVAL(0x66, 2, 1),  }, 	/* FVco 660.000000 */
	{ .frequency = 340000000,	.driver_data = PLLVAL(0x4d, 1, 1),  }, 	/* FVco 680.000000 */
	{ .frequency = 350000000,	.driver_data = PLLVAL(0xa7, 4, 1),  }, 	/* FVco 700.000000 */
	{ .frequency = 360000000,	.driver_data = PLLVAL(0x70, 2, 1),  }, 	/* FVco 720.000000 */
	{ .frequency = 370000000,	.driver_data = PLLVAL(0xb1, 4, 1),  }, 	/* FVco 740.000000 */
	{ .frequency = 380000000,	.driver_data = PLLVAL(0x57, 1, 1),  }, 	/* FVco 760.000000 */
	{ .frequency = 390000000,	.driver_data = PLLVAL(0x7a, 2, 1),  }, 	/* FVco 780.000000 */
	{ .frequency = 400000000,	.driver_data = PLLVAL(0x5c, 1, 1),  }, 	/* FVco 800.000000 */
};

static int s3c2440_plls12_add(struct device *dev, struct subsys_interface *sif)
{
	struct clk *xtal_clk;
	unsigned long xtal;

	xtal_clk = clk_get(NULL, "xtal");
	if (IS_ERR(xtal_clk))
		return PTR_ERR(xtal_clk);

	xtal = clk_get_rate(xtal_clk);
	clk_put(xtal_clk);

	if (xtal == 12000000) {
		printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
		return s3c_plltab_register(s3c2440_plls_12,
					   ARRAY_SIZE(s3c2440_plls_12));
	}

	return 0;
}

static struct subsys_interface s3c2440_plls12_interface = {
	.name		= "s3c2440_plls12",
	.subsys		= &s3c2440_subsys,
	.add_dev	= s3c2440_plls12_add,
};

static int __init s3c2440_pll_12mhz(void)
{
	return subsys_interface_register(&s3c2440_plls12_interface);

}
arch_initcall(s3c2440_pll_12mhz);

static struct subsys_interface s3c2442_plls12_interface = {
	.name		= "s3c2442_plls12",
	.subsys		= &s3c2442_subsys,
	.add_dev	= s3c2440_plls12_add,
};

static int __init s3c2442_pll_12mhz(void)
{
	return subsys_interface_register(&s3c2442_plls12_interface);

}
arch_initcall(s3c2442_pll_12mhz);


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2006-2008 Simtec Electronics
//	http://armlinux.simtec.co.uk/
//	Ben Dooks <ben@simtec.co.uk>
//	Vincent Sanders <vince@arm.linux.org.uk>
//
// S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/clk.h>
#include <linux/err.h>

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

/* This array should be sorted in ascending order of the frequencies */
static struct cpufreq_frequency_table s3c2440_plls_169344[] = {
	{ .frequency = 78019200,	.driver_data = PLLVAL(121, 5, 3), 	}, 	/* FVco 624.153600 */
	{ .frequency = 84067200,	.driver_data = PLLVAL(131, 5, 3), 	}, 	/* FVco 672.537600 */
	{ .frequency = 90115200,	.driver_data = PLLVAL(141, 5, 3), 	}, 	/* FVco 720.921600 */
	{ .frequency = 96163200,	.driver_data = PLLVAL(151, 5, 3), 	}, 	/* FVco 769.305600 */
	{ .frequency = 102135600,	.driver_data = PLLVAL(185, 6, 3), 	}, 	/* FVco 817.084800 */
	{ .frequency = 108259200,	.driver_data = PLLVAL(171, 5, 3), 	}, 	/* FVco 866.073600 */
	{ .frequency = 114307200,	.driver_data = PLLVAL(127, 3, 3), 	}, 	/* FVco 914.457600 */
	{ .frequency = 120234240,	.driver_data = PLLVAL(134, 3, 3), 	}, 	/* FVco 961.873920 */
	{ .frequency = 126161280,	.driver_data = PLLVAL(141, 3, 3), 	}, 	/* FVco 1009.290240 */
	{ .frequency = 132088320,	.driver_data = PLLVAL(148, 3, 3), 	}, 	/* FVco 1056.706560 */
	{ .frequency = 138015360,	.driver_data = PLLVAL(155, 3, 3), 	}, 	/* FVco 1104.122880 */
	{ .frequency = 144789120,	.driver_data = PLLVAL(163, 3, 3), 	}, 	/* FVco 1158.312960 */
	{ .frequency = 150100363,	.driver_data = PLLVAL(187, 9, 2), 	}, 	/* FVco 600.401454 */
	{ .frequency = 156038400,	.driver_data = PLLVAL(121, 5, 2), 	}, 	/* FVco 624.153600 */
	{ .frequency = 162086400,	.driver_data = PLLVAL(126, 5, 2), 	}, 	/* FVco 648.345600 */
	{ .frequency = 168134400,	.driver_data = PLLVAL(131, 5, 2), 	}, 	/* FVco 672.537600 */
	{ .frequency = 174048000,	.driver_data = PLLVAL(177, 7, 2), 	}, 	/* FVco 696.192000 */
	{ .frequency = 180230400,	.driver_data = PLLVAL(141, 5, 2), 	}, 	/* FVco 720.921600 */
	{ .frequency = 186278400,	.driver_data = PLLVAL(124, 4, 2), 	}, 	/* FVco 745.113600 */
	{ .frequency = 192326400,	.driver_data = PLLVAL(151, 5, 2), 	}, 	/* FVco 769.305600 */
	{ .frequency = 198132480,	.driver_data = PLLVAL(109, 3, 2), 	}, 	/* FVco 792.529920 */
	{ .frequency = 204271200,	.driver_data = PLLVAL(185, 6, 2), 	}, 	/* FVco 817.084800 */
	{ .frequency = 210268800,	.driver_data = PLLVAL(141, 4, 2), 	}, 	/* FVco 841.075200 */
	{ .frequency = 216518400,	.driver_data = PLLVAL(171, 5, 2), 	}, 	/* FVco 866.073600 */
	{ .frequency = 222264000,	.driver_data = PLLVAL(97, 2, 2), 	}, 	/* FVco 889.056000 */
	{ .frequency = 228614400,	.driver_data = PLLVAL(127, 3, 2), 	}, 	/* FVco 914.457600 */
	{ .frequency = 234259200,	.driver_data = PLLVAL(158, 4, 2), 	}, 	/* FVco 937.036800 */
	{ .frequency = 240468480,	.driver_data = PLLVAL(134, 3, 2), 	}, 	/* FVco 961.873920 */
	{ .frequency = 246960000,	.driver_data = PLLVAL(167, 4, 2), 	}, 	/* FVco 987.840000 */
	{ .frequency = 252322560,	.driver_data = PLLVAL(141, 3, 2), 	}, 	/* FVco 1009.290240 */
	{ .frequency = 258249600,	.driver_data = PLLVAL(114, 2, 2), 	}, 	/* FVco 1032.998400 */
	{ .frequency = 264176640,	.driver_data = PLLVAL(148, 3, 2), 	}, 	/* FVco 1056.706560 */
	{ .frequency = 270950400,	.driver_data = PLLVAL(120, 2, 2), 	}, 	/* FVco 1083.801600 */
	{ .frequency = 276030720,	.driver_data = PLLVAL(155, 3, 2), 	}, 	/* FVco 1104.122880 */
	{ .frequency = 282240000,	.driver_data = PLLVAL(92, 1, 2), 	}, 	/* FVco 1128.960000 */
	{ .frequency = 289578240,	.driver_data = PLLVAL(163, 3, 2), 	}, 	/* FVco 1158.312960 */
	{ .frequency = 294235200,	.driver_data = PLLVAL(131, 2, 2), 	}, 	/* FVco 1176.940800 */
	{ .frequency = 300200727,	.driver_data = PLLVAL(187, 9, 1), 	}, 	/* FVco 600.401454 */
	{ .frequency = 306358690,	.driver_data = PLLVAL(191, 9, 1), 	}, 	/* FVco 612.717380 */
	{ .frequency = 312076800,	.driver_data = PLLVAL(121, 5, 1), 	}, 	/* FVco 624.153600 */
	{ .frequency = 318366720,	.driver_data = PLLVAL(86, 3, 1), 	}, 	/* FVco 636.733440 */
	{ .frequency = 324172800,	.driver_data = PLLVAL(126, 5, 1), 	}, 	/* FVco 648.345600 */
	{ .frequency = 330220800,	.driver_data = PLLVAL(109, 4, 1), 	}, 	/* FVco 660.441600 */
	{ .frequency = 336268800,	.driver_data = PLLVAL(131, 5, 1), 	}, 	/* FVco 672.537600 */
	{ .frequency = 342074880,	.driver_data = PLLVAL(93, 3, 1), 	}, 	/* FVco 684.149760 */
	{ .frequency = 348096000,	.driver_data = PLLVAL(177, 7, 1), 	}, 	/* FVco 696.192000 */
	{ .frequency = 355622400,	.driver_data = PLLVAL(118, 4, 1), 	}, 	/* FVco 711.244800 */
	{ .frequency = 360460800,	.driver_data = PLLVAL(141, 5, 1), 	}, 	/* FVco 720.921600 */
	{ .frequency = 366206400,	.driver_data = PLLVAL(165, 6, 1), 	}, 	/* FVco 732.412800 */
	{ .frequency = 372556800,	.driver_data = PLLVAL(124, 4, 1), 	}, 	/* FVco 745.113600 */
	{ .frequency = 378201600,	.driver_data = PLLVAL(126, 4, 1), 	}, 	/* FVco 756.403200 */
	{ .frequency = 384652800,	.driver_data = PLLVAL(151, 5, 1), 	}, 	/* FVco 769.305600 */
	{ .frequency = 391608000,	.driver_data = PLLVAL(177, 6, 1), 	}, 	/* FVco 783.216000 */
	{ .frequency = 396264960,	.driver_data = PLLVAL(109, 3, 1), 	}, 	/* FVco 792.529920 */
	{ .frequency = 402192000,	.driver_data = PLLVAL(87, 2, 1), 	}, 	/* FVco 804.384000 */
};

static int s3c2440_plls169344_add(struct device *dev,
				  struct subsys_interface *sif)
{
	struct clk *xtal_clk;
	unsigned long xtal;

	xtal_clk = clk_get(NULL, "xtal");
	if (IS_ERR(xtal_clk))
		return PTR_ERR(xtal_clk);

	xtal = clk_get_rate(xtal_clk);
	clk_put(xtal_clk);

	if (xtal == 169344000) {
		printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
		return s3c_plltab_register(s3c2440_plls_169344,
					   ARRAY_SIZE(s3c2440_plls_169344));
	}

	return 0;
}

static struct subsys_interface s3c2440_plls169344_interface = {
	.name		= "s3c2440_plls169344",
	.subsys		= &s3c2440_subsys,
	.add_dev	= s3c2440_plls169344_add,
};

static int __init s3c2440_pll_16934400(void)
{
	return subsys_interface_register(&s3c2440_plls169344_interface);
}
arch_initcall(s3c2440_pll_16934400);

static struct subsys_interface s3c2442_plls169344_interface = {
	.name		= "s3c2442_plls169344",
	.subsys		= &s3c2442_subsys,
	.add_dev	= s3c2440_plls169344_add,
};

static int __init s3c2442_pll_16934400(void)
{
	return subsys_interface_register(&s3c2442_plls169344_interface);
}
arch_initcall(s3c2442_pll_16934400);


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (C) 2013 Samsung Electronics Co., Ltd.
//	Tomasz Figa <t.figa@samsung.com>
// Copyright (C) 2008 Openmoko, Inc.
// Copyright (C) 2004-2008 Simtec Electronics
//	Ben Dooks <ben@simtec.co.uk>
//	http://armlinux.simtec.co.uk/
//
// Samsung common power management helper functions.

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

#include "pm-common.h"

/* helper functions to save and restore register state */

/**
 * s3c_pm_do_save() - save a set of registers for restoration on resume.
 * @ptr: Pointer to an array of registers.
 * @count: Size of the ptr array.
 *
 * Run through the list of registers given, saving their contents in the
 * array for later restoration when we wakeup.
 */
void s3c_pm_do_save(struct sleep_save *ptr, int count)
{
	for (; count > 0; count--, ptr++) {
		ptr->val = readl_relaxed(ptr->reg);
		S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
	}
}

/**
 * s3c_pm_do_restore() - restore register values from the save list.
 * @ptr: Pointer to an array of registers.
 * @count: Size of the ptr array.
 *
 * Restore the register values saved from s3c_pm_do_save().
 *
 * Note, we do not use S3C_PMDBG() in here, as the system may not have
 * restore the UARTs state yet
*/

void s3c_pm_do_restore(const struct sleep_save *ptr, int count)
{
	for (; count > 0; count--, ptr++) {
		pr_debug("restore %p (restore %08lx, was %08x)\n",
				ptr->reg, ptr->val, readl_relaxed(ptr->reg));

		writel_relaxed(ptr->val, ptr->reg);
	}
}

/**
 * s3c_pm_do_restore_core() - early restore register values from save list.
 * @ptr: Pointer to an array of registers.
 * @count: Size of the ptr array.
 *
 * This is similar to s3c_pm_do_restore() except we try and minimise the
 * side effects of the function in case registers that hardware might need
 * to work has been restored.
 *
 * WARNING: Do not put any debug in here that may effect memory or use
 * peripherals, as things may be changing!
*/

void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count)
{
	for (; count > 0; count--, ptr++)
		writel_relaxed(ptr->val, ptr->reg);
}


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
 *	Tomasz Figa <t.figa@samsung.com>
 * Copyright (c) 2004 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Written by Ben Dooks, <ben@simtec.co.uk>
 */

#ifndef __PLAT_SAMSUNG_PM_COMMON_H
#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__

#include <linux/irq.h>
#include <linux/soc/samsung/s3c-pm.h>

/* sleep save info */

/**
 * struct sleep_save - save information for shared peripherals.
 * @reg: Pointer to the register to save.
 * @val: Holder for the value saved from reg.
 *
 * This describes a list of registers which is used by the pm core and
 * other subsystem to save and restore register values over suspend.
 */
struct sleep_save {
	void __iomem	*reg;
	unsigned long	val;
};

#define SAVE_ITEM(x) \
	{ .reg = (x) }

/* helper functions to save/restore lists of registers. */

extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count);
extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count);

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2008 Simtec Electronics
 *      Ben Dooks <ben@simtec.co.uk>
 *      http://armlinux.simtec.co.uk/
 *
 * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c
 */

#include <linux/delay.h>
#include <linux/io.h>

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

static inline void s3c_pm_debug_init_uart(void)
{
#ifdef CONFIG_SAMSUNG_PM_DEBUG
	unsigned long tmp = __raw_readl(S3C2410_CLKCON);

	/* re-start uart clocks */
	tmp |= S3C2410_CLKCON_UART0;
	tmp |= S3C2410_CLKCON_UART1;
	tmp |= S3C2410_CLKCON_UART2;

	__raw_writel(tmp, S3C2410_CLKCON);
	udelay(10);
#endif
}

static inline void s3c_pm_arch_prepare_irqs(void)
{
	__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
	__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);

	/* ack any outstanding external interrupts before we go to sleep */

	__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
	__raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
	__raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);

}

static inline void s3c_pm_arch_stop_clocks(void)
{
	__raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
}

/* s3c2410_pm_show_resume_irqs
 *
 * print any IRQs asserted at resume time (ie, we woke from)
*/
static inline void s3c_pm_show_resume_irqs(int start, unsigned long which,
					   unsigned long mask)
{
	int i;

	which &= ~mask;

	for (i = 0; i <= 31; i++) {
		if (which & (1L<<i)) {
			S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
		}
	}
}

static inline void s3c_pm_arch_show_resume_irqs(void)
{
	S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
		  __raw_readl(S3C2410_SRCPND),
		  __raw_readl(S3C2410_EINTPEND));

	s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
				s3c_irqwake_intmask);

	s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
				s3c_irqwake_eintmask);
}

static inline void s3c_pm_restored_gpios(void) { }
static inline void samsung_pm_saved_gpios(void) { }

/* state for IRQs over sleep */

/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
 *
 * set bit to 1 in allow bitfield to enable the wakeup settings on it
*/
#ifdef CONFIG_PM_SLEEP
#define s3c_irqwake_intallow	(1L << 30 | 0xfL)
#define s3c_irqwake_eintallow	(0x0000fff0L)
#else
#define s3c_irqwake_eintallow 0
#define s3c_irqwake_intallow  0
#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2008 Openmoko, Inc.
 * Copyright 2008 Simtec Electronics
 *      Ben Dooks <ben@simtec.co.uk>
 *      http://armlinux.simtec.co.uk/
 *
 * S3C64XX - PM core support for arch/arm/plat-s3c/pm.c
 */

#ifndef __MACH_S3C64XX_PM_CORE_H
#define __MACH_S3C64XX_PM_CORE_H __FILE__

#include <linux/serial_s3c.h>
#include <linux/delay.h>

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

static inline void s3c_pm_debug_init_uart(void)
{
#ifdef CONFIG_SAMSUNG_PM_DEBUG
	u32 tmp = __raw_readl(S3C_PCLK_GATE);

	/* As a note, since the S3C64XX UARTs generally have multiple
	 * clock sources, we simply enable PCLK at the moment and hope
	 * that the resume settings for the UART are suitable for the
	 * use with PCLK.
	 */

	tmp |= S3C_CLKCON_PCLK_UART0;
	tmp |= S3C_CLKCON_PCLK_UART1;
	tmp |= S3C_CLKCON_PCLK_UART2;
	tmp |= S3C_CLKCON_PCLK_UART3;

	__raw_writel(tmp, S3C_PCLK_GATE);
	udelay(10);
#endif
}

static inline void s3c_pm_arch_prepare_irqs(void)
{
	/* VIC should have already been taken care of */

	/* clear any pending EINT0 interrupts */
	__raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
}

static inline void s3c_pm_arch_stop_clocks(void)
{
}

static inline void s3c_pm_arch_show_resume_irqs(void)
{
}

/* make these defines, we currently do not have any need to change
 * the IRQ wake controls depending on the CPU we are running on */
#ifdef CONFIG_PM_SLEEP
#define s3c_irqwake_eintallow	((1 << 28) - 1)
#define s3c_irqwake_intallow	(~0)
#else
#define s3c_irqwake_eintallow 0
#define s3c_irqwake_intallow  0
#endif

static inline void s3c_pm_restored_gpios(void)
{
	/* ensure sleep mode has been cleared from the system */

	__raw_writel(0, S3C64XX_SLPEN);
}

static inline void samsung_pm_saved_gpios(void)
{
	/* turn on the sleep mode and keep it there, as it seems that during
	 * suspend the xCON registers get re-set and thus you can end up with
	 * problems between going to sleep and resuming.
	 */

	__raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN);
}
#endif /* __MACH_S3C64XX_PM_CORE_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */

#ifdef CONFIG_ARCH_S3C24XX
#include "pm-core-s3c24xx.h"
#endif

#ifdef CONFIG_ARCH_S3C64XX
#include "pm-core-s3c64xx.h"
#endif


code:
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright 2008 Openmoko, Inc.
// Copyright 2008 Simtec Electronics
//	Ben Dooks <ben@simtec.co.uk>
//	http://armlinux.simtec.co.uk/
//
// S3C series GPIO PM code

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/gpio.h>

#include "gpio-samsung.h"

#include "gpio-core.h"
#include "pm.h"

/* PM GPIO helpers */

#define OFFS_CON	(0x00)
#define OFFS_DAT	(0x04)
#define OFFS_UP		(0x08)

static void samsung_gpio_pm_1bit_save(struct samsung_gpio_chip *chip)
{
	chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
	chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
}

static void samsung_gpio_pm_1bit_resume(struct samsung_gpio_chip *chip)
{
	void __iomem *base = chip->base;
	u32 old_gpcon = __raw_readl(base + OFFS_CON);
	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
	u32 gps_gpcon = chip->pm_save[0];
	u32 gps_gpdat = chip->pm_save[1];
	u32 gpcon;

	/* GPACON only has one bit per control / data and no PULLUPs.
	 * GPACON[x] = 0 => Output, 1 => SFN */

	/* first set all SFN bits to SFN */

	gpcon = old_gpcon | gps_gpcon;
	__raw_writel(gpcon, base + OFFS_CON);

	/* now set all the other bits */

	__raw_writel(gps_gpdat, base + OFFS_DAT);
	__raw_writel(gps_gpcon, base + OFFS_CON);

	S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
		  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
}

struct samsung_gpio_pm samsung_gpio_pm_1bit = {
	.save	= samsung_gpio_pm_1bit_save,
	.resume = samsung_gpio_pm_1bit_resume,
};

static void samsung_gpio_pm_2bit_save(struct samsung_gpio_chip *chip)
{
	chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
	chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
	chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
}

/* Test whether the given masked+shifted bits of an GPIO configuration
 * are one of the SFN (special function) modes. */

static inline int is_sfn(unsigned long con)
{
	return con >= 2;
}

/* Test if the given masked+shifted GPIO configuration is an input */

static inline int is_in(unsigned long con)
{
	return con == 0;
}

/* Test if the given masked+shifted GPIO configuration is an output */

static inline int is_out(unsigned long con)
{
	return con == 1;
}

/**
 * samsung_gpio_pm_2bit_resume() - restore the given GPIO bank
 * @chip: The chip information to resume.
 *
 * Restore one of the GPIO banks that was saved during suspend. This is
 * not as simple as once thought, due to the possibility of glitches
 * from the order that the CON and DAT registers are set in.
 *
 * The three states the pin can be are {IN,OUT,SFN} which gives us 9
 * combinations of changes to check. Three of these, if the pin stays
 * in the same configuration can be discounted. This leaves us with
 * the following:
 *
 * { IN => OUT }  Change DAT first
 * { IN => SFN }  Change CON first
 * { OUT => SFN } Change CON first, so new data will not glitch
 * { OUT => IN }  Change CON first, so new data will not glitch
 * { SFN => IN }  Change CON first
 * { SFN => OUT } Change DAT first, so new data will not glitch [1]
 *
 * We do not currently deal with the UP registers as these control
 * weak resistors, so a small delay in change should not need to bring
 * these into the calculations.
 *
 * [1] this assumes that writing to a pin DAT whilst in SFN will set the
 *     state for when it is next output.
 */
static void samsung_gpio_pm_2bit_resume(struct samsung_gpio_chip *chip)
{
	void __iomem *base = chip->base;
	u32 old_gpcon = __raw_readl(base + OFFS_CON);
	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
	u32 gps_gpcon = chip->pm_save[0];
	u32 gps_gpdat = chip->pm_save[1];
	u32 gpcon, old, new, mask;
	u32 change_mask = 0x0;
	int nr;

	/* restore GPIO pull-up settings */
	__raw_writel(chip->pm_save[2], base + OFFS_UP);

	/* Create a change_mask of all the items that need to have
	 * their CON value changed before their DAT value, so that
	 * we minimise the work between the two settings.
	 */

	for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
		old = (old_gpcon & mask) >> nr;
		new = (gps_gpcon & mask) >> nr;

		/* If there is no change, then skip */

		if (old == new)
			continue;

		/* If both are special function, then skip */

		if (is_sfn(old) && is_sfn(new))
			continue;

		/* Change is IN => OUT, do not change now */

		if (is_in(old) && is_out(new))
			continue;

		/* Change is SFN => OUT, do not change now */

		if (is_sfn(old) && is_out(new))
			continue;

		/* We should now be at the case of IN=>SFN,
		 * OUT=>SFN, OUT=>IN, SFN=>IN. */

		change_mask |= mask;
	}

	/* Write the new CON settings */

	gpcon = old_gpcon & ~change_mask;
	gpcon |= gps_gpcon & change_mask;

	__raw_writel(gpcon, base + OFFS_CON);

	/* Now change any items that require DAT,CON */

	__raw_writel(gps_gpdat, base + OFFS_DAT);
	__raw_writel(gps_gpcon, base + OFFS_CON);

	S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
		  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
}

struct samsung_gpio_pm samsung_gpio_pm_2bit = {
	.save	= samsung_gpio_pm_2bit_save,
	.resume = samsung_gpio_pm_2bit_resume,
};

#if defined(CONFIG_ARCH_S3C64XX)
static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip)
{
	chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
	chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
	chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);

	if (chip->chip.ngpio > 8)
		chip->pm_save[0] = __raw_readl(chip->base - 4);
}

static u32 samsung_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
{
	u32 old, new, mask;
	u32 change_mask = 0x0;
	int nr;

	for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
		old = (old_gpcon & mask) >> nr;
		new = (gps_gpcon & mask) >> nr;

		/* If there is no change, then skip */

		if (old == new)
			continue;

		/* If both are special function, then skip */

		if (is_sfn(old) && is_sfn(new))
			continue;

		/* Change is IN => OUT, do not change now */

		if (is_in(old) && is_out(new))
			continue;

		/* Change is SFN => OUT, do not change now */

		if (is_sfn(old) && is_out(new))
			continue;

		/* We should now be at the case of IN=>SFN,
		 * OUT=>SFN, OUT=>IN, SFN=>IN. */

		change_mask |= mask;
	}

	return change_mask;
}

static void samsung_gpio_pm_4bit_con(struct samsung_gpio_chip *chip, int index)
{
	void __iomem *con = chip->base + (index * 4);
	u32 old_gpcon = __raw_readl(con);
	u32 gps_gpcon = chip->pm_save[index + 1];
	u32 gpcon, mask;

	mask = samsung_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);

	gpcon = old_gpcon & ~mask;
	gpcon |= gps_gpcon & mask;

	__raw_writel(gpcon, con);
}

static void samsung_gpio_pm_4bit_resume(struct samsung_gpio_chip *chip)
{
	void __iomem *base = chip->base;
	u32 old_gpcon[2];
	u32 old_gpdat = __raw_readl(base + OFFS_DAT);
	u32 gps_gpdat = chip->pm_save[2];

	/* First, modify the CON settings */

	old_gpcon[0] = 0;
	old_gpcon[1] = __raw_readl(base + OFFS_CON);

	samsung_gpio_pm_4bit_con(chip, 0);
	if (chip->chip.ngpio > 8) {
		old_gpcon[0] = __raw_readl(base - 4);
		samsung_gpio_pm_4bit_con(chip, -1);
	}

	/* Now change the configurations that require DAT,CON */

	__raw_writel(chip->pm_save[2], base + OFFS_DAT);
	__raw_writel(chip->pm_save[1], base + OFFS_CON);
	if (chip->chip.ngpio > 8)
		__raw_writel(chip->pm_save[0], base - 4);

	__raw_writel(chip->pm_save[2], base + OFFS_DAT);
	__raw_writel(chip->pm_save[3], base + OFFS_UP);

	if (chip->chip.ngpio > 8) {
		S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
			  chip->chip.label, old_gpcon[0], old_gpcon[1],
			  __raw_readl(base - 4),
			  __raw_readl(base + OFFS_CON),
			  old_gpdat, gps_gpdat);
	} else
		S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
			  chip->chip.label, old_gpcon[1],
			  __raw_readl(base + OFFS_CON),
			  old_gpdat, gps_gpdat);
}

struct samsung_gpio_pm samsung_gpio_pm_4bit = {
	.save	= samsung_gpio_pm_4bit_save,
	.resume = samsung_gpio_pm_4bit_resume,
};
#endif /* CONFIG_ARCH_S3C64XX */

/**
 * samsung_pm_save_gpio() - save gpio chip data for suspend
 * @ourchip: The chip for suspend.
 */
static void samsung_pm_save_gpio(struct samsung_gpio_chip *ourchip)
{
	struct samsung_gpio_pm *pm = ourchip->pm;

	if (pm == NULL || pm->save == NULL)
		S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
	else
		pm->save(ourchip);
}

/**
 * samsung_pm_save_gpios() - Save the state of the GPIO banks.
 *
 * For all the GPIO banks, save the state of each one ready for going
 * into a suspend mode.
 */
void samsung_pm_save_gpios(void)
{
	struct samsung_gpio_chip *ourchip;
	unsigned int gpio_nr;

	for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
		ourchip = samsung_gpiolib_getchip(gpio_nr);
		if (!ourchip) {
			gpio_nr++;
			continue;
		}

		samsung_pm_save_gpio(ourchip);

		S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
			  ourchip->chip.label,
			  ourchip->pm_save[0],
			  ourchip->pm_save[1],
			  ourchip->pm_save[2],
			  ourchip->pm_save[3]);

		gpio_nr += ourchip->chip.ngpio;
		gpio_nr += CONFIG_S3C_GPIO_SPACE;
	}
}

/**
 * samsung_pm_resume_gpio() - restore gpio chip data after suspend
 * @ourchip: The suspended chip.
 */
static void samsung_pm_resume_gpio(struct samsung_gpio_chip *ourchip)
{
	struct samsung_gpio_pm *pm = ourchip->pm;

	if (pm == NULL || pm->resume == NULL)
		S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
	else
		pm->resume(ourchip);
}

void samsung_pm_restore_gpios(void)
{
	struct samsung_gpio_chip *ourchip;
	unsigned int gpio_nr;

	for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
		ourchip = samsung_gpiolib_getchip(gpio_nr);
		if (!ourchip) {
			gpio_nr++;
			continue;
		}

		samsung_pm_resume_gpio(ourchip);

		gpio_nr += ourchip->chip.ngpio;
		gpio_nr += CONFIG_S3C_GPIO_SPACE;
	}
}


code:
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (c) 2006 Ben Dooks <ben-linux@fluff.org>
 *
 * H1940 Suspend to RAM
 */

#include <linux/linkage.h>
#include <asm/assembler.h>
#include "map.h"

#include "regs-gpio.h"

	.text
	.global	h1940_pm_return

h1940_pm_return:
	mov	r0, #S3C2410_PA_GPIO
	ldr	pc, [r0, #S3C2410_GSTATUS3 - S3C24XX_VA_GPIO]


code:
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2006 Simtec Electronics
//	Ben Dooks <ben@simtec.co.uk>
//
// S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support

#include <linux/init.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/syscore_ops.h>
#include <linux/gpio.h>
#include <linux/io.h>

#include <asm/mach-types.h>

#include "regs-gpio.h"
#include "gpio-samsung.h"

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

#include "h1940.h"

static void s3c2410_pm_prepare(void)
{
	/* ensure at least GSTATUS3 has the resume address */

	__raw_writel(__pa_symbol(s3c_cpu_resume), S3C2410_GSTATUS3);

	S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
	S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));

	if (machine_is_h1940()) {
		void *base = phys_to_virt(H1940_SUSPEND_CHECK);
		unsigned long ptr;
		unsigned long calc = 0;

		/* generate check for the bootloader to check on resume */

		for (ptr = 0; ptr < 0x40000; ptr += 0x400)
			calc += __raw_readl(base+ptr);

		__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
	}

	/* RX3715 and RX1950 use similar to H1940 code and the
	 * same offsets for resume and checksum pointers */

	if (machine_is_rx3715() || machine_is_rx1950()) {
		void *base = phys_to_virt(H1940_SUSPEND_CHECK);
		unsigned long ptr;
		unsigned long calc = 0;

		/* generate check for the bootloader to check on resume */

		for (ptr = 0; ptr < 0x40000; ptr += 0x4)
			calc += __raw_readl(base+ptr);

		__raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
	}

	if (machine_is_aml_m5900()) {
		gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_HIGH, NULL);
		gpio_free(S3C2410_GPF(2));
	}

	if (machine_is_rx1950()) {
		/* According to S3C2442 user's manual, page 7-17,
		 * when the system is operating in NAND boot mode,
		 * the hardware pin configuration - EINT[23:21] –
		 * must be set as input for starting up after
		 * wakeup from sleep mode
		 */
		s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
		s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
		s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
	}
}

static void s3c2410_pm_resume(void)
{
	unsigned long tmp;

	/* unset the return-from-sleep flag, to ensure reset */

	tmp = __raw_readl(S3C2410_GSTATUS2);
	tmp &= S3C2410_GSTATUS2_OFFRESET;
	__raw_writel(tmp, S3C2410_GSTATUS2);

	if (machine_is_aml_m5900()) {
		gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_LOW, NULL);
		gpio_free(S3C2410_GPF(2));
	}
}

struct syscore_ops s3c2410_pm_syscore_ops = {
	.resume		= s3c2410_pm_resume,
};

static int s3c2410_pm_add(struct device *dev, struct subsys_interface *sif)
{
	pm_cpu_prep = s3c2410_pm_prepare;
	pm_cpu_sleep = s3c2410_cpu_suspend;

	return 0;
}

#if defined(CONFIG_CPU_S3C2410)
static struct subsys_interface s3c2410_pm_interface = {
	.name		= "s3c2410_pm",
	.subsys		= &s3c2410_subsys,
	.add_dev	= s3c2410_pm_add,
};

/* register ourselves */

static int __init s3c2410_pm_drvinit(void)
{
	return subsys_interface_register(&s3c2410_pm_interface);
}

arch_initcall(s3c2410_pm_drvinit);

static struct subsys_interface s3c2410a_pm_interface = {
	.name		= "s3c2410a_pm",
	.subsys		= &s3c2410a_subsys,
	.add_dev	= s3c2410_pm_add,
};

static int __init s3c2410a_pm_drvinit(void)
{
	return subsys_interface_register(&s3c2410a_pm_interface);
}

arch_initcall(s3c2410a_pm_drvinit);
#endif

#if defined(CONFIG_CPU_S3C2440)
static struct subsys_interface s3c2440_pm_interface = {
	.name		= "s3c2440_pm",
	.subsys		= &s3c2440_subsys,
	.add_dev	= s3c2410_pm_add,
};

static int __init s3c2440_pm_drvinit(void)
{
	return subsys_interface_register(&s3c2440_pm_interface);
}

arch_initcall(s3c2440_pm_drvinit);
#endif

#if defined(CONFIG_CPU_S3C2442)
static struct subsys_interface s3c2442_pm_interface = {
	.name		= "s3c2442_pm",
	.subsys		= &s3c2442_subsys,
	.add_dev	= s3c2410_pm_add,
};

static int __init s3c2442_pm_drvinit(void)
{
	return subsys_interface_register(&s3c2442_pm_interface);
}

arch_initcall(s3c2442_pm_drvinit);
#endif


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2006 Simtec Electronics
//	Ben Dooks <ben@simtec.co.uk>
//
// http://armlinux.simtec.co.uk/.

#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/device.h>
#include <linux/syscore_ops.h>
#include <linux/platform_device.h>
#include <linux/io.h>

#include <asm/cacheflush.h>
#include <asm/irq.h>

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

#include "cpu.h"
#include "pm.h"
#include "wakeup-mask.h"

#include "regs-dsc-s3c24xx.h"
#include "s3c2412-power.h"

extern void s3c2412_sleep_enter(void);

static int s3c2412_cpu_suspend(unsigned long arg)
{
	unsigned long tmp;

	/* set our standby method to sleep */

	tmp = __raw_readl(S3C2412_PWRCFG);
	tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
	__raw_writel(tmp, S3C2412_PWRCFG);

	s3c2412_sleep_enter();

	pr_info("Failed to suspend the system\n");
	return 1; /* Aborting suspend */
}

/* mapping of interrupts to parts of the wakeup mask */
static const struct samsung_wakeup_mask wake_irqs[] = {
	{ .irq = IRQ_RTC,	.bit = S3C2412_PWRCFG_RTC_MASKIRQ, },
};

static void s3c2412_pm_prepare(void)
{
	samsung_sync_wakemask(S3C2412_PWRCFG,
			      wake_irqs, ARRAY_SIZE(wake_irqs));
}

static int s3c2412_pm_add(struct device *dev, struct subsys_interface *sif)
{
	pm_cpu_prep = s3c2412_pm_prepare;
	pm_cpu_sleep = s3c2412_cpu_suspend;

	return 0;
}

static struct sleep_save s3c2412_sleep[] = {
	SAVE_ITEM(S3C2412_DSC0),
	SAVE_ITEM(S3C2412_DSC1),
	SAVE_ITEM(S3C2413_GPJDAT),
	SAVE_ITEM(S3C2413_GPJCON),
	SAVE_ITEM(S3C2413_GPJUP),

	/* save the PWRCFG to get back to original sleep method */

	SAVE_ITEM(S3C2412_PWRCFG),

	/* save the sleep configuration anyway, just in case these
	 * get damaged during wakeup */

	SAVE_ITEM(S3C2412_GPBSLPCON),
	SAVE_ITEM(S3C2412_GPCSLPCON),
	SAVE_ITEM(S3C2412_GPDSLPCON),
	SAVE_ITEM(S3C2412_GPFSLPCON),
	SAVE_ITEM(S3C2412_GPGSLPCON),
	SAVE_ITEM(S3C2412_GPHSLPCON),
	SAVE_ITEM(S3C2413_GPJSLPCON),
};

static struct subsys_interface s3c2412_pm_interface = {
	.name		= "s3c2412_pm",
	.subsys		= &s3c2412_subsys,
	.add_dev	= s3c2412_pm_add,
};

static __init int s3c2412_pm_init(void)
{
	return subsys_interface_register(&s3c2412_pm_interface);
}

arch_initcall(s3c2412_pm_init);

static int s3c2412_pm_suspend(void)
{
	s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
	return 0;
}

static void s3c2412_pm_resume(void)
{
	unsigned long tmp;

	tmp = __raw_readl(S3C2412_PWRCFG);
	tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
	tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
	__raw_writel(tmp, S3C2412_PWRCFG);

	s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
}

struct syscore_ops s3c2412_pm_syscore_ops = {
	.suspend	= s3c2412_pm_suspend,
	.resume		= s3c2412_pm_resume,
};


code:
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2010 Samsung Electronics Co., Ltd.
//		http://www.samsung.com
//
// S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)

#include <linux/device.h>
#include <linux/syscore_ops.h>
#include <linux/io.h>

#include <asm/cacheflush.h>

#include "regs-s3c2443-clock.h"

#include "cpu.h"
#include "pm.h"

#include "s3c2412-power.h"

#ifdef CONFIG_PM_SLEEP
extern void s3c2412_sleep_enter(void);

static int s3c2416_cpu_suspend(unsigned long arg)
{
	/* enable wakeup sources regardless of battery state */
	__raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);

	/* set the mode as sleep, 2BED represents "Go to BED" */
	__raw_writel(0x2BED, S3C2443_PWRMODE);

	s3c2412_sleep_enter();

	pr_info("Failed to suspend the system\n");
	return 1; /* Aborting suspend */
}

static void s3c2416_pm_prepare(void)
{
	/*
	 * write the magic value u-boot uses to check for resume into
	 * the INFORM0 register, and ensure INFORM1 is set to the
	 * correct address to resume from.
	 */
	__raw_writel(0x2BED, S3C2412_INFORM0);
	__raw_writel(__pa_symbol(s3c_cpu_resume), S3C2412_INFORM1);
}

static int s3c2416_pm_add(struct device *dev, struct subsys_interface *sif)
{
	pm_cpu_prep = s3c2416_pm_prepare;
	pm_cpu_sleep = s3c2416_cpu_suspend;

	return 0;
}

static struct subsys_interface s3c2416_pm_interface = {
	.name		= "s3c2416_pm",
	.subsys		= &s3c2416_subsys,
	.add_dev	= s3c2416_pm_add,
};

static __init int s3c2416_pm_init(void)
{
	return subsys_interface_register(&s3c2416_pm_interface);
}

arch_initcall(s3c2416_pm_init);
#endif

static void s3c2416_pm_resume(void)
{
	/* unset the return-from-sleep amd inform flags */
	__raw_writel(0x0, S3C2443_PWRMODE);
	__raw_writel(0x0, S3C2412_INFORM0);
	__raw_writel(0x0, S3C2412_INFORM1);
}

struct syscore_ops s3c2416_pm_syscore_ops = {
	.resume		= s3c2416_pm_resume,
};