linux/arch/arm/mach-omap2/devices.c
Tony Lindgren 3e9a6321f9 This is the first set of omap cleanup patches for v3.8 merge
window to remove most of the remaining plat includes to get us
 closer to ARM common zImage support.
 
 To avoid a huge amount of trivial merge conflicts with includes,
 this branch is based on several small topic branches coordinated
 with the driver subsystem maintainers. These branches are based on
 v3.7-rc1 and can also be merged into the related driver subsystem
 branches as needed:
 
 omap-for-v3.8/cleanup-headers-prepare   few trivial driver changes
 omap-for-v3.8/cleanup-headers-dma       move of the DMA header
 omap-for-v3.8/cleanup-headers-gpmc      GPMC and MTD changes
 omap-for-v3.8/cleanup-headers-mmc       MMC related changes
 omap-for-v3.8/cleanup-headers-dss       DSS related changes
 omap-for-v3.8/cleanup-headers-asoc      ASoC related changes
 
 Note that for the dma-omap.h, it was decided that it should be
 is completed. For the related discussion, please see:
 
 https://patchwork.kernel.org/patch/1519591/#
 
 After these patches we still have a few plat headers remaining
 that will be handled in later pull requests.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJQgLn6AAoJEBvUPslcq6VztJIQAMDLmUr4XRa0pV9ASPieMSnP
 LqXQ8Gpr8JP6I2A7mjj5K/PVvU2PCIgefX5/F7PssWeDzPs1p6T5eQc6/Oo88j+k
 6xIaPJtuU6aiMKiH4QJBU9mfFZN4tvKNX8sJZ4YhzAmkKshwSd2XdWQlkSWYV7Ii
 QFRXOdYdX3dgvt3Pv5LYhFMlRDzXlMtCNkdyO0C5yDc038FvT5kxcgpOJ99ndX1F
 aSpNPchDwEXP7WZl3O7uZs732hRHQbKraMkzalVJ5mgvLSwF7VsB+BLdjOgRqFfg
 edpAPt/izpTk7cg7RQiItrW3xz3eSiN/fiAg2wLvxr6ewzB5DguPLa6DNPF+uyup
 BlpQAvNsICIixfKb/qimQBOkB71TTRxqvBnG0Vt/cExS1dTuWlhyCYzA6dhZtl+w
 7ETCo7Mmj+L9T1EfzhMPgjWvMZ4Luli4NHSUYxMl5Cs8nu1y6ytIXxH9e0mnZAbK
 n4ANoIuFE3ZueXWnHAVCOs0YZj2F1OLB+mFkIFg3OVpB4WCXiOTgJuDNsAAQNS3/
 VsYVehNFRB/E/lMWkN293j95LRSwl/sIKbvlpxe7M3XQi4IWh1bDPwcg1YhGPxRV
 HIuQSSMIIzcsFoDqbQYv9qzpvslfee58fBV0L8BzMyXNd1lYzWJ5Af6A8ddSVVFS
 Hh+btZObC1zP/2IKbImk
 =HUTj
 -----END PGP SIGNATURE-----

Merge tag 'omap-for-v3.8/cleanup-headers-signed' into omap-for-v3.8/cleanup-headers-serial-take2

This is the first set of omap cleanup patches for v3.8 merge
window to remove most of the remaining plat includes to get us
closer to ARM common zImage support.

To avoid a huge amount of trivial merge conflicts with includes,
this branch is based on several small topic branches coordinated
with the driver subsystem maintainers. These branches are based on
v3.7-rc1 and can also be merged into the related driver subsystem
branches as needed:

omap-for-v3.8/cleanup-headers-prepare   few trivial driver changes
omap-for-v3.8/cleanup-headers-dma       move of the DMA header
omap-for-v3.8/cleanup-headers-gpmc      GPMC and MTD changes
omap-for-v3.8/cleanup-headers-mmc       MMC related changes
omap-for-v3.8/cleanup-headers-dss       DSS related changes
omap-for-v3.8/cleanup-headers-asoc      ASoC related changes

Note that for the dma-omap.h, it was decided that it should be
is completed. For the related discussion, please see:

https://patchwork.kernel.org/patch/1519591/#

After these patches we still have a few plat headers remaining
that will be handled in later pull requests.
2012-10-24 13:25:44 -07:00

675 lines
15 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/gpio.h>
#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 <linux/slab.h>
#include <linux/of.h>
#include <linux/pinctrl/machine.h>
#include <linux/platform_data/omap4-keypad.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <plat-omap/dma-omap.h>
#include "iomap.h"
#include "omap_hwmod.h"
#include "omap_device.h"
#include "omap4-keypad.h"
#include "soc.h"
#include "common.h"
#include "mux.h"
#include "control.h"
#include "devices.h"
#include "dma.h"
#define L3_MODULES_MAX_LEN 12
#define L3_MODULES 3
static int __init omap3_l3_init(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
char oh_name[L3_MODULES_MAX_LEN];
/*
* To avoid code running on other OMAPs in
* multi-omap builds
*/
if (!(cpu_is_omap34xx()))
return -ENODEV;
snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main");
oh = omap_hwmod_lookup(oh_name);
if (!oh)
pr_err("could not look up %s\n", oh_name);
pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0,
NULL, 0, 0);
WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
}
postcore_initcall(omap3_l3_init);
static int __init omap4_l3_init(void)
{
int i;
struct omap_hwmod *oh[3];
struct platform_device *pdev;
char oh_name[L3_MODULES_MAX_LEN];
/* If dtb is there, the devices will be created dynamically */
if (of_have_populated_dt())
return -ENODEV;
/*
* To avoid code running on other OMAPs in
* multi-omap builds
*/
if (!cpu_is_omap44xx() && !soc_is_omap54xx())
return -ENODEV;
for (i = 0; i < L3_MODULES; i++) {
snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main_%d", i+1);
oh[i] = omap_hwmod_lookup(oh_name);
if (!(oh[i]))
pr_err("could not look up %s\n", oh_name);
}
pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL,
0, NULL, 0, 0);
WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
}
postcore_initcall(omap4_l3_init);
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
static struct resource omap2cam_resources[] = {
{
.start = OMAP24XX_CAMERA_BASE,
.end = OMAP24XX_CAMERA_BASE + 0xfff,
.flags = IORESOURCE_MEM,
},
{
.start = 24 + OMAP_INTC_START,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device omap2cam_device = {
.name = "omap24xxcam",
.id = -1,
.num_resources = ARRAY_SIZE(omap2cam_resources),
.resource = omap2cam_resources,
};
#endif
#if defined(CONFIG_IOMMU_API)
#include <plat/iommu.h>
static struct resource omap3isp_resources[] = {
{
.start = OMAP3430_ISP_BASE,
.end = OMAP3430_ISP_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_REGS1_BASE,
.end = OMAP3430_ISP_CSI2A_REGS1_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3430_ISP_CSIPHY2_BASE,
.end = OMAP3430_ISP_CSIPHY2_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSI2A_REGS2_BASE,
.end = OMAP3630_ISP_CSI2A_REGS2_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSI2C_REGS1_BASE,
.end = OMAP3630_ISP_CSI2C_REGS1_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSIPHY1_BASE,
.end = OMAP3630_ISP_CSIPHY1_END,
.flags = IORESOURCE_MEM,
},
{
.start = OMAP3630_ISP_CSI2C_REGS2_BASE,
.end = OMAP3630_ISP_CSI2C_REGS2_END,
.flags = IORESOURCE_MEM,
},
{
.start = 24 + OMAP_INTC_START,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device omap3isp_device = {
.name = "omap3isp",
.id = -1,
.num_resources = ARRAY_SIZE(omap3isp_resources),
.resource = omap3isp_resources,
};
static struct omap_iommu_arch_data omap3_isp_iommu = {
.name = "isp",
};
int omap3_init_camera(struct isp_platform_data *pdata)
{
omap3isp_device.dev.platform_data = pdata;
omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;
return platform_device_register(&omap3isp_device);
}
#else /* !CONFIG_IOMMU_API */
int omap3_init_camera(struct isp_platform_data *pdata)
{
return 0;
}
#endif
static inline void omap_init_camera(void)
{
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
if (cpu_is_omap24xx())
platform_device_register(&omap2cam_device);
#endif
}
int __init omap4_keyboard_init(struct omap4_keypad_platform_data
*sdp4430_keypad_data, struct omap_board_data *bdata)
{
struct platform_device *pdev;
struct omap_hwmod *oh;
struct omap4_keypad_platform_data *keypad_data;
unsigned int id = -1;
char *oh_name = "kbd";
char *name = "omap4-keypad";
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up %s\n", oh_name);
return -ENODEV;
}
keypad_data = sdp4430_keypad_data;
pdev = omap_device_build(name, id, oh, keypad_data,
sizeof(struct omap4_keypad_platform_data), NULL, 0, 0);
if (IS_ERR(pdev)) {
WARN(1, "Can't build omap_device for %s:%s.\n",
name, oh->name);
return PTR_ERR(pdev);
}
oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
return 0;
}
#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
static inline void __init omap_init_mbox(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("mailbox");
if (!oh) {
pr_err("%s: unable to find hwmod\n", __func__);
return;
}
pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0);
WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
__func__, PTR_ERR(pdev));
}
#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,
};
static void omap_init_audio(void)
{
platform_device_register(&omap_pcm);
}
#else
static inline void omap_init_audio(void) {}
#endif
#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
static void __init omap_init_mcpdm(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("mcpdm");
if (!oh) {
printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
return;
}
pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0, NULL, 0, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n");
}
#else
static inline void omap_init_mcpdm(void) {}
#endif
#if defined(CONFIG_SND_OMAP_SOC_DMIC) || \
defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE)
static void __init omap_init_dmic(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("dmic");
if (!oh) {
pr_err("Could not look up dmic hw_mod\n");
return;
}
pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n");
}
#else
static inline void omap_init_dmic(void) {}
#endif
#if defined(CONFIG_SND_OMAP_SOC_OMAP_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP_HDMI_MODULE)
static struct platform_device omap_hdmi_audio = {
.name = "omap-hdmi-audio",
.id = -1,
};
static void __init omap_init_hdmi_audio(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("dss_hdmi");
if (!oh) {
printk(KERN_ERR "Could not look up dss_hdmi hw_mod\n");
return;
}
pdev = omap_device_build("omap-hdmi-audio-dai",
-1, oh, NULL, 0, NULL, 0, 0);
WARN(IS_ERR(pdev),
"Can't build omap_device for omap-hdmi-audio-dai.\n");
platform_device_register(&omap_hdmi_audio);
}
#else
static inline void omap_init_hdmi_audio(void) {}
#endif
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
#include <linux/platform_data/spi-omap2-mcspi.h>
static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)
{
struct platform_device *pdev;
char *name = "omap2_mcspi";
struct omap2_mcspi_platform_config *pdata;
static int spi_num;
struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
pr_err("Memory allocation for McSPI device failed\n");
return -ENOMEM;
}
pdata->num_cs = mcspi_attrib->num_chipselect;
switch (oh->class->rev) {
case OMAP2_MCSPI_REV:
case OMAP3_MCSPI_REV:
pdata->regs_offset = 0;
break;
case OMAP4_MCSPI_REV:
pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET;
break;
default:
pr_err("Invalid McSPI Revision value\n");
kfree(pdata);
return -EINVAL;
}
spi_num++;
pdev = omap_device_build(name, spi_num, oh, pdata,
sizeof(*pdata), NULL, 0, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",
name, oh->name);
kfree(pdata);
return 0;
}
static void omap_init_mcspi(void)
{
omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL);
}
#else
static inline void omap_init_mcspi(void) {}
#endif
/**
* omap_init_rng - bind the RNG hwmod to the RNG omap_device
*
* Bind the RNG hwmod to the RNG omap_device. No return value.
*/
static void omap_init_rng(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
oh = omap_hwmod_lookup("rng");
if (!oh)
return;
pdev = omap_device_build("omap_rng", -1, oh, NULL, 0, NULL, 0, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
}
#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 = 51 + OMAP_INTC_START,
.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 = 49 + OMAP_INTC_START,
.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_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)
{
/* Enable dummy states for those platforms without pinctrl support */
if (!of_have_populated_dt())
pinctrl_provide_dummies();
/*
* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
omap_init_audio();
omap_init_camera();
omap_init_hdmi_audio();
omap_init_mbox();
/* If dtb is there, the devices will be created dynamically */
if (!of_have_populated_dt()) {
omap_init_dmic();
omap_init_mcpdm();
omap_init_mcspi();
}
omap_init_sti();
omap_init_rng();
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)
static int __init omap_init_wdt(void)
{
int id = -1;
struct platform_device *pdev;
struct omap_hwmod *oh;
char *oh_name = "wd_timer2";
char *dev_name = "omap_wdt";
if (!cpu_class_is_omap2() || of_have_populated_dt())
return 0;
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up wd_timer%d hwmod\n", id);
return -EINVAL;
}
pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
dev_name, oh->name);
return 0;
}
subsys_initcall(omap_init_wdt);
#endif