kernel-ark/arch/arm/mach-omap2/devices.c
Paul Walmsley ff2516fbef OMAP2+: wd_timer: disable on boot via hwmod postsetup mechanism
The OMAP watchdog timer IP blocks require a specific set of register
writes to occur before they will be disabled[1], even if the device
clocks appear to be disabled in the CM_*CLKEN registers.  In the MPU
watchdog case, failure to execute this reset sequence will eventually
cause the watchdog to reset the OMAP unexpectedly.

Previously, the code to disable this watchdog was manually called from
mach-omap2/devices.c during device initialization.  This causes the
watchdog to be unconditionally disabled for a portion of kernel
initialization.  This should be controllable by the board-*.c files,
since some system integrators will want full watchdog coverage of
kernel initialization.  Also, the watchdog disable code was not
connected to the hwmod shutdown code.  This means that calling
omap_hwmod_shutdown() will not, in fact, disable the watchdog, and the
goal of omap_hwmod_shutdown() is to be able to shutdown any on-chip
OMAP device.

To resolve the latter problem, populate the pre_shutdown pointer in
the watchdog timer hwmod classes with a function that executes the
watchdog shutdown sequence.  This allows the hwmod code to fully
disable the watchdog.

Then, to allow some board files to support watchdog coverage
throughout kernel initialization, add common code to mach-omap2/io.c
to cause the MPU watchdog to be disabled on boot unless a board file
specifically requests it to remain enabled.  Board files can do this
by changing the watchdog timer hwmod's postsetup state between the
omap2_init_common_infrastructure() and omap2_init_common_devices()
function calls.

1. OMAP34xx Multimedia Device Silicon Revision 3.1.x Rev. ZH
   [SWPU222H], Section 16.4.3.6, "Start/Stop Sequence for WDTs (Using
   WDTi.WSPR Register)"

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Charulatha Varadarajan <charu@ti.com>
2010-12-21 19:57:40 -07:00

1015 lines
24 KiB
C

/*
* linux/arch/arm/mach-omap2/devices.c
*
* OMAP2 platform device setup/initialization
*
* 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 <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/pmu.h>
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mcbsp.h>
#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/dma.h>
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
#include "mux.h"
#include "control.h"
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
static struct resource cam_resources[] = {
{
.start = OMAP24XX_CAMERA_BASE,
.end = OMAP24XX_CAMERA_BASE + 0xfff,
.flags = IORESOURCE_MEM,
},
{
.start = INT_24XX_CAM_IRQ,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device omap_cam_device = {
.name = "omap24xxcam",
.id = -1,
.num_resources = ARRAY_SIZE(cam_resources),
.resource = cam_resources,
};
static inline void omap_init_camera(void)
{
platform_device_register(&omap_cam_device);
}
#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
static struct resource omap3isp_resources[] = {
{
.start = OMAP3430_ISP_BASE,
.end = OMAP3430_ISP_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CBUFF_BASE,
.end = OMAP3430_ISP_CBUFF_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CCP2_BASE,
.end = OMAP3430_ISP_CCP2_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CCDC_BASE,
.end = OMAP3430_ISP_CCDC_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_HIST_BASE,
.end = OMAP3430_ISP_HIST_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_H3A_BASE,
.end = OMAP3430_ISP_H3A_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_PREV_BASE,
.end = OMAP3430_ISP_PREV_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_RESZ_BASE,
.end = OMAP3430_ISP_RESZ_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_SBL_BASE,
.end = OMAP3430_ISP_SBL_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CSI2A_BASE,
.end = OMAP3430_ISP_CSI2A_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CSI2PHY_BASE,
.end = OMAP3430_ISP_CSI2PHY_END,
.flags = IORESOURCE_MEM,
},
{
.start = INT_34XX_CAM_IRQ,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device omap3isp_device = {
.name = "omap3isp",
.id = -1,
.num_resources = ARRAY_SIZE(omap3isp_resources),
.resource = omap3isp_resources,
};
static inline void omap_init_camera(void)
{
platform_device_register(&omap3isp_device);
}
#else
static inline void omap_init_camera(void)
{
}
#endif
#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
#define MBOX_REG_SIZE 0x120
#ifdef CONFIG_ARCH_OMAP2
static struct resource omap2_mbox_resources[] = {
{
.start = OMAP24XX_MAILBOX_BASE,
.end = OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_24XX_MAIL_U0_MPU,
.flags = IORESOURCE_IRQ,
.name = "dsp",
},
{
.start = INT_24XX_MAIL_U3_MPU,
.flags = IORESOURCE_IRQ,
.name = "iva",
},
};
static int omap2_mbox_resources_sz = ARRAY_SIZE(omap2_mbox_resources);
#else
#define omap2_mbox_resources NULL
#define omap2_mbox_resources_sz 0
#endif
#ifdef CONFIG_ARCH_OMAP3
static struct resource omap3_mbox_resources[] = {
{
.start = OMAP34XX_MAILBOX_BASE,
.end = OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_24XX_MAIL_U0_MPU,
.flags = IORESOURCE_IRQ,
.name = "dsp",
},
};
static int omap3_mbox_resources_sz = ARRAY_SIZE(omap3_mbox_resources);
#else
#define omap3_mbox_resources NULL
#define omap3_mbox_resources_sz 0
#endif
#ifdef CONFIG_ARCH_OMAP4
#define OMAP4_MBOX_REG_SIZE 0x130
static struct resource omap4_mbox_resources[] = {
{
.start = OMAP44XX_MAILBOX_BASE,
.end = OMAP44XX_MAILBOX_BASE +
OMAP4_MBOX_REG_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP44XX_IRQ_MAIL_U0,
.flags = IORESOURCE_IRQ,
.name = "mbox",
},
};
static int omap4_mbox_resources_sz = ARRAY_SIZE(omap4_mbox_resources);
#else
#define omap4_mbox_resources NULL
#define omap4_mbox_resources_sz 0
#endif
static struct platform_device mbox_device = {
.name = "omap-mailbox",
.id = -1,
};
static inline void omap_init_mbox(void)
{
if (cpu_is_omap24xx()) {
mbox_device.resource = omap2_mbox_resources;
mbox_device.num_resources = omap2_mbox_resources_sz;
} else if (cpu_is_omap34xx()) {
mbox_device.resource = omap3_mbox_resources;
mbox_device.num_resources = omap3_mbox_resources_sz;
} else if (cpu_is_omap44xx()) {
mbox_device.resource = omap4_mbox_resources;
mbox_device.num_resources = omap4_mbox_resources_sz;
} else {
pr_err("%s: platform not supported\n", __func__);
return;
}
platform_device_register(&mbox_device);
}
#else
static inline void omap_init_mbox(void) { }
#endif /* CONFIG_OMAP_MBOX_FWK */
static inline void omap_init_sti(void) {}
#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
static struct platform_device omap_pcm = {
.name = "omap-pcm-audio",
.id = -1,
};
/*
* OMAP2420 has 2 McBSP ports
* OMAP2430 has 5 McBSP ports
* OMAP3 has 5 McBSP ports
* OMAP4 has 4 McBSP ports
*/
OMAP_MCBSP_PLATFORM_DEVICE(1);
OMAP_MCBSP_PLATFORM_DEVICE(2);
OMAP_MCBSP_PLATFORM_DEVICE(3);
OMAP_MCBSP_PLATFORM_DEVICE(4);
OMAP_MCBSP_PLATFORM_DEVICE(5);
static void omap_init_audio(void)
{
platform_device_register(&omap_mcbsp1);
platform_device_register(&omap_mcbsp2);
if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
platform_device_register(&omap_mcbsp3);
platform_device_register(&omap_mcbsp4);
}
if (cpu_is_omap243x() || cpu_is_omap34xx())
platform_device_register(&omap_mcbsp5);
platform_device_register(&omap_pcm);
}
#else
static inline void omap_init_audio(void) {}
#endif
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
#include <plat/mcspi.h>
#define OMAP2_MCSPI1_BASE 0x48098000
#define OMAP2_MCSPI2_BASE 0x4809a000
#define OMAP2_MCSPI3_BASE 0x480b8000
#define OMAP2_MCSPI4_BASE 0x480ba000
#define OMAP4_MCSPI1_BASE 0x48098100
#define OMAP4_MCSPI2_BASE 0x4809a100
#define OMAP4_MCSPI3_BASE 0x480b8100
#define OMAP4_MCSPI4_BASE 0x480ba100
static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
.num_cs = 4,
};
static struct resource omap2_mcspi1_resources[] = {
{
.start = OMAP2_MCSPI1_BASE,
.end = OMAP2_MCSPI1_BASE + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device omap2_mcspi1 = {
.name = "omap2_mcspi",
.id = 1,
.num_resources = ARRAY_SIZE(omap2_mcspi1_resources),
.resource = omap2_mcspi1_resources,
.dev = {
.platform_data = &omap2_mcspi1_config,
},
};
static struct omap2_mcspi_platform_config omap2_mcspi2_config = {
.num_cs = 2,
};
static struct resource omap2_mcspi2_resources[] = {
{
.start = OMAP2_MCSPI2_BASE,
.end = OMAP2_MCSPI2_BASE + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device omap2_mcspi2 = {
.name = "omap2_mcspi",
.id = 2,
.num_resources = ARRAY_SIZE(omap2_mcspi2_resources),
.resource = omap2_mcspi2_resources,
.dev = {
.platform_data = &omap2_mcspi2_config,
},
};
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
defined(CONFIG_ARCH_OMAP4)
static struct omap2_mcspi_platform_config omap2_mcspi3_config = {
.num_cs = 2,
};
static struct resource omap2_mcspi3_resources[] = {
{
.start = OMAP2_MCSPI3_BASE,
.end = OMAP2_MCSPI3_BASE + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device omap2_mcspi3 = {
.name = "omap2_mcspi",
.id = 3,
.num_resources = ARRAY_SIZE(omap2_mcspi3_resources),
.resource = omap2_mcspi3_resources,
.dev = {
.platform_data = &omap2_mcspi3_config,
},
};
#endif
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
static struct omap2_mcspi_platform_config omap2_mcspi4_config = {
.num_cs = 1,
};
static struct resource omap2_mcspi4_resources[] = {
{
.start = OMAP2_MCSPI4_BASE,
.end = OMAP2_MCSPI4_BASE + 0xff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device omap2_mcspi4 = {
.name = "omap2_mcspi",
.id = 4,
.num_resources = ARRAY_SIZE(omap2_mcspi4_resources),
.resource = omap2_mcspi4_resources,
.dev = {
.platform_data = &omap2_mcspi4_config,
},
};
#endif
#ifdef CONFIG_ARCH_OMAP4
static inline void omap4_mcspi_fixup(void)
{
omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE;
omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff;
omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE;
omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff;
omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE;
omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff;
omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE;
omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff;
}
#else
static inline void omap4_mcspi_fixup(void)
{
}
#endif
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
defined(CONFIG_ARCH_OMAP4)
static inline void omap2_mcspi3_init(void)
{
platform_device_register(&omap2_mcspi3);
}
#else
static inline void omap2_mcspi3_init(void)
{
}
#endif
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
static inline void omap2_mcspi4_init(void)
{
platform_device_register(&omap2_mcspi4);
}
#else
static inline void omap2_mcspi4_init(void)
{
}
#endif
static void omap_init_mcspi(void)
{
if (cpu_is_omap44xx())
omap4_mcspi_fixup();
platform_device_register(&omap2_mcspi1);
platform_device_register(&omap2_mcspi2);
if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx())
omap2_mcspi3_init();
if (cpu_is_omap343x() || cpu_is_omap44xx())
omap2_mcspi4_init();
}
#else
static inline void omap_init_mcspi(void) {}
#endif
static struct resource omap2_pmu_resource = {
.start = 3,
.end = 3,
.flags = IORESOURCE_IRQ,
};
static struct resource omap3_pmu_resource = {
.start = INT_34XX_BENCH_MPU_EMUL,
.end = INT_34XX_BENCH_MPU_EMUL,
.flags = IORESOURCE_IRQ,
};
static struct platform_device omap_pmu_device = {
.name = "arm-pmu",
.id = ARM_PMU_DEVICE_CPU,
.num_resources = 1,
};
static void omap_init_pmu(void)
{
if (cpu_is_omap24xx())
omap_pmu_device.resource = &omap2_pmu_resource;
else if (cpu_is_omap34xx())
omap_pmu_device.resource = &omap3_pmu_resource;
else
return;
platform_device_register(&omap_pmu_device);
}
#if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
#ifdef CONFIG_ARCH_OMAP2
static struct resource omap2_sham_resources[] = {
{
.start = OMAP24XX_SEC_SHA1MD5_BASE,
.end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
.flags = IORESOURCE_MEM,
},
{
.start = INT_24XX_SHA1MD5,
.flags = IORESOURCE_IRQ,
}
};
static int omap2_sham_resources_sz = ARRAY_SIZE(omap2_sham_resources);
#else
#define omap2_sham_resources NULL
#define omap2_sham_resources_sz 0
#endif
#ifdef CONFIG_ARCH_OMAP3
static struct resource omap3_sham_resources[] = {
{
.start = OMAP34XX_SEC_SHA1MD5_BASE,
.end = OMAP34XX_SEC_SHA1MD5_BASE + 0x64,
.flags = IORESOURCE_MEM,
},
{
.start = INT_34XX_SHA1MD52_IRQ,
.flags = IORESOURCE_IRQ,
},
{
.start = OMAP34XX_DMA_SHA1MD5_RX,
.flags = IORESOURCE_DMA,
}
};
static int omap3_sham_resources_sz = ARRAY_SIZE(omap3_sham_resources);
#else
#define omap3_sham_resources NULL
#define omap3_sham_resources_sz 0
#endif
static struct platform_device sham_device = {
.name = "omap-sham",
.id = -1,
};
static void omap_init_sham(void)
{
if (cpu_is_omap24xx()) {
sham_device.resource = omap2_sham_resources;
sham_device.num_resources = omap2_sham_resources_sz;
} else if (cpu_is_omap34xx()) {
sham_device.resource = omap3_sham_resources;
sham_device.num_resources = omap3_sham_resources_sz;
} else {
pr_err("%s: platform not supported\n", __func__);
return;
}
platform_device_register(&sham_device);
}
#else
static inline void omap_init_sham(void) { }
#endif
#if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
#ifdef CONFIG_ARCH_OMAP2
static struct resource omap2_aes_resources[] = {
{
.start = OMAP24XX_SEC_AES_BASE,
.end = OMAP24XX_SEC_AES_BASE + 0x4C,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP24XX_DMA_AES_TX,
.flags = IORESOURCE_DMA,
},
{
.start = OMAP24XX_DMA_AES_RX,
.flags = IORESOURCE_DMA,
}
};
static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources);
#else
#define omap2_aes_resources NULL
#define omap2_aes_resources_sz 0
#endif
#ifdef CONFIG_ARCH_OMAP3
static struct resource omap3_aes_resources[] = {
{
.start = OMAP34XX_SEC_AES_BASE,
.end = OMAP34XX_SEC_AES_BASE + 0x4C,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP34XX_DMA_AES2_TX,
.flags = IORESOURCE_DMA,
},
{
.start = OMAP34XX_DMA_AES2_RX,
.flags = IORESOURCE_DMA,
}
};
static int omap3_aes_resources_sz = ARRAY_SIZE(omap3_aes_resources);
#else
#define omap3_aes_resources NULL
#define omap3_aes_resources_sz 0
#endif
static struct platform_device aes_device = {
.name = "omap-aes",
.id = -1,
};
static void omap_init_aes(void)
{
if (cpu_is_omap24xx()) {
aes_device.resource = omap2_aes_resources;
aes_device.num_resources = omap2_aes_resources_sz;
} else if (cpu_is_omap34xx()) {
aes_device.resource = omap3_aes_resources;
aes_device.num_resources = omap3_aes_resources_sz;
} else {
pr_err("%s: platform not supported\n", __func__);
return;
}
platform_device_register(&aes_device);
}
#else
static inline void omap_init_aes(void) { }
#endif
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
#define MMCHS_SYSCONFIG 0x0010
#define MMCHS_SYSCONFIG_SWRESET (1 << 1)
#define MMCHS_SYSSTATUS 0x0014
#define MMCHS_SYSSTATUS_RESETDONE (1 << 0)
static struct platform_device dummy_pdev = {
.dev = {
.bus = &platform_bus_type,
},
};
/**
* omap_hsmmc_reset() - Full reset of each HS-MMC controller
*
* Ensure that each MMC controller is fully reset. Controllers
* left in an unknown state (by bootloader) may prevent retention
* or OFF-mode. This is especially important in cases where the
* MMC driver is not enabled, _or_ built as a module.
*
* In order for reset to work, interface, functional and debounce
* clocks must be enabled. The debounce clock comes from func_32k_clk
* and is not under SW control, so we only enable i- and f-clocks.
**/
static void __init omap_hsmmc_reset(void)
{
u32 i, nr_controllers;
struct clk *iclk, *fclk;
if (cpu_is_omap242x())
return;
nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC :
(cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC);
for (i = 0; i < nr_controllers; i++) {
u32 v, base = 0;
struct device *dev = &dummy_pdev.dev;
switch (i) {
case 0:
base = OMAP2_MMC1_BASE;
break;
case 1:
base = OMAP2_MMC2_BASE;
break;
case 2:
base = OMAP3_MMC3_BASE;
break;
case 3:
if (!cpu_is_omap44xx())
return;
base = OMAP4_MMC4_BASE;
break;
case 4:
if (!cpu_is_omap44xx())
return;
base = OMAP4_MMC5_BASE;
break;
}
if (cpu_is_omap44xx())
base += OMAP4_MMC_REG_OFFSET;
dummy_pdev.id = i;
dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
iclk = clk_get(dev, "ick");
if (IS_ERR(iclk))
goto err1;
if (clk_enable(iclk))
goto err2;
fclk = clk_get(dev, "fck");
if (IS_ERR(fclk))
goto err3;
if (clk_enable(fclk))
goto err4;
omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
v = omap_readl(base + MMCHS_SYSSTATUS);
while (!(omap_readl(base + MMCHS_SYSSTATUS) &
MMCHS_SYSSTATUS_RESETDONE))
cpu_relax();
clk_disable(fclk);
clk_put(fclk);
clk_disable(iclk);
clk_put(iclk);
}
return;
err4:
clk_put(fclk);
err3:
clk_disable(iclk);
err2:
clk_put(iclk);
err1:
printk(KERN_WARNING "%s: Unable to enable clocks for MMC%d, "
"cannot reset.\n", __func__, i);
}
#else
static inline void omap_hsmmc_reset(void) {}
#endif
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
int controller_nr)
{
if ((mmc_controller->slots[0].switch_pin > 0) && \
(mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
OMAP_PIN_INPUT_PULLUP);
if ((mmc_controller->slots[0].gpio_wp > 0) && \
(mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
OMAP_PIN_INPUT_PULLUP);
if (cpu_is_omap2420() && controller_nr == 0) {
omap_mux_init_signal("sdmmc_cmd", 0);
omap_mux_init_signal("sdmmc_clki", 0);
omap_mux_init_signal("sdmmc_clko", 0);
omap_mux_init_signal("sdmmc_dat0", 0);
omap_mux_init_signal("sdmmc_dat_dir0", 0);
omap_mux_init_signal("sdmmc_cmd_dir", 0);
if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
omap_mux_init_signal("sdmmc_dat1", 0);
omap_mux_init_signal("sdmmc_dat2", 0);
omap_mux_init_signal("sdmmc_dat3", 0);
omap_mux_init_signal("sdmmc_dat_dir1", 0);
omap_mux_init_signal("sdmmc_dat_dir2", 0);
omap_mux_init_signal("sdmmc_dat_dir3", 0);
}
/*
* Use internal loop-back in MMC/SDIO Module Input Clock
* selection
*/
if (mmc_controller->slots[0].internal_clock) {
u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
v |= (1 << 24);
omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
}
}
if (cpu_is_omap34xx()) {
if (controller_nr == 0) {
omap_mux_init_signal("sdmmc1_clk",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_cmd",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat0",
OMAP_PIN_INPUT_PULLUP);
if (mmc_controller->slots[0].caps &
(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
omap_mux_init_signal("sdmmc1_dat1",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat2",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat3",
OMAP_PIN_INPUT_PULLUP);
}
if (mmc_controller->slots[0].caps &
MMC_CAP_8_BIT_DATA) {
omap_mux_init_signal("sdmmc1_dat4",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat5",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat6",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc1_dat7",
OMAP_PIN_INPUT_PULLUP);
}
}
if (controller_nr == 1) {
/* MMC2 */
omap_mux_init_signal("sdmmc2_clk",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_cmd",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat0",
OMAP_PIN_INPUT_PULLUP);
/*
* For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
* in the board-*.c files
*/
if (mmc_controller->slots[0].caps &
(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
omap_mux_init_signal("sdmmc2_dat1",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat2",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat3",
OMAP_PIN_INPUT_PULLUP);
}
if (mmc_controller->slots[0].caps &
MMC_CAP_8_BIT_DATA) {
omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7",
OMAP_PIN_INPUT_PULLUP);
}
}
/*
* For MMC3 the pins need to be muxed in the board-*.c files
*/
}
}
void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers)
{
int i;
char *name;
for (i = 0; i < nr_controllers; i++) {
unsigned long base, size;
unsigned int irq = 0;
if (!mmc_data[i])
continue;
omap2_mmc_mux(mmc_data[i], i);
switch (i) {
case 0:
base = OMAP2_MMC1_BASE;
irq = INT_24XX_MMC_IRQ;
break;
case 1:
base = OMAP2_MMC2_BASE;
irq = INT_24XX_MMC2_IRQ;
break;
case 2:
if (!cpu_is_omap44xx() && !cpu_is_omap34xx())
return;
base = OMAP3_MMC3_BASE;
irq = INT_34XX_MMC3_IRQ;
break;
case 3:
if (!cpu_is_omap44xx())
return;
base = OMAP4_MMC4_BASE;
irq = OMAP44XX_IRQ_MMC4;
break;
case 4:
if (!cpu_is_omap44xx())
return;
base = OMAP4_MMC5_BASE;
irq = OMAP44XX_IRQ_MMC5;
break;
default:
continue;
}
if (cpu_is_omap2420()) {
size = OMAP2420_MMC_SIZE;
name = "mmci-omap";
} else if (cpu_is_omap44xx()) {
if (i < 3)
irq += OMAP44XX_IRQ_GIC_START;
size = OMAP4_HSMMC_SIZE;
name = "mmci-omap-hs";
} else {
size = OMAP3_HSMMC_SIZE;
name = "mmci-omap-hs";
}
omap_mmc_add(name, i, base, size, irq, mmc_data[i]);
};
}
#endif
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
#define OMAP_HDQ_BASE 0x480B2000
#endif
static struct resource omap_hdq_resources[] = {
{
.start = OMAP_HDQ_BASE,
.end = OMAP_HDQ_BASE + 0x1C,
.flags = IORESOURCE_MEM,
},
{
.start = INT_24XX_HDQ_IRQ,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device omap_hdq_dev = {
.name = "omap_hdq",
.id = 0,
.dev = {
.platform_data = NULL,
},
.num_resources = ARRAY_SIZE(omap_hdq_resources),
.resource = omap_hdq_resources,
};
static inline void omap_hdq_init(void)
{
(void) platform_device_register(&omap_hdq_dev);
}
#else
static inline void omap_hdq_init(void) {}
#endif
/*---------------------------------------------------------------------------*/
#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = {
};
#else
static struct resource omap_vout_resource[2] = {
};
#endif
static struct platform_device omap_vout_device = {
.name = "omap_vout",
.num_resources = ARRAY_SIZE(omap_vout_resource),
.resource = &omap_vout_resource[0],
.id = -1,
};
static void omap_init_vout(void)
{
if (platform_device_register(&omap_vout_device) < 0)
printk(KERN_ERR "Unable to register OMAP-VOUT device\n");
}
#else
static inline void omap_init_vout(void) {}
#endif
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
{
/*
* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
omap_hsmmc_reset();
omap_init_audio();
omap_init_camera();
omap_init_mbox();
omap_init_mcspi();
omap_init_pmu();
omap_hdq_init();
omap_init_sti();
omap_init_sham();
omap_init_aes();
omap_init_vout();
return 0;
}
arch_initcall(omap2_init_devices);
#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
struct omap_device_pm_latency omap_wdt_latency[] = {
[0] = {
.deactivate_func = omap_device_idle_hwmods,
.activate_func = omap_device_enable_hwmods,
.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
},
};
static int __init omap_init_wdt(void)
{
int id = -1;
struct omap_device *od;
struct omap_hwmod *oh;
char *oh_name = "wd_timer2";
char *dev_name = "omap_wdt";
if (!cpu_class_is_omap2())
return 0;
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up wd_timer%d hwmod\n", id);
return -EINVAL;
}
od = omap_device_build(dev_name, id, oh, NULL, 0,
omap_wdt_latency,
ARRAY_SIZE(omap_wdt_latency), 0);
WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
dev_name, oh->name);
return 0;
}
subsys_initcall(omap_init_wdt);
#endif