summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 23:17:06 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 23:17:06 +0400
commitff877c498eb2f9c4ea386270642e383bc867f63c (patch)
treeae37e2f57ac6e6d19d01b7380f77db2a1c6c5b14
parent529b73fc0a9764050dcc597f4851728e8ff59165 (diff)
parent1f5b7dcfdad3840d4bce27ab0b3cc8f376b81544 (diff)
downloadlinux-ff877c498eb2f9c4ea386270642e383bc867f63c.tar.xz
Merge tag 'drivers2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull "ARM: More SoC driver updates" from Olof Johansson: "This branch contains a handful of driver updates, mostly to the LPC32xx platform but also for Samsung EXYNOS and Davinci. It had a few context conflicts against patches already merged through fixes-non-critical. We should have resolved this early during the development cycle by pulling them in as a dependency, instead I did it after the fact this time." * tag 'drivers2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: gpio/samsung: use ioremap() for EXYNOS4 GPIOlib gpio/samsung: add support GPIOlib for EXYNOS5250 ARM: EXYNOS: add support GPIO for EXYNOS5250 ARM: LPC32xx: Ethernet support ARM: LPC32xx: USB Support ARM: davinci: dm644x evm: add support for VPBE display ARM: davinci: dm644x: add support for v4l2 video display ARM: EXYNOS: Hook up JPEG PD to generic PD infrastructure ARM: EXYNOS: Hook up G2D PD to generic PD infrastructure arm: lpc32xx: phy3250: add rtc & touch device ARM: LPC32xx: clock.c: Clock registration fixes ARM: LPC32xx: clock.c: jiffies wrapping ARM: LPC32xx: clock.c: Missing header file ARM: LPC32XX: Remove broken non-static declaration ARM: LPC32xx: clock.c: Fix mutex lock issues ARM: LPC32xx: clock.c: warning fix ARM: LPC32xx: Added lpc32xx_defconfig
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c109
-rw-r--r--arch/arm/mach-davinci/davinci.h8
-rw-r--r--arch/arm/mach-davinci/dm644x.c166
-rw-r--r--arch/arm/mach-exynos/common.c15
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio.h239
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h4
-rw-r--r--arch/arm/mach-exynos/pm_domains.c6
-rw-r--r--arch/arm/mach-lpc32xx/Kconfig25
-rw-r--r--arch/arm/mach-lpc32xx/clock.c87
-rw-r--r--arch/arm/mach-lpc32xx/common.c47
-rw-r--r--arch/arm/mach-lpc32xx/common.h4
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/board.h24
-rw-r--r--arch/arm/mach-lpc32xx/irq.c4
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c3
-rw-r--r--drivers/gpio/gpio-samsung.c487
15 files changed, 1080 insertions, 148 deletions
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 864f676eccac..3683306e0245 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -613,6 +613,113 @@ static void __init evm_init_i2c(void)
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
}
+#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+/* venc standard timings */
+static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
+ {
+ .name = "ntsc",
+ .timings_type = VPBE_ENC_STD,
+ .timings = {V4L2_STD_525_60},
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 480,
+ .aspect = {11, 10},
+ .fps = {30000, 1001},
+ .left_margin = 0x79,
+ .upper_margin = 0x10,
+ },
+ {
+ .name = "pal",
+ .timings_type = VPBE_ENC_STD,
+ .timings = {V4L2_STD_625_50},
+ .interlaced = 1,
+ .xres = 720,
+ .yres = 576,
+ .aspect = {54, 59},
+ .fps = {25, 1},
+ .left_margin = 0x7e,
+ .upper_margin = 0x16,
+ },
+};
+
+/* venc dv preset timings */
+static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
+ {
+ .name = "480p59_94",
+ .timings_type = VPBE_ENC_DV_PRESET,
+ .timings = {V4L2_DV_480P59_94},
+ .interlaced = 0,
+ .xres = 720,
+ .yres = 480,
+ .aspect = {1, 1},
+ .fps = {5994, 100},
+ .left_margin = 0x80,
+ .upper_margin = 0x20,
+ },
+ {
+ .name = "576p50",
+ .timings_type = VPBE_ENC_DV_PRESET,
+ .timings = {V4L2_DV_576P50},
+ .interlaced = 0,
+ .xres = 720,
+ .yres = 576,
+ .aspect = {1, 1},
+ .fps = {50, 1},
+ .left_margin = 0x7e,
+ .upper_margin = 0x30,
+ },
+};
+
+/*
+ * The outputs available from VPBE + encoders. Keep the order same
+ * as that of encoders. First those from venc followed by that from
+ * encoders. Index in the output refers to index on a particular encoder.
+ * Driver uses this index to pass it to encoder when it supports more
+ * than one output. Userspace applications use index of the array to
+ * set an output.
+ */
+static struct vpbe_output dm644xevm_vpbe_outputs[] = {
+ {
+ .output = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .std = VENC_STD_ALL,
+ .capabilities = V4L2_OUT_CAP_STD,
+ },
+ .subdev_name = VPBE_VENC_SUBDEV_NAME,
+ .default_mode = "ntsc",
+ .num_modes = ARRAY_SIZE(dm644xevm_enc_std_timing),
+ .modes = dm644xevm_enc_std_timing,
+ },
+ {
+ .output = {
+ .index = 1,
+ .name = "Component",
+ .type = V4L2_OUTPUT_TYPE_ANALOG,
+ .capabilities = V4L2_OUT_CAP_PRESETS,
+ },
+ .subdev_name = VPBE_VENC_SUBDEV_NAME,
+ .default_mode = "480p59_94",
+ .num_modes = ARRAY_SIZE(dm644xevm_enc_preset_timing),
+ .modes = dm644xevm_enc_preset_timing,
+ },
+};
+
+static struct vpbe_config dm644xevm_display_cfg = {
+ .module_name = "dm644x-vpbe-display",
+ .i2c_adapter_id = 1,
+ .osd = {
+ .module_name = VPBE_OSD_SUBDEV_NAME,
+ },
+ .venc = {
+ .module_name = VPBE_VENC_SUBDEV_NAME,
+ },
+ .num_outputs = ARRAY_SIZE(dm644xevm_vpbe_outputs),
+ .outputs = dm644xevm_vpbe_outputs,
+};
+
static struct platform_device *davinci_evm_devices[] __initdata = {
&davinci_fb_device,
&rtc_dev,
@@ -696,7 +803,7 @@ static __init void davinci_evm_init(void)
evm_init_i2c();
davinci_setup_mmc(0, &dm6446evm_mmc_config);
- dm644x_init_video(&dm644xevm_capture_cfg);
+ dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg);
davinci_serial_init(&uart_config);
dm644x_init_asp(&dm644x_evm_snd_data);
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 9d708034b57f..3e519dad5bb9 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -29,9 +29,15 @@
#include <media/davinci/vpfe_capture.h>
#include <media/davinci/vpif_types.h>
+#include <media/davinci/vpss.h>
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe_venc.h>
+#include <media/davinci/vpbe.h>
+#include <media/davinci/vpbe_osd.h>
#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
#define SYSMOD_VIDCLKCTL 0x38
+#define SYSMOD_VPSS_CLKCTL 0x44
#define SYSMOD_VDD3P3VPWDN 0x48
#define SYSMOD_VSCLKDIS 0x6c
#define SYSMOD_PUPDCTL1 0x7c
@@ -83,7 +89,7 @@ void dm365_set_vpfe_config(struct vpfe_config *cfg);
/* DM644x function declarations */
void __init dm644x_init(void);
void __init dm644x_init_asp(struct snd_platform_data *pdata);
-int __init dm644x_init_video(struct vpfe_config *);
+int __init dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
/* DM646x function declarations */
void __init dm646x_init(void);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 23e81cafba8d..c8b866657fcb 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -627,7 +627,7 @@ static struct resource dm644x_vpfe_resources[] = {
},
};
-static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static u64 dm644x_video_dma_mask = DMA_BIT_MASK(32);
static struct resource dm644x_ccdc_resource[] = {
/* CCDC Base address */
{
@@ -643,7 +643,7 @@ static struct platform_device dm644x_ccdc_dev = {
.num_resources = ARRAY_SIZE(dm644x_ccdc_resource),
.resource = dm644x_ccdc_resource,
.dev = {
- .dma_mask = &vpfe_capture_dma_mask,
+ .dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
@@ -654,7 +654,134 @@ static struct platform_device dm644x_vpfe_dev = {
.num_resources = ARRAY_SIZE(dm644x_vpfe_resources),
.resource = dm644x_vpfe_resources,
.dev = {
- .dma_mask = &vpfe_capture_dma_mask,
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+#define DM644X_OSD_BASE 0x01c72600
+
+static struct resource dm644x_osd_resources[] = {
+ {
+ .start = DM644X_OSD_BASE,
+ .end = DM644X_OSD_BASE + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct osd_platform_data dm644x_osd_data = {
+ .vpbe_type = VPBE_VERSION_1,
+};
+
+static struct platform_device dm644x_osd_dev = {
+ .name = VPBE_OSD_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_osd_resources),
+ .resource = dm644x_osd_resources,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dm644x_osd_data,
+ },
+};
+
+#define DM644X_VENC_BASE 0x01c72400
+
+static struct resource dm644x_venc_resources[] = {
+ {
+ .start = DM644X_VENC_BASE,
+ .end = DM644X_VENC_BASE + 0x17f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+#define DM644X_VPSS_MUXSEL_PLL2_MODE BIT(0)
+#define DM644X_VPSS_MUXSEL_VPBECLK_MODE BIT(1)
+#define DM644X_VPSS_VENCLKEN BIT(3)
+#define DM644X_VPSS_DACCLKEN BIT(4)
+
+static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
+ unsigned int mode)
+{
+ int ret = 0;
+ u32 v = DM644X_VPSS_VENCLKEN;
+
+ switch (type) {
+ case VPBE_ENC_STD:
+ v |= DM644X_VPSS_DACCLKEN;
+ writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+ break;
+ case VPBE_ENC_DV_PRESET:
+ switch (mode) {
+ case V4L2_DV_480P59_94:
+ case V4L2_DV_576P50:
+ v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
+ DM644X_VPSS_DACCLKEN;
+ writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+ break;
+ case V4L2_DV_720P60:
+ case V4L2_DV_1080I60:
+ case V4L2_DV_1080P30:
+ /*
+ * For HD, use external clock source since
+ * HD requires higher clock rate
+ */
+ v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE;
+ writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct resource dm644x_v4l2_disp_resources[] = {
+ {
+ .start = IRQ_VENCINT,
+ .end = IRQ_VENCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm644x_vpbe_display = {
+ .name = "vpbe-v4l2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_v4l2_disp_resources),
+ .resource = dm644x_v4l2_disp_resources,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct venc_platform_data dm644x_venc_pdata = {
+ .venc_type = VPBE_VERSION_1,
+ .setup_clock = dm644x_venc_setup_clock,
+};
+
+static struct platform_device dm644x_venc_dev = {
+ .name = VPBE_VENC_SUBDEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_venc_resources),
+ .resource = dm644x_venc_resources,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dm644x_venc_pdata,
+ },
+};
+
+static struct platform_device dm644x_vpbe_dev = {
+ .name = "vpbe_controller",
+ .id = -1,
+ .dev = {
+ .dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
@@ -786,17 +913,30 @@ void __init dm644x_init(void)
davinci_map_sysmod();
}
-int __init dm644x_init_video(struct vpfe_config *vpfe_cfg)
+int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
+ struct vpbe_config *vpbe_cfg)
{
- dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
-
- /* Add ccdc clock aliases */
- clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
- clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
-
- platform_device_register(&dm644x_vpss_device);
- platform_device_register(&dm644x_ccdc_dev);
- platform_device_register(&dm644x_vpfe_dev);
+ if (vpfe_cfg || vpbe_cfg)
+ platform_device_register(&dm644x_vpss_device);
+
+ if (vpfe_cfg) {
+ dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
+ platform_device_register(&dm644x_ccdc_dev);
+ platform_device_register(&dm644x_vpfe_dev);
+ /* Add ccdc clock aliases */
+ clk_add_alias("master", dm644x_ccdc_dev.name,
+ "vpss_master", NULL);
+ clk_add_alias("slave", dm644x_ccdc_dev.name,
+ "vpss_slave", NULL);
+ }
+
+ if (vpbe_cfg) {
+ dm644x_vpbe_dev.dev.platform_data = vpbe_cfg;
+ platform_device_register(&dm644x_osd_dev);
+ platform_device_register(&dm644x_venc_dev);
+ platform_device_register(&dm644x_vpbe_dev);
+ platform_device_register(&dm644x_vpbe_display);
+ }
return 0;
}
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 97ca2592ce83..d67e21e526e6 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -160,21 +160,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
.length = SZ_4K,
.type = MT_DEVICE,
}, {
- .virtual = (unsigned long)S5P_VA_GPIO1,
- .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_GPIO2,
- .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_GPIO3,
- .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3),
- .length = SZ_256,
- .type = MT_DEVICE,
- }, {
.virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
.length = SZ_64K,
diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h
index 80523ca9bb49..d7498afe036a 100644
--- a/arch/arm/mach-exynos/include/mach/gpio.h
+++ b/arch/arm/mach-exynos/include/mach/gpio.h
@@ -1,9 +1,8 @@
-/* linux/arch/arm/mach-exynos4/include/mach/gpio.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
- * EXYNOS4 - GPIO lib support
+ * EXYNOS - GPIO lib support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,9 +12,13 @@
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H __FILE__
-/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
+/* Macro for EXYNOS GPIO numbering */
+
+#define EXYNOS_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+/* EXYNOS4 GPIO bank sizes */
-/* GPIO bank sizes */
#define EXYNOS4_GPIO_A0_NR (8)
#define EXYNOS4_GPIO_A1_NR (6)
#define EXYNOS4_GPIO_B_NR (8)
@@ -54,52 +57,50 @@
#define EXYNOS4_GPIO_Y6_NR (8)
#define EXYNOS4_GPIO_Z_NR (7)
-/* GPIO bank numbers */
-
-#define EXYNOS4_GPIO_NEXT(__gpio) \
- ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+/* EXYNOS4 GPIO bank numbers */
-enum s5p_gpio_number {
+enum exynos4_gpio_number {
EXYNOS4_GPIO_A0_START = 0,
- EXYNOS4_GPIO_A1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
- EXYNOS4_GPIO_B_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
- EXYNOS4_GPIO_C0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
- EXYNOS4_GPIO_C1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
- EXYNOS4_GPIO_D0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
- EXYNOS4_GPIO_D1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
- EXYNOS4_GPIO_E0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
- EXYNOS4_GPIO_E1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0),
- EXYNOS4_GPIO_E2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1),
- EXYNOS4_GPIO_E3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2),
- EXYNOS4_GPIO_E4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3),
- EXYNOS4_GPIO_F0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4),
- EXYNOS4_GPIO_F1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
- EXYNOS4_GPIO_F2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
- EXYNOS4_GPIO_F3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
- EXYNOS4_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
- EXYNOS4_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0),
- EXYNOS4_GPIO_K0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1),
- EXYNOS4_GPIO_K1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
- EXYNOS4_GPIO_K2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
- EXYNOS4_GPIO_K3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
- EXYNOS4_GPIO_L0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
- EXYNOS4_GPIO_L1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
- EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
- EXYNOS4_GPIO_X0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
- EXYNOS4_GPIO_X1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
- EXYNOS4_GPIO_X2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
- EXYNOS4_GPIO_X3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
- EXYNOS4_GPIO_Y0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
- EXYNOS4_GPIO_Y1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0),
- EXYNOS4_GPIO_Y2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1),
- EXYNOS4_GPIO_Y3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2),
- EXYNOS4_GPIO_Y4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3),
- EXYNOS4_GPIO_Y5_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4),
- EXYNOS4_GPIO_Y6_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5),
- EXYNOS4_GPIO_Z_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6),
+ EXYNOS4_GPIO_A1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A0),
+ EXYNOS4_GPIO_B_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A1),
+ EXYNOS4_GPIO_C0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_B),
+ EXYNOS4_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C0),
+ EXYNOS4_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C1),
+ EXYNOS4_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D0),
+ EXYNOS4_GPIO_E0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D1),
+ EXYNOS4_GPIO_E1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E0),
+ EXYNOS4_GPIO_E2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E1),
+ EXYNOS4_GPIO_E3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E2),
+ EXYNOS4_GPIO_E4_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E3),
+ EXYNOS4_GPIO_F0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E4),
+ EXYNOS4_GPIO_F1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F0),
+ EXYNOS4_GPIO_F2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F1),
+ EXYNOS4_GPIO_F3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F2),
+ EXYNOS4_GPIO_J0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F3),
+ EXYNOS4_GPIO_J1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J0),
+ EXYNOS4_GPIO_K0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J1),
+ EXYNOS4_GPIO_K1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K0),
+ EXYNOS4_GPIO_K2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K1),
+ EXYNOS4_GPIO_K3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K2),
+ EXYNOS4_GPIO_L0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K3),
+ EXYNOS4_GPIO_L1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L0),
+ EXYNOS4_GPIO_L2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L1),
+ EXYNOS4_GPIO_X0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L2),
+ EXYNOS4_GPIO_X1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X0),
+ EXYNOS4_GPIO_X2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X1),
+ EXYNOS4_GPIO_X3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X2),
+ EXYNOS4_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X3),
+ EXYNOS4_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y0),
+ EXYNOS4_GPIO_Y2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y1),
+ EXYNOS4_GPIO_Y3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y2),
+ EXYNOS4_GPIO_Y4_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y3),
+ EXYNOS4_GPIO_Y5_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y4),
+ EXYNOS4_GPIO_Y6_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y5),
+ EXYNOS4_GPIO_Z_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y6),
};
/* EXYNOS4 GPIO number definitions */
+
#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr))
#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr))
#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr))
@@ -139,11 +140,147 @@ enum s5p_gpio_number {
#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr))
/* the end of the EXYNOS4 specific gpios */
+
#define EXYNOS4_GPIO_END (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
-#define S3C_GPIO_END EXYNOS4_GPIO_END
-/* define the number of gpios we need to the one after the GPZ() range */
-#define ARCH_NR_GPIOS (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + \
- CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+/* EXYNOS5 GPIO bank sizes */
+
+#define EXYNOS5_GPIO_A0_NR (8)
+#define EXYNOS5_GPIO_A1_NR (6)
+#define EXYNOS5_GPIO_A2_NR (8)
+#define EXYNOS5_GPIO_B0_NR (5)
+#define EXYNOS5_GPIO_B1_NR (5)
+#define EXYNOS5_GPIO_B2_NR (4)
+#define EXYNOS5_GPIO_B3_NR (4)
+#define EXYNOS5_GPIO_C0_NR (7)
+#define EXYNOS5_GPIO_C1_NR (7)
+#define EXYNOS5_GPIO_C2_NR (7)
+#define EXYNOS5_GPIO_C3_NR (7)
+#define EXYNOS5_GPIO_D0_NR (8)
+#define EXYNOS5_GPIO_D1_NR (8)
+#define EXYNOS5_GPIO_Y0_NR (6)
+#define EXYNOS5_GPIO_Y1_NR (4)
+#define EXYNOS5_GPIO_Y2_NR (6)
+#define EXYNOS5_GPIO_Y3_NR (8)
+#define EXYNOS5_GPIO_Y4_NR (8)
+#define EXYNOS5_GPIO_Y5_NR (8)
+#define EXYNOS5_GPIO_Y6_NR (8)
+#define EXYNOS5_GPIO_X0_NR (8)
+#define EXYNOS5_GPIO_X1_NR (8)
+#define EXYNOS5_GPIO_X2_NR (8)
+#define EXYNOS5_GPIO_X3_NR (8)
+#define EXYNOS5_GPIO_E0_NR (8)
+#define EXYNOS5_GPIO_E1_NR (2)
+#define EXYNOS5_GPIO_F0_NR (4)
+#define EXYNOS5_GPIO_F1_NR (4)
+#define EXYNOS5_GPIO_G0_NR (8)
+#define EXYNOS5_GPIO_G1_NR (8)
+#define EXYNOS5_GPIO_G2_NR (2)
+#define EXYNOS5_GPIO_H0_NR (4)
+#define EXYNOS5_GPIO_H1_NR (8)
+#define EXYNOS5_GPIO_V0_NR (8)
+#define EXYNOS5_GPIO_V1_NR (8)
+#define EXYNOS5_GPIO_V2_NR (8)
+#define EXYNOS5_GPIO_V3_NR (8)
+#define EXYNOS5_GPIO_V4_NR (2)
+#define EXYNOS5_GPIO_Z_NR (7)
+
+/* EXYNOS5 GPIO bank numbers */
+
+enum exynos5_gpio_number {
+ EXYNOS5_GPIO_A0_START = 0,
+ EXYNOS5_GPIO_A1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A0),
+ EXYNOS5_GPIO_A2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A1),
+ EXYNOS5_GPIO_B0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A2),
+ EXYNOS5_GPIO_B1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B0),
+ EXYNOS5_GPIO_B2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B1),
+ EXYNOS5_GPIO_B3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B2),
+ EXYNOS5_GPIO_C0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B3),
+ EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0),
+ EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1),
+ EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2),
+ EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3),
+ EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0),
+ EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1),
+ EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0),
+ EXYNOS5_GPIO_Y2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y1),
+ EXYNOS5_GPIO_Y3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y2),
+ EXYNOS5_GPIO_Y4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y3),
+ EXYNOS5_GPIO_Y5_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y4),
+ EXYNOS5_GPIO_Y6_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y5),
+ EXYNOS5_GPIO_X0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y6),
+ EXYNOS5_GPIO_X1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X0),
+ EXYNOS5_GPIO_X2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X1),
+ EXYNOS5_GPIO_X3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X2),
+ EXYNOS5_GPIO_E0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X3),
+ EXYNOS5_GPIO_E1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E0),
+ EXYNOS5_GPIO_F0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E1),
+ EXYNOS5_GPIO_F1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F0),
+ EXYNOS5_GPIO_G0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F1),
+ EXYNOS5_GPIO_G1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G0),
+ EXYNOS5_GPIO_G2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G1),
+ EXYNOS5_GPIO_H0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G2),
+ EXYNOS5_GPIO_H1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H0),
+ EXYNOS5_GPIO_V0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H1),
+ EXYNOS5_GPIO_V1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V0),
+ EXYNOS5_GPIO_V2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V1),
+ EXYNOS5_GPIO_V3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V2),
+ EXYNOS5_GPIO_V4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V3),
+ EXYNOS5_GPIO_Z_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V4),
+};
+
+/* EXYNOS5 GPIO number definitions */
+
+#define EXYNOS5_GPA0(_nr) (EXYNOS5_GPIO_A0_START + (_nr))
+#define EXYNOS5_GPA1(_nr) (EXYNOS5_GPIO_A1_START + (_nr))
+#define EXYNOS5_GPA2(_nr) (EXYNOS5_GPIO_A2_START + (_nr))
+#define EXYNOS5_GPB0(_nr) (EXYNOS5_GPIO_B0_START + (_nr))
+#define EXYNOS5_GPB1(_nr) (EXYNOS5_GPIO_B1_START + (_nr))
+#define EXYNOS5_GPB2(_nr) (EXYNOS5_GPIO_B2_START + (_nr))
+#define EXYNOS5_GPB3(_nr) (EXYNOS5_GPIO_B3_START + (_nr))
+#define EXYNOS5_GPC0(_nr) (EXYNOS5_GPIO_C0_START + (_nr))
+#define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr))
+#define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr))
+#define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr))
+#define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr))
+#define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr))
+#define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr))
+#define EXYNOS5_GPY1(_nr) (EXYNOS5_GPIO_Y1_START + (_nr))
+#define EXYNOS5_GPY2(_nr) (EXYNOS5_GPIO_Y2_START + (_nr))
+#define EXYNOS5_GPY3(_nr) (EXYNOS5_GPIO_Y3_START + (_nr))
+#define EXYNOS5_GPY4(_nr) (EXYNOS5_GPIO_Y4_START + (_nr))
+#define EXYNOS5_GPY5(_nr) (EXYNOS5_GPIO_Y5_START + (_nr))
+#define EXYNOS5_GPY6(_nr) (EXYNOS5_GPIO_Y6_START + (_nr))
+#define EXYNOS5_GPX0(_nr) (EXYNOS5_GPIO_X0_START + (_nr))
+#define EXYNOS5_GPX1(_nr) (EXYNOS5_GPIO_X1_START + (_nr))
+#define EXYNOS5_GPX2(_nr) (EXYNOS5_GPIO_X2_START + (_nr))
+#define EXYNOS5_GPX3(_nr) (EXYNOS5_GPIO_X3_START + (_nr))
+#define EXYNOS5_GPE0(_nr) (EXYNOS5_GPIO_E0_START + (_nr))
+#define EXYNOS5_GPE1(_nr) (EXYNOS5_GPIO_E1_START + (_nr))
+#define EXYNOS5_GPF0(_nr) (EXYNOS5_GPIO_F0_START + (_nr))
+#define EXYNOS5_GPF1(_nr) (EXYNOS5_GPIO_F1_START + (_nr))
+#define EXYNOS5_GPG0(_nr) (EXYNOS5_GPIO_G0_START + (_nr))
+#define EXYNOS5_GPG1(_nr) (EXYNOS5_GPIO_G1_START + (_nr))
+#define EXYNOS5_GPG2(_nr) (EXYNOS5_GPIO_G2_START + (_nr))
+#define EXYNOS5_GPH0(_nr) (EXYNOS5_GPIO_H0_START + (_nr))
+#define EXYNOS5_GPH1(_nr) (EXYNOS5_GPIO_H1_START + (_nr))
+#define EXYNOS5_GPV0(_nr) (EXYNOS5_GPIO_V0_START + (_nr))
+#define EXYNOS5_GPV1(_nr) (EXYNOS5_GPIO_V1_START + (_nr))
+#define EXYNOS5_GPV2(_nr) (EXYNOS5_GPIO_V2_START + (_nr))
+#define EXYNOS5_GPV3(_nr) (EXYNOS5_GPIO_V3_START + (_nr))
+#define EXYNOS5_GPV4(_nr) (EXYNOS5_GPIO_V4_START + (_nr))
+#define EXYNOS5_GPZ(_nr) (EXYNOS5_GPIO_Z_START + (_nr))
+
+/* the end of the EXYNOS5 specific gpios */
+
+#define EXYNOS5_GPIO_END (EXYNOS5_GPZ(EXYNOS5_GPIO_Z_NR) + 1)
+
+/* actually, EXYNOS5_GPIO_END is bigger than EXYNOS4 */
+
+#define S3C_GPIO_END (EXYNOS5_GPIO_END)
+
+/* define the number of gpios */
+
+#define ARCH_NR_GPIOS (CONFIG_SAMSUNG_GPIO_EXTRA + S3C_GPIO_END)
#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 609127df9b02..54307b09813a 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -101,6 +101,10 @@
#define EXYNOS4_PA_GPIO1 0x11400000
#define EXYNOS4_PA_GPIO2 0x11000000
#define EXYNOS4_PA_GPIO3 0x03860000
+#define EXYNOS5_PA_GPIO1 0x11400000
+#define EXYNOS5_PA_GPIO2 0x13400000
+#define EXYNOS5_PA_GPIO3 0x10D10000
+#define EXYNOS5_PA_GPIO4 0x03860000
#define EXYNOS4_PA_MIPI_CSIS0 0x11880000
#define EXYNOS4_PA_MIPI_CSIS1 0x11890000
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 0b04af2b13cc..13b306808b42 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -183,6 +183,12 @@ static __init int exynos4_pm_init_power_domain(void)
#ifdef CONFIG_S5P_DEV_CSIS1
exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam);
#endif
+#ifdef CONFIG_S5P_DEV_G2D
+ exynos_pm_add_dev_to_genpd(&s5p_device_g2d, &exynos4_pd_lcd0);
+#endif
+#ifdef CONFIG_S5P_DEV_JPEG
+ exynos_pm_add_dev_to_genpd(&s5p_device_jpeg, &exynos4_pd_cam);
+#endif
return 0;
}
arch_initcall(exynos4_pm_init_power_domain);
diff --git a/arch/arm/mach-lpc32xx/Kconfig b/arch/arm/mach-lpc32xx/Kconfig
index fde663508696..75946ac89ee9 100644
--- a/arch/arm/mach-lpc32xx/Kconfig
+++ b/arch/arm/mach-lpc32xx/Kconfig
@@ -29,5 +29,30 @@ config ARCH_LPC32XX_UART6_SELECT
endmenu
+menu "LPC32XX chip components"
+
+config ARCH_LPC32XX_IRAM_FOR_NET
+ bool "Use IRAM for network buffers"
+ default y
+ help
+ Say Y here to use the LPC internal fast IRAM (i.e. 256KB SRAM) as
+ network buffer. If the total combined required buffer sizes is
+ larger than the size of IRAM, then SDRAM will be used instead.
+
+ This can be enabled safely if the IRAM is not intended for other
+ uses.
+
+config ARCH_LPC32XX_MII_SUPPORT
+ bool "Check to enable MII support or leave disabled for RMII support"
+ help
+ Say Y here to enable MII support, or N for RMII support. Regardless of
+ which support is selected, the ethernet interface driver needs to be
+ selected in the device driver networking section.
+
+ The PHY3250 reference board uses RMII, so users of this board should
+ say N.
+
+endmenu
+
endif
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index f55c772d1816..b7ef51119d37 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -87,6 +87,7 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/device.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/amba/bus.h>
@@ -100,6 +101,8 @@
static DEFINE_SPINLOCK(global_clkregs_lock);
+static int usb_pll_enable, usb_pll_valid;
+
static struct clk clk_armpll;
static struct clk clk_usbpll;
@@ -384,30 +387,62 @@ static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup)
static int local_usbpll_enable(struct clk *clk, int enable)
{
u32 reg;
- int ret = -ENODEV;
- unsigned long timeout = jiffies + msecs_to_jiffies(10);
+ int ret = 0;
+ unsigned long timeout = jiffies + msecs_to_jiffies(20);
reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
- if (enable == 0) {
- reg &= ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
- LPC32XX_CLKPWR_USBCTRL_CLK_EN2);
- __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
- } else if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP) {
+ __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 |
+ LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
+ LPC32XX_CLKPWR_USB_CTRL);
+ __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1,
+ LPC32XX_CLKPWR_USB_CTRL);
+
+ if (enable && usb_pll_valid && usb_pll_enable) {
+ ret = -ENODEV;
+ /*
+ * If the PLL rate has been previously set, then the rate
+ * in the PLL register is valid and can be enabled here.
+ * Otherwise, it needs to be enabled as part of setrate.
+ */
+
+ /*
+ * Gate clock into PLL
+ */
reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
- /* Wait for PLL lock */
+ /*
+ * Enable PLL
+ */
+ reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+ /*
+ * Wait for PLL to lock
+ */
while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
ret = 0;
+ else
+ udelay(10);
}
+ /*
+ * Gate clock from PLL if PLL is locked
+ */
if (ret == 0) {
- reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2;
- __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+ __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2,
+ LPC32XX_CLKPWR_USB_CTRL);
+ } else {
+ __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
+ LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
+ LPC32XX_CLKPWR_USB_CTRL);
}
+ } else if ((enable == 0) && usb_pll_valid && usb_pll_enable) {
+ usb_pll_valid = 0;
+ usb_pll_enable = 0;
}
return ret;
@@ -425,7 +460,7 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
*/
rate = rate * 1000;
- clkin = clk->parent->rate;
+ clkin = clk->get_rate(clk);
usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
clkin = clkin / usbdiv;
@@ -439,7 +474,8 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
{
- u32 clkin, reg, usbdiv;
+ int ret = -ENODEV;
+ u32 clkin, usbdiv;
struct clk_pll_setup pllsetup;
/*
@@ -448,7 +484,7 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
*/
rate = rate * 1000;
- clkin = clk->get_rate(clk);
+ clkin = clk->get_rate(clk->parent);
usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
clkin = clkin / usbdiv;
@@ -457,22 +493,25 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
return -EINVAL;
+ /*
+ * Disable PLL clocks during PLL change
+ */
local_usbpll_enable(clk, 0);
-
- reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
- reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
- __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
- pllsetup.analog_on = 1;
+ pllsetup.analog_on = 0;
local_clk_usbpll_setup(&pllsetup);
- clk->rate = clk_check_pll_setup(clkin, &pllsetup);
+ /*
+ * Start USB PLL and check PLL status
+ */
+
+ usb_pll_valid = 1;
+ usb_pll_enable = 1;
- reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
- reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2;
- __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+ ret = local_usbpll_enable(clk, 1);
+ if (ret >= 0)
+ clk->rate = clk_check_pll_setup(clkin, &pllsetup);
- return 0;
+ return ret;
}
static struct clk clk_usbpll = {
diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
index 6c76bb36559b..bbbf063a74c2 100644
--- a/arch/arm/mach-lpc32xx/common.c
+++ b/arch/arm/mach-lpc32xx/common.c
@@ -160,6 +160,53 @@ struct platform_device lpc32xx_adc_device = {
};
/*
+ * USB support
+ */
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32) 0;
+static struct resource ohci_resources[] = {
+ {
+ .start = IO_ADDRESS(LPC32XX_USB_BASE),
+ .end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100 - 1),
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_LPC32XX_USB_HOST,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+struct platform_device lpc32xx_ohci_device = {
+ .name = "usb-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+};
+
+/*
+ * Network Support
+ */
+static struct resource net_resources[] = {
+ [0] = DEFINE_RES_MEM(LPC32XX_ETHERNET_BASE, SZ_4K),
+ [1] = DEFINE_RES_MEM(LPC32XX_IRAM_BASE, SZ_128K),
+ [2] = DEFINE_RES_IRQ(IRQ_LPC32XX_ETHERNET),
+};
+
+static u64 lpc32xx_mac_dma_mask = 0xffffffffUL;
+struct platform_device lpc32xx_net_device = {
+ .name = "lpc-eth",
+ .id = 0,
+ .dev = {
+ .dma_mask = &lpc32xx_mac_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL,
+ },
+ .num_resources = ARRAY_SIZE(net_resources),
+ .resource = net_resources,
+};
+
+/*
* Returns the unique ID for the device
*/
void lpc32xx_get_uid(u32 devid[4])
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
index 68f2e46d98ad..68e45e8c9486 100644
--- a/arch/arm/mach-lpc32xx/common.h
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -19,6 +19,7 @@
#ifndef __LPC32XX_COMMON_H
#define __LPC32XX_COMMON_H
+#include <mach/board.h>
#include <linux/platform_device.h>
/*
@@ -31,6 +32,8 @@ extern struct platform_device lpc32xx_i2c2_device;
extern struct platform_device lpc32xx_tsc_device;
extern struct platform_device lpc32xx_adc_device;
extern struct platform_device lpc32xx_rtc_device;
+extern struct platform_device lpc32xx_ohci_device;
+extern struct platform_device lpc32xx_net_device;
/*
* Other arch specific structures and functions
@@ -67,7 +70,6 @@ extern u32 clk_get_pclk_div(void);
extern void lpc32xx_get_uid(u32 devid[4]);
extern u32 lpc32xx_return_iram_size(void);
-
/*
* Pointers used for sizing and copying suspend function data
*/
diff --git a/arch/arm/mach-lpc32xx/include/mach/board.h b/arch/arm/mach-lpc32xx/include/mach/board.h
new file mode 100644
index 000000000000..52531ca7bd1d
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/board.h
@@ -0,0 +1,24 @@
+/*
+ * arm/arch/mach-lpc32xx/include/mach/board.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_BOARD_H
+#define __ASM_ARCH_BOARD_H
+
+extern u32 lpc32xx_return_iram_size(void);
+
+#endif /* __ASM_ARCH_BOARD_H */
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
index c74de01ab5b6..d080cb1123dd 100644
--- a/arch/arm/mach-lpc32xx/irq.c
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -150,6 +150,10 @@ static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
.event_group = &lpc32xx_event_int_regs,
.mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT,
},
+ [IRQ_LPC32XX_ETHERNET] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_MAC_BIT,
+ },
[IRQ_LPC32XX_USB_OTG_ATX] = {
.event_group = &lpc32xx_event_int_regs,
.mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT,
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 0d79a3f8a5e0..7f7401ec7487 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -37,6 +37,7 @@
#include <mach/hardware.h>
#include <mach/platform.h>
+#include <mach/board.h>
#include <mach/gpio-lpc32xx.h>
#include "common.h"
@@ -255,6 +256,8 @@ static struct platform_device *phy3250_devs[] __initdata = {
&lpc32xx_watchdog_device,
&lpc32xx_gpio_led_device,
&lpc32xx_adc_device,
+ &lpc32xx_ohci_device,
+ &lpc32xx_net_device,
};
static struct amba_device *amba_devs[] __initdata = {
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index 0a79a1167a25..46277877b7ec 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -169,7 +169,7 @@ int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
}
-static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip,
+static int exynos_gpio_setpull(struct samsung_gpio_chip *chip,
unsigned int off, samsung_gpio_pull_t pull)
{
if (pull == S3C_GPIO_PULL_UP)
@@ -178,7 +178,7 @@ static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip,
return samsung_gpio_setpull_updown(chip, off, pull);
}
-static samsung_gpio_pull_t exynos4_gpio_getpull(struct samsung_gpio_chip *chip,
+static samsung_gpio_pull_t exynos_gpio_getpull(struct samsung_gpio_chip *chip,
unsigned int off)
{
samsung_gpio_pull_t pull;
@@ -452,9 +452,9 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
};
#endif
-static struct samsung_gpio_cfg exynos4_gpio_cfg = {
- .set_pull = exynos4_gpio_setpull,
- .get_pull = exynos4_gpio_getpull,
+static struct samsung_gpio_cfg exynos_gpio_cfg = {
+ .set_pull = exynos_gpio_setpull,
+ .get_pull = exynos_gpio_getpull,
.set_config = samsung_gpio_setcfg_4bit,
.get_config = samsung_gpio_getcfg_4bit,
};
@@ -502,13 +502,13 @@ static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
.get_config = samsung_gpio_getcfg_2bit,
},
[8] = {
- .set_pull = exynos4_gpio_setpull,
- .get_pull = exynos4_gpio_getpull,
+ .set_pull = exynos_gpio_setpull,
+ .get_pull = exynos_gpio_getpull,
},
[9] = {
.cfg_eint = 0x3,
- .set_pull = exynos4_gpio_setpull,
- .get_pull = exynos4_gpio_getpull,
+ .set_pull = exynos_gpio_setpull,
+ .get_pull = exynos_gpio_getpull,
}
};
@@ -2113,10 +2113,10 @@ static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
};
/*
- * Followings are the gpio banks in EXYNOS4210
+ * Followings are the gpio banks in EXYNOS SoCs
*
* The 'config' member when left to NULL, is initialized to the default
- * structure samsung_gpio_cfgs[3] in the init function below.
+ * structure exynos_gpio_cfg in the init function below.
*
* The 'base' member is also initialized in the init function below.
* Note: The initialization of 'base' member of samsung_gpio_chip structure
@@ -2331,7 +2331,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.label = "GPY6",
},
}, {
- .base = (S5P_VA_GPIO2 + 0xC00),
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(0),
.chip = {
@@ -2341,7 +2340,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.to_irq = samsung_gpiolib_to_irq,
},
}, {
- .base = (S5P_VA_GPIO2 + 0xC20),
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(8),
.chip = {
@@ -2351,7 +2349,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.to_irq = samsung_gpiolib_to_irq,
},
}, {
- .base = (S5P_VA_GPIO2 + 0xC40),
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(16),
.chip = {
@@ -2361,7 +2358,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.to_irq = samsung_gpiolib_to_irq,
},
}, {
- .base = (S5P_VA_GPIO2 + 0xC60),
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(24),
.chip = {
@@ -2386,8 +2382,280 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
#endif
};
-#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
-static int exynos4_gpio_xlate(struct gpio_chip *gc,
+static struct samsung_gpio_chip exynos5_gpios_1[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+ {
+ .chip = {
+ .base = EXYNOS5_GPA0(0),
+ .ngpio = EXYNOS5_GPIO_A0_NR,
+ .label = "GPA0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPA1(0),
+ .ngpio = EXYNOS5_GPIO_A1_NR,
+ .label = "GPA1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPA2(0),
+ .ngpio = EXYNOS5_GPIO_A2_NR,
+ .label = "GPA2",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPB0(0),
+ .ngpio = EXYNOS5_GPIO_B0_NR,
+ .label = "GPB0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPB1(0),
+ .ngpio = EXYNOS5_GPIO_B1_NR,
+ .label = "GPB1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPB2(0),
+ .ngpio = EXYNOS5_GPIO_B2_NR,
+ .label = "GPB2",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPB3(0),
+ .ngpio = EXYNOS5_GPIO_B3_NR,
+ .label = "GPB3",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPC0(0),
+ .ngpio = EXYNOS5_GPIO_C0_NR,
+ .label = "GPC0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPC1(0),
+ .ngpio = EXYNOS5_GPIO_C1_NR,
+ .label = "GPC1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPC2(0),
+ .ngpio = EXYNOS5_GPIO_C2_NR,
+ .label = "GPC2",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPC3(0),
+ .ngpio = EXYNOS5_GPIO_C3_NR,
+ .label = "GPC3",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPD0(0),
+ .ngpio = EXYNOS5_GPIO_D0_NR,
+ .label = "GPD0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPD1(0),
+ .ngpio = EXYNOS5_GPIO_D1_NR,
+ .label = "GPD1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPY0(0),
+ .ngpio = EXYNOS5_GPIO_Y0_NR,
+ .label = "GPY0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPY1(0),
+ .ngpio = EXYNOS5_GPIO_Y1_NR,
+ .label = "GPY1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPY2(0),
+ .ngpio = EXYNOS5_GPIO_Y2_NR,
+ .label = "GPY2",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPY3(0),
+ .ngpio = EXYNOS5_GPIO_Y3_NR,
+ .label = "GPY3",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPY4(0),
+ .ngpio = EXYNOS5_GPIO_Y4_NR,
+ .label = "GPY4",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPY5(0),
+ .ngpio = EXYNOS5_GPIO_Y5_NR,
+ .label = "GPY5",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPY6(0),
+ .ngpio = EXYNOS5_GPIO_Y6_NR,
+ .label = "GPY6",
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[9],
+ .irq_base = IRQ_EINT(0),
+ .chip = {
+ .base = EXYNOS5_GPX0(0),
+ .ngpio = EXYNOS5_GPIO_X0_NR,
+ .label = "GPX0",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[9],
+ .irq_base = IRQ_EINT(8),
+ .chip = {
+ .base = EXYNOS5_GPX1(0),
+ .ngpio = EXYNOS5_GPIO_X1_NR,
+ .label = "GPX1",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[9],
+ .irq_base = IRQ_EINT(16),
+ .chip = {
+ .base = EXYNOS5_GPX2(0),
+ .ngpio = EXYNOS5_GPIO_X2_NR,
+ .label = "GPX2",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .config = &samsung_gpio_cfgs[9],
+ .irq_base = IRQ_EINT(24),
+ .chip = {
+ .base = EXYNOS5_GPX3(0),
+ .ngpio = EXYNOS5_GPIO_X3_NR,
+ .label = "GPX3",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ },
+#endif
+};
+
+static struct samsung_gpio_chip exynos5_gpios_2[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+ {
+ .chip = {
+ .base = EXYNOS5_GPE0(0),
+ .ngpio = EXYNOS5_GPIO_E0_NR,
+ .label = "GPE0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPE1(0),
+ .ngpio = EXYNOS5_GPIO_E1_NR,
+ .label = "GPE1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPF0(0),
+ .ngpio = EXYNOS5_GPIO_F0_NR,
+ .label = "GPF0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPF1(0),
+ .ngpio = EXYNOS5_GPIO_F1_NR,
+ .label = "GPF1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPG0(0),
+ .ngpio = EXYNOS5_GPIO_G0_NR,
+ .label = "GPG0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPG1(0),
+ .ngpio = EXYNOS5_GPIO_G1_NR,
+ .label = "GPG1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPG2(0),
+ .ngpio = EXYNOS5_GPIO_G2_NR,
+ .label = "GPG2",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPH0(0),
+ .ngpio = EXYNOS5_GPIO_H0_NR,
+ .label = "GPH0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPH1(0),
+ .ngpio = EXYNOS5_GPIO_H1_NR,
+ .label = "GPH1",
+
+ },
+ },
+#endif
+};
+
+static struct samsung_gpio_chip exynos5_gpios_3[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+ {
+ .chip = {
+ .base = EXYNOS5_GPV0(0),
+ .ngpio = EXYNOS5_GPIO_V0_NR,
+ .label = "GPV0",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPV1(0),
+ .ngpio = EXYNOS5_GPIO_V1_NR,
+ .label = "GPV1",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPV2(0),
+ .ngpio = EXYNOS5_GPIO_V2_NR,
+ .label = "GPV2",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPV3(0),
+ .ngpio = EXYNOS5_GPIO_V3_NR,
+ .label = "GPV3",
+ },
+ }, {
+ .chip = {
+ .base = EXYNOS5_GPV4(0),
+ .ngpio = EXYNOS5_GPIO_V4_NR,
+ .label = "GPV4",
+ },
+ },
+#endif
+};
+
+static struct samsung_gpio_chip exynos5_gpios_4[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+ {
+ .chip = {
+ .base = EXYNOS5_GPZ(0),
+ .ngpio = EXYNOS5_GPIO_Z_NR,
+ .label = "GPZ",
+ },
+ },
+#endif
+};
+
+
+#if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
+static int exynos_gpio_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags)
{
unsigned int pin;
@@ -2413,13 +2681,13 @@ static int exynos4_gpio_xlate(struct gpio_chip *gc,
return gpiospec->args[0];
}
-static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
+static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
{ .compatible = "samsung,exynos4-gpio", },
{}
};
-static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
- u64 base, u64 offset)
+static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
+ u64 base, u64 offset)
{
struct gpio_chip *gc = &chip->chip;
u64 address;
@@ -2429,28 +2697,29 @@ static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
gc->of_node = of_find_matching_node_by_address(NULL,
- exynos4_gpio_dt_match, address);
+ exynos_gpio_dt_match, address);
if (!gc->of_node) {
pr_info("gpio: device tree node not found for gpio controller"
" with base address %08llx\n", address);
return;
}
gc->of_gpio_n_cells = 4;
- gc->of_xlate = exynos4_gpio_xlate;
+ gc->of_xlate = exynos_gpio_xlate;
}
-#elif defined(CONFIG_ARCH_EXYNOS4)
-static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
- u64 base, u64 offset)
+#elif defined(CONFIG_ARCH_EXYNOS)
+static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
+ u64 base, u64 offset)
{
return;
}
-#endif /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) */
+#endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
/* TODO: cleanup soc_is_* */
static __init int samsung_gpiolib_init(void)
{
struct samsung_gpio_chip *chip;
int i, nr_chips;
+ void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
int group = 0;
samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
@@ -2516,66 +2785,200 @@ static __init int samsung_gpiolib_init(void)
s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
#endif
} else if (soc_is_exynos4210()) {
- group = 0;
+#ifdef CONFIG_CPU_EXYNOS4210
+ void __iomem *gpx_base;
/* gpio part1 */
+ gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
+ if (gpio_base1 == NULL) {
+ pr_err("unable to ioremap for gpio_base1\n");
+ goto err_ioremap1;
+ }
+
chip = exynos4_gpios_1;
nr_chips = ARRAY_SIZE(exynos4_gpios_1);
for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) {
- chip->config = &exynos4_gpio_cfg;
+ chip->config = &exynos_gpio_cfg;
chip->group = group++;
}
-#ifdef CONFIG_CPU_EXYNOS4210
- exynos4_gpiolib_attach_ofnode(chip,
+ exynos_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO1, i * 0x20);
-#endif
}
- samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1);
+ samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
+ nr_chips, gpio_base1);
/* gpio part2 */
+ gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
+ if (gpio_base2 == NULL) {
+ pr_err("unable to ioremap for gpio_base2\n");
+ goto err_ioremap2;
+ }
+
+ /* need to set base address for gpx */
+ chip = &exynos4_gpios_2[16];
+ gpx_base = gpio_base2 + 0xC00;
+ for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
+ chip->base = gpx_base;
+
chip = exynos4_gpios_2;
nr_chips = ARRAY_SIZE(exynos4_gpios_2);
for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) {
- chip->config = &exynos4_gpio_cfg;
+ chip->config = &exynos_gpio_cfg;
chip->group = group++;
}
-#ifdef CONFIG_CPU_EXYNOS4210
- exynos4_gpiolib_attach_ofnode(chip,
+ exynos_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO2, i * 0x20);
-#endif
}
- samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2);
+ samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
+ nr_chips, gpio_base2);
/* gpio part3 */
+ gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
+ if (gpio_base3 == NULL) {
+ pr_err("unable to ioremap for gpio_base3\n");
+ goto err_ioremap3;
+ }
+
chip = exynos4_gpios_3;
nr_chips = ARRAY_SIZE(exynos4_gpios_3);
for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) {
- chip->config = &exynos4_gpio_cfg;
+ chip->config = &exynos_gpio_cfg;
chip->group = group++;
}
-#ifdef CONFIG_CPU_EXYNOS4210
- exynos4_gpiolib_attach_ofnode(chip,
+ exynos_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO3, i * 0x20);
-#endif
}
- samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3);
+ samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
+ nr_chips, gpio_base3);
#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
#endif
+
+#endif /* CONFIG_CPU_EXYNOS4210 */
+ } else if (soc_is_exynos5250()) {
+#ifdef CONFIG_SOC_EXYNOS5250
+ void __iomem *gpx_base;
+
+ /* gpio part1 */
+ gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
+ if (gpio_base1 == NULL) {
+ pr_err("unable to ioremap for gpio_base1\n");
+ goto err_ioremap1;
+ }
+
+ /* need to set base address for gpx */
+ chip = &exynos5_gpios_1[20];
+ gpx_base = gpio_base1 + 0xC00;
+ for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
+ chip->base = gpx_base;
+
+ chip = exynos5_gpios_1;
+ nr_chips = ARRAY_SIZE(exynos5_gpios_1);
+
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (!chip->config) {
+ chip->config = &exynos_gpio_cfg;
+ chip->group = group++;
+ }
+ exynos_gpiolib_attach_ofnode(chip,
+ EXYNOS5_PA_GPIO1, i * 0x20);
+ }
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
+ nr_chips, gpio_base1);
+
+ /* gpio part2 */
+ gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
+ if (gpio_base2 == NULL) {
+ pr_err("unable to ioremap for gpio_base2\n");
+ goto err_ioremap2;
+ }
+
+ chip = exynos5_gpios_2;
+ nr_chips = ARRAY_SIZE(exynos5_gpios_2);
+
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (!chip->config) {
+ chip->config = &exynos_gpio_cfg;
+ chip->group = group++;
+ }
+ exynos_gpiolib_attach_ofnode(chip,
+ EXYNOS5_PA_GPIO2, i * 0x20);
+ }
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
+ nr_chips, gpio_base2);
+
+ /* gpio part3 */
+ gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
+ if (gpio_base3 == NULL) {
+ pr_err("unable to ioremap for gpio_base3\n");
+ goto err_ioremap3;
+ }
+
+ /* need to set base address for gpv */
+ exynos5_gpios_3[0].base = gpio_base3;
+ exynos5_gpios_3[1].base = gpio_base3 + 0x20;
+ exynos5_gpios_3[2].base = gpio_base3 + 0x60;
+ exynos5_gpios_3[3].base = gpio_base3 + 0x80;
+ exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
+
+ chip = exynos5_gpios_3;
+ nr_chips = ARRAY_SIZE(exynos5_gpios_3);
+
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (!chip->config) {
+ chip->config = &exynos_gpio_cfg;
+ chip->group = group++;
+ }
+ exynos_gpiolib_attach_ofnode(chip,
+ EXYNOS5_PA_GPIO3, i * 0x20);
+ }
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
+ nr_chips, gpio_base3);
+
+ /* gpio part4 */
+ gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
+ if (gpio_base4 == NULL) {
+ pr_err("unable to ioremap for gpio_base4\n");
+ goto err_ioremap4;
+ }
+
+ chip = exynos5_gpios_4;
+ nr_chips = ARRAY_SIZE(exynos5_gpios_4);
+
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (!chip->config) {
+ chip->config = &exynos_gpio_cfg;
+ chip->group = group++;
+ }
+ exynos_gpiolib_attach_ofnode(chip,
+ EXYNOS5_PA_GPIO4, i * 0x20);
+ }
+ samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
+ nr_chips, gpio_base4);
+#endif /* CONFIG_SOC_EXYNOS5250 */
} else {
WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
return -ENODEV;
}
return 0;
+
+err_ioremap4:
+ iounmap(gpio_base3);
+err_ioremap3:
+ iounmap(gpio_base2);
+err_ioremap2:
+ iounmap(gpio_base1);
+err_ioremap1:
+ return -ENOMEM;
}
core_initcall(samsung_gpiolib_init);