From 1e65dfbf48f3b71eb7945a8b14a69abf370181b9 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Sep 2005 15:10:13 +0300 Subject: [PATCH] ARM: OMAP: Added common devices.c to plat-omap for I2C and MMC init Added common devices.c to plat-omap for I2C and MMC init --- arch/arm/mach-omap1/devices.c | 188 +---------------- arch/arm/mach-omap2/board-generic.c | 11 + arch/arm/mach-omap2/board-h4.c | 16 +- arch/arm/plat-omap/Makefile | 2 +- arch/arm/plat-omap/devices.c | 305 ++++++++++++++++++++++++++++ 5 files changed, 331 insertions(+), 191 deletions(-) create mode 100644 arch/arm/plat-omap/devices.c diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index e8b3981444c..62a9668a5da 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -25,56 +25,7 @@ #include #include - -static void omap_nop_release(struct device *dev) -{ - /* Nothing */ -} - -/*-------------------------------------------------------------------------*/ - -#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) - -#define OMAP_I2C_BASE 0xfffb3800 - -static struct resource i2c_resources[] = { - { - .start = OMAP_I2C_BASE, - .end = OMAP_I2C_BASE + 0x3f, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_I2C, - .flags = IORESOURCE_IRQ, - }, -}; - -/* DMA not used; works around erratum writing to non-empty i2c fifo */ - -static struct platform_device omap_i2c_device = { - .name = "i2c_omap", - .id = -1, - .dev = { - .release = omap_nop_release, - }, - .num_resources = ARRAY_SIZE(i2c_resources), - .resource = i2c_resources, -}; - -static void omap_init_i2c(void) -{ - /* FIXME define and use a boot tag, in case of boards that - * either don't wire up I2C, or chips that mux it differently... - * it can include clocking and address info, maybe more. - */ - omap_cfg_reg(I2C_SCL); - omap_cfg_reg(I2C_SDA); - - (void) platform_device_register(&omap_i2c_device); -} -#else -static inline void omap_init_i2c(void) {} -#endif +extern void omap_nop_release(struct device *dev); /*-------------------------------------------------------------------------*/ @@ -110,137 +61,6 @@ static inline void omap_init_irda(void) {} /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) - -#define OMAP_MMC1_BASE 0xfffb7800 -#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ - -static struct omap_mmc_conf mmc1_conf; - -static u64 mmc1_dmamask = 0xffffffff; - -static struct resource mmc1_resources[] = { - { - .start = IO_ADDRESS(OMAP_MMC1_BASE), - .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_MMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device mmc_omap_device1 = { - .name = "mmci-omap", - .id = 1, - .dev = { - .release = omap_nop_release, - .dma_mask = &mmc1_dmamask, - .platform_data = &mmc1_conf, - }, - .num_resources = ARRAY_SIZE(mmc1_resources), - .resource = mmc1_resources, -}; - -#ifdef CONFIG_ARCH_OMAP16XX - -static struct omap_mmc_conf mmc2_conf; - -static u64 mmc2_dmamask = 0xffffffff; - -static struct resource mmc2_resources[] = { - { - .start = IO_ADDRESS(OMAP_MMC2_BASE), - .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_1610_MMC2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device mmc_omap_device2 = { - .name = "mmci-omap", - .id = 2, - .dev = { - .release = omap_nop_release, - .dma_mask = &mmc2_dmamask, - .platform_data = &mmc2_conf, - }, - .num_resources = ARRAY_SIZE(mmc2_resources), - .resource = mmc2_resources, -}; -#endif - -static void __init omap_init_mmc(void) -{ - const struct omap_mmc_config *mmc_conf; - const struct omap_mmc_conf *mmc; - - /* NOTE: assumes MMC was never (wrongly) enabled */ - mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config); - if (!mmc_conf) - return; - - /* block 1 is always available and has just one pinout option */ - mmc = &mmc_conf->mmc[0]; - if (mmc->enabled) { - omap_cfg_reg(MMC_CMD); - omap_cfg_reg(MMC_CLK); - omap_cfg_reg(MMC_DAT0); - if (cpu_is_omap1710()) { - omap_cfg_reg(M15_1710_MMC_CLKI); - omap_cfg_reg(P19_1710_MMC_CMDDIR); - omap_cfg_reg(P20_1710_MMC_DATDIR0); - } - if (mmc->wire4) { - omap_cfg_reg(MMC_DAT1); - /* NOTE: DAT2 can be on W10 (here) or M15 */ - if (!mmc->nomux) - omap_cfg_reg(MMC_DAT2); - omap_cfg_reg(MMC_DAT3); - } - mmc1_conf = *mmc; - (void) platform_device_register(&mmc_omap_device1); - } - -#ifdef CONFIG_ARCH_OMAP16XX - /* block 2 is on newer chips, and has many pinout options */ - mmc = &mmc_conf->mmc[1]; - if (mmc->enabled) { - if (!mmc->nomux) { - omap_cfg_reg(Y8_1610_MMC2_CMD); - omap_cfg_reg(Y10_1610_MMC2_CLK); - omap_cfg_reg(R18_1610_MMC2_CLKIN); - omap_cfg_reg(W8_1610_MMC2_DAT0); - if (mmc->wire4) { - omap_cfg_reg(V8_1610_MMC2_DAT1); - omap_cfg_reg(W15_1610_MMC2_DAT2); - omap_cfg_reg(R10_1610_MMC2_DAT3); - } - - /* These are needed for the level shifter */ - omap_cfg_reg(V9_1610_MMC2_CMDDIR); - omap_cfg_reg(V5_1610_MMC2_DATDIR0); - omap_cfg_reg(W19_1610_MMC2_DATDIR1); - } - - /* Feedback clock must be set on OMAP-1710 MMC2 */ - if (cpu_is_omap1710()) - omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), - MOD_CONF_CTRL_1); - mmc2_conf = *mmc; - (void) platform_device_register(&mmc_omap_device2); - } -#endif - return; -} -#else -static inline void omap_init_mmc(void) {} -#endif - #if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC) #define OMAP_RTC_BASE 0xfffb4800 @@ -334,18 +154,16 @@ static inline void omap_init_wdt(void) {} * may be handled by the boot loader, and drivers should expect it will * normally have been done by the time they're probed. */ -static int __init omap_init_devices(void) +static int __init omap1_init_devices(void) { /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ - omap_init_i2c(); omap_init_irda(); - omap_init_mmc(); omap_init_rtc(); omap_init_wdt(); return 0; } -arch_initcall(omap_init_devices); +arch_initcall(omap1_init_devices); diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index f5d94a8bcd0..c602e7a3d93 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -40,8 +40,19 @@ static struct omap_uart_config generic_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; +static struct omap_mmc_config generic_mmc_config __initdata = { + .mmc [0] = { + .enabled = 0, + .wire4 = 0, + .wp_pin = -1, + .power_pin = -1, + .switch_pin = -1, + }, +}; + static struct omap_board_config_kernel generic_config[] = { { OMAP_TAG_UART, &generic_uart_config }, + { OMAP_TAG_MMC, &generic_mmc_config }, }; static void __init omap_generic_init(void) diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index c58b00f245c..c9b7b2766ac 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -6,11 +6,6 @@ * * Modified from mach-omap/omap1/board-generic.c * - * Code for generic OMAP2 board. Should work on many OMAP2 systems where - * the bootloader passes the board-specific data to the kernel. - * Do not put any board specific code to this file; create a new machine - * type if you need custom low-level initializations. - * * 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 * published by the Free Software Foundation. @@ -88,8 +83,19 @@ static struct omap_uart_config h4_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; +static struct omap_mmc_config h4_mmc_config __initdata = { + .mmc [0] = { + .enabled = 1, + .wire4 = 1, + .wp_pin = -1, + .power_pin = -1, + .switch_pin = -1, + }, +}; + static struct omap_board_config_kernel h4_config[] = { { OMAP_TAG_UART, &h4_uart_config }, + { OMAP_TAG_MMC, &h4_mmc_config }, }; static void __init omap_h4_init(void) diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 092e7405e47..bed117dc03d 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o +obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o obj-m := obj-n := obj- := diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c new file mode 100644 index 00000000000..06b801cd71d --- /dev/null +++ b/arch/arm/plat-omap/devices.c @@ -0,0 +1,305 @@ +/* + * linux/arch/arm/plat-omap/devices.c + * + * Common platform device setup/initialization for OMAP1 and OMAP2 + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +static void omap_nop_release(struct device *dev) +{ + /* Nothing */ +} + +/*-------------------------------------------------------------------------*/ + +#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) + +#define OMAP1_I2C_BASE 0xfffb3800 +#define OMAP2_I2C_BASE1 0x48070000 +#define OMAP2_I2C_BASE2 0x48072000 +#define OMAP_I2C_SIZE 0x3f +#define OMAP1_I2C_INT INT_I2C +#define OMAP2_I2C_INT1 56 +#define OMAP2_I2C_INT2 57 + +static struct resource i2c_resources1[] = { + { + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM, + }, + { + .start = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +/* DMA not used; works around erratum writing to non-empty i2c fifo */ + +static struct platform_device omap_i2c_device1 = { + .name = "i2c_omap", + .id = 1, + .dev = { + .release = omap_nop_release, + }, + .num_resources = ARRAY_SIZE(i2c_resources1), + .resource = i2c_resources1, +}; + +#ifdef CONFIG_ARCH_OMAP24XX +static struct resource i2c_resources2[] = { + { + .start = OMAP2_I2C_BASE2, + .end = OMAP2_I2C_BASE2 + OMAP_I2C_SIZE, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP2_I2C_INT2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device omap_i2c_device2 = { + .name = "i2c_omap", + .id = 2, + .dev = { + .release = omap_nop_release, + }, + .num_resources = ARRAY_SIZE(i2c_resources2), + .resource = i2c_resources2, +}; +#else +#define omap_i2c_device2 NULL +#endif + +static void omap_init_i2c(void) +{ + if (cpu_is_omap24xx()) { + i2c_resources1[0].start = OMAP2_I2C_BASE1; + i2c_resources1[0].end = OMAP2_I2C_BASE1 + OMAP_I2C_SIZE; + i2c_resources1[1].start = OMAP2_I2C_INT1; + } else { + i2c_resources1[0].start = OMAP1_I2C_BASE; + i2c_resources1[0].end = OMAP1_I2C_BASE + OMAP_I2C_SIZE; + i2c_resources1[1].start = OMAP1_I2C_INT; + } + + /* FIXME define and use a boot tag, in case of boards that + * either don't wire up I2C, or chips that mux it differently... + * it can include clocking and address info, maybe more. + */ + if (cpu_is_omap24xx()) { + omap_cfg_reg(M19_24XX_I2C1_SCL); + omap_cfg_reg(L15_24XX_I2C1_SDA); + omap_cfg_reg(J15_24XX_I2C2_SCL); + omap_cfg_reg(H19_24XX_I2C2_SDA); + } else { + omap_cfg_reg(I2C_SCL); + omap_cfg_reg(I2C_SDA); + } + + (void) platform_device_register(&omap_i2c_device1); + + //if (cpu_is_omap24xx()) + // (void) platform_device_register(&omap_i2c_device2); +} +#else +static inline void omap_init_i2c(void) {} +#endif + +/*-------------------------------------------------------------------------*/ + +#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) + +#ifdef CONFIG_ARCH_OMAP24XX +#define OMAP_MMC1_BASE 0x4809c000 +#define OMAP_MMC1_INT 83 +#else +#define OMAP_MMC1_BASE 0xfffb7800 +#define OMAP_MMC1_INT INT_MMC +#endif +#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ + +static struct omap_mmc_conf mmc1_conf; + +static u64 mmc1_dmamask = 0xffffffff; + +static struct resource mmc1_resources[] = { + { + .start = IO_ADDRESS(OMAP_MMC1_BASE), + .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f, + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP_MMC1_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mmc_omap_device1 = { + .name = "mmci-omap", + .id = 1, + .dev = { + .release = omap_nop_release, + .dma_mask = &mmc1_dmamask, + .platform_data = &mmc1_conf, + }, + .num_resources = ARRAY_SIZE(mmc1_resources), + .resource = mmc1_resources, +}; + +#ifdef CONFIG_ARCH_OMAP16XX + +static struct omap_mmc_conf mmc2_conf; + +static u64 mmc2_dmamask = 0xffffffff; + +static struct resource mmc2_resources[] = { + { + .start = IO_ADDRESS(OMAP_MMC2_BASE), + .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_1610_MMC2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mmc_omap_device2 = { + .name = "mmci-omap", + .id = 2, + .dev = { + .release = omap_nop_release, + .dma_mask = &mmc2_dmamask, + .platform_data = &mmc2_conf, + }, + .num_resources = ARRAY_SIZE(mmc2_resources), + .resource = mmc2_resources, +}; +#endif + +static void __init omap_init_mmc(void) +{ + const struct omap_mmc_config *mmc_conf; + const struct omap_mmc_conf *mmc; + + /* NOTE: assumes MMC was never (wrongly) enabled */ + mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config); + if (!mmc_conf) + return; + + /* block 1 is always available and has just one pinout option */ + mmc = &mmc_conf->mmc[0]; + if (mmc->enabled) { + if (!cpu_is_omap24xx()) { + omap_cfg_reg(MMC_CMD); + omap_cfg_reg(MMC_CLK); + omap_cfg_reg(MMC_DAT0); + if (cpu_is_omap1710()) { + omap_cfg_reg(M15_1710_MMC_CLKI); + omap_cfg_reg(P19_1710_MMC_CMDDIR); + omap_cfg_reg(P20_1710_MMC_DATDIR0); + } + } + if (mmc->wire4) { + if (!cpu_is_omap24xx()) { + omap_cfg_reg(MMC_DAT1); + /* NOTE: DAT2 can be on W10 (here) or M15 */ + if (!mmc->nomux) + omap_cfg_reg(MMC_DAT2); + omap_cfg_reg(MMC_DAT3); + } + } + mmc1_conf = *mmc; + (void) platform_device_register(&mmc_omap_device1); + } + +#ifdef CONFIG_ARCH_OMAP16XX + /* block 2 is on newer chips, and has many pinout options */ + mmc = &mmc_conf->mmc[1]; + if (mmc->enabled) { + if (!mmc->nomux) { + omap_cfg_reg(Y8_1610_MMC2_CMD); + omap_cfg_reg(Y10_1610_MMC2_CLK); + omap_cfg_reg(R18_1610_MMC2_CLKIN); + omap_cfg_reg(W8_1610_MMC2_DAT0); + if (mmc->wire4) { + omap_cfg_reg(V8_1610_MMC2_DAT1); + omap_cfg_reg(W15_1610_MMC2_DAT2); + omap_cfg_reg(R10_1610_MMC2_DAT3); + } + + /* These are needed for the level shifter */ + omap_cfg_reg(V9_1610_MMC2_CMDDIR); + omap_cfg_reg(V5_1610_MMC2_DATDIR0); + omap_cfg_reg(W19_1610_MMC2_DATDIR1); + } + + /* Feedback clock must be set on OMAP-1710 MMC2 */ + if (cpu_is_omap1710()) + omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), + MOD_CONF_CTRL_1); + mmc2_conf = *mmc; + (void) platform_device_register(&mmc_omap_device2); + } +#endif + return; +} +#else +static inline void omap_init_mmc(void) {} +#endif + +/* + * This gets called after board-specific INIT_MACHINE, and initializes most + * on-chip peripherals accessible on this board (except for few like USB): + * + * (a) Does any "standard config" pin muxing needed. Board-specific + * code will have muxed GPIO pins and done "nonstandard" setup; + * that code could live in the boot loader. + * (b) Populating board-specific platform_data with the data drivers + * rely on to handle wiring variations. + * (c) Creating platform devices as meaningful on this board and + * with this kernel configuration. + * + * Claiming GPIOs, and setting their direction and initial values, is the + * responsibility of the device drivers. So is responding to probe(). + * + * Board-specific knowlege like creating devices or pin setup is to be + * kept out of drivers as much as possible. In particular, pin setup + * may be handled by the boot loader, and drivers should expect it will + * normally have been done by the time they're probed. + */ +static int __init omap_init_devices(void) +{ + /* please keep these calls, and their implementations above, + * in alphabetical order so they're easier to sort through. + */ + omap_init_i2c(); + omap_init_mmc(); + + return 0; +} +arch_initcall(omap_init_devices); + -- 2.41.1