1/* 2 * linux/arch/arm/mach-omap2/devices.c 3 * 4 * OMAP2 platform device setup/initialization 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11#include <linux/gpio.h> 12#include <linux/kernel.h> 13#include <linux/init.h> 14#include <linux/platform_device.h> 15#include <linux/io.h> 16#include <linux/clk.h> 17#include <linux/err.h> 18#include <linux/slab.h> 19#include <linux/of.h> 20#include <linux/pinctrl/machine.h> 21#include <linux/platform_data/mailbox-omap.h> 22 23#include <asm/mach-types.h> 24#include <asm/mach/map.h> 25 26#include <linux/omap-dma.h> 27 28#include "iomap.h" 29#include "omap_hwmod.h" 30#include "omap_device.h" 31 32#include "soc.h" 33#include "common.h" 34#include "mux.h" 35#include "control.h" 36#include "display.h" 37 38#define L3_MODULES_MAX_LEN 12 39#define L3_MODULES 3 40 41static int __init omap3_l3_init(void) 42{ 43 struct omap_hwmod *oh; 44 struct platform_device *pdev; 45 char oh_name[L3_MODULES_MAX_LEN]; 46 47 /* 48 * To avoid code running on other OMAPs in 49 * multi-omap builds 50 */ 51 if (!(cpu_is_omap34xx()) || of_have_populated_dt()) 52 return -ENODEV; 53 54 snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main"); 55 56 oh = omap_hwmod_lookup(oh_name); 57 58 if (!oh) 59 pr_err("could not look up %s\n", oh_name); 60 61 pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0); 62 63 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); 64 65 return PTR_ERR_OR_ZERO(pdev); 66} 67omap_postcore_initcall(omap3_l3_init); 68 69#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) 70static inline void __init omap_init_mbox(void) 71{ 72 struct omap_hwmod *oh; 73 struct platform_device *pdev; 74 struct omap_mbox_pdata *pdata; 75 76 oh = omap_hwmod_lookup("mailbox"); 77 if (!oh) { 78 pr_err("%s: unable to find hwmod\n", __func__); 79 return; 80 } 81 if (!oh->dev_attr) { 82 pr_err("%s: hwmod doesn't have valid attrs\n", __func__); 83 return; 84 } 85 86 pdata = (struct omap_mbox_pdata *)oh->dev_attr; 87 pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata)); 88 WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", 89 __func__, PTR_ERR(pdev)); 90} 91#else 92static inline void omap_init_mbox(void) { } 93#endif /* CONFIG_OMAP2PLUS_MBOX */ 94 95static inline void omap_init_sti(void) {} 96 97#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE) 98 99static struct platform_device omap_pcm = { 100 .name = "omap-pcm-audio", 101 .id = -1, 102}; 103 104static void omap_init_audio(void) 105{ 106 platform_device_register(&omap_pcm); 107} 108 109#else 110static inline void omap_init_audio(void) {} 111#endif 112 113#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) 114 115#include <linux/platform_data/spi-omap2-mcspi.h> 116 117static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) 118{ 119 struct platform_device *pdev; 120 char *name = "omap2_mcspi"; 121 struct omap2_mcspi_platform_config *pdata; 122 static int spi_num; 123 struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; 124 125 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); 126 if (!pdata) { 127 pr_err("Memory allocation for McSPI device failed\n"); 128 return -ENOMEM; 129 } 130 131 pdata->num_cs = mcspi_attrib->num_chipselect; 132 switch (oh->class->rev) { 133 case OMAP2_MCSPI_REV: 134 case OMAP3_MCSPI_REV: 135 pdata->regs_offset = 0; 136 break; 137 case OMAP4_MCSPI_REV: 138 pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; 139 break; 140 default: 141 pr_err("Invalid McSPI Revision value\n"); 142 kfree(pdata); 143 return -EINVAL; 144 } 145 146 spi_num++; 147 pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata)); 148 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", 149 name, oh->name); 150 kfree(pdata); 151 return 0; 152} 153 154static void omap_init_mcspi(void) 155{ 156 omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); 157} 158 159#else 160static inline void omap_init_mcspi(void) {} 161#endif 162 163/** 164 * omap_init_rng - bind the RNG hwmod to the RNG omap_device 165 * 166 * Bind the RNG hwmod to the RNG omap_device. No return value. 167 */ 168static void omap_init_rng(void) 169{ 170 struct omap_hwmod *oh; 171 struct platform_device *pdev; 172 173 oh = omap_hwmod_lookup("rng"); 174 if (!oh) 175 return; 176 177 pdev = omap_device_build("omap_rng", -1, oh, NULL, 0); 178 WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); 179} 180 181static void __init omap_init_sham(void) 182{ 183 struct omap_hwmod *oh; 184 struct platform_device *pdev; 185 186 oh = omap_hwmod_lookup("sham"); 187 if (!oh) 188 return; 189 190 pdev = omap_device_build("omap-sham", -1, oh, NULL, 0); 191 WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n"); 192} 193 194static void __init omap_init_aes(void) 195{ 196 struct omap_hwmod *oh; 197 struct platform_device *pdev; 198 199 oh = omap_hwmod_lookup("aes"); 200 if (!oh) 201 return; 202 203 pdev = omap_device_build("omap-aes", -1, oh, NULL, 0); 204 WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n"); 205} 206 207/*-------------------------------------------------------------------------*/ 208 209#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ 210 defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) 211#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) 212static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = { 213}; 214#else 215static struct resource omap_vout_resource[2] = { 216}; 217#endif 218 219static struct platform_device omap_vout_device = { 220 .name = "omap_vout", 221 .num_resources = ARRAY_SIZE(omap_vout_resource), 222 .resource = &omap_vout_resource[0], 223 .id = -1, 224}; 225 226int __init omap_init_vout(void) 227{ 228 return platform_device_register(&omap_vout_device); 229} 230#else 231int __init omap_init_vout(void) { return 0; } 232#endif 233 234/*-------------------------------------------------------------------------*/ 235 236static int __init omap2_init_devices(void) 237{ 238 /* Enable dummy states for those platforms without pinctrl support */ 239 if (!of_have_populated_dt()) 240 pinctrl_provide_dummies(); 241 242 /* 243 * please keep these calls, and their implementations above, 244 * in alphabetical order so they're easier to sort through. 245 */ 246 omap_init_audio(); 247 /* If dtb is there, the devices will be created dynamically */ 248 if (!of_have_populated_dt()) { 249 omap_init_mbox(); 250 omap_init_mcspi(); 251 omap_init_sham(); 252 omap_init_aes(); 253 omap_init_rng(); 254 } 255 omap_init_sti(); 256 257 return 0; 258} 259omap_arch_initcall(omap2_init_devices); 260 261static int __init omap_gpmc_init(void) 262{ 263 struct omap_hwmod *oh; 264 struct platform_device *pdev; 265 char *oh_name = "gpmc"; 266 267 /* 268 * if the board boots up with a populated DT, do not 269 * manually add the device from this initcall 270 */ 271 if (of_have_populated_dt()) 272 return -ENODEV; 273 274 oh = omap_hwmod_lookup(oh_name); 275 if (!oh) { 276 pr_err("Could not look up %s\n", oh_name); 277 return -ENODEV; 278 } 279 280 pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0); 281 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); 282 283 return PTR_ERR_OR_ZERO(pdev); 284} 285omap_postcore_initcall(omap_gpmc_init); 286