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 "devices.h" 37 #include "display.h" 38 39 #define L3_MODULES_MAX_LEN 12 40 #define L3_MODULES 3 41 42 static int __init omap3_l3_init(void) 43 { 44 struct omap_hwmod *oh; 45 struct platform_device *pdev; 46 char oh_name[L3_MODULES_MAX_LEN]; 47 48 /* 49 * To avoid code running on other OMAPs in 50 * multi-omap builds 51 */ 52 if (!(cpu_is_omap34xx()) || of_have_populated_dt()) 53 return -ENODEV; 54 55 snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main"); 56 57 oh = omap_hwmod_lookup(oh_name); 58 59 if (!oh) 60 pr_err("could not look up %s\n", oh_name); 61 62 pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0); 63 64 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); 65 66 return PTR_RET(pdev); 67 } 68 omap_postcore_initcall(omap3_l3_init); 69 70 #if defined(CONFIG_IOMMU_API) 71 72 #include <linux/platform_data/iommu-omap.h> 73 74 static struct resource omap3isp_resources[] = { 75 { 76 .start = OMAP3430_ISP_BASE, 77 .end = OMAP3430_ISP_END, 78 .flags = IORESOURCE_MEM, 79 }, 80 { 81 .start = OMAP3430_ISP_CCP2_BASE, 82 .end = OMAP3430_ISP_CCP2_END, 83 .flags = IORESOURCE_MEM, 84 }, 85 { 86 .start = OMAP3430_ISP_CCDC_BASE, 87 .end = OMAP3430_ISP_CCDC_END, 88 .flags = IORESOURCE_MEM, 89 }, 90 { 91 .start = OMAP3430_ISP_HIST_BASE, 92 .end = OMAP3430_ISP_HIST_END, 93 .flags = IORESOURCE_MEM, 94 }, 95 { 96 .start = OMAP3430_ISP_H3A_BASE, 97 .end = OMAP3430_ISP_H3A_END, 98 .flags = IORESOURCE_MEM, 99 }, 100 { 101 .start = OMAP3430_ISP_PREV_BASE, 102 .end = OMAP3430_ISP_PREV_END, 103 .flags = IORESOURCE_MEM, 104 }, 105 { 106 .start = OMAP3430_ISP_RESZ_BASE, 107 .end = OMAP3430_ISP_RESZ_END, 108 .flags = IORESOURCE_MEM, 109 }, 110 { 111 .start = OMAP3430_ISP_SBL_BASE, 112 .end = OMAP3430_ISP_SBL_END, 113 .flags = IORESOURCE_MEM, 114 }, 115 { 116 .start = OMAP3430_ISP_CSI2A_REGS1_BASE, 117 .end = OMAP3430_ISP_CSI2A_REGS1_END, 118 .flags = IORESOURCE_MEM, 119 }, 120 { 121 .start = OMAP3430_ISP_CSIPHY2_BASE, 122 .end = OMAP3430_ISP_CSIPHY2_END, 123 .flags = IORESOURCE_MEM, 124 }, 125 { 126 .start = OMAP3630_ISP_CSI2A_REGS2_BASE, 127 .end = OMAP3630_ISP_CSI2A_REGS2_END, 128 .flags = IORESOURCE_MEM, 129 }, 130 { 131 .start = OMAP3630_ISP_CSI2C_REGS1_BASE, 132 .end = OMAP3630_ISP_CSI2C_REGS1_END, 133 .flags = IORESOURCE_MEM, 134 }, 135 { 136 .start = OMAP3630_ISP_CSIPHY1_BASE, 137 .end = OMAP3630_ISP_CSIPHY1_END, 138 .flags = IORESOURCE_MEM, 139 }, 140 { 141 .start = OMAP3630_ISP_CSI2C_REGS2_BASE, 142 .end = OMAP3630_ISP_CSI2C_REGS2_END, 143 .flags = IORESOURCE_MEM, 144 }, 145 { 146 .start = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE, 147 .end = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE + 3, 148 .flags = IORESOURCE_MEM, 149 }, 150 { 151 .start = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL, 152 .end = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL + 3, 153 .flags = IORESOURCE_MEM, 154 }, 155 { 156 .start = 24 + OMAP_INTC_START, 157 .flags = IORESOURCE_IRQ, 158 } 159 }; 160 161 static struct platform_device omap3isp_device = { 162 .name = "omap3isp", 163 .id = -1, 164 .num_resources = ARRAY_SIZE(omap3isp_resources), 165 .resource = omap3isp_resources, 166 }; 167 168 static struct omap_iommu_arch_data omap3_isp_iommu = { 169 .name = "mmu_isp", 170 }; 171 172 int omap3_init_camera(struct isp_platform_data *pdata) 173 { 174 if (of_have_populated_dt()) 175 omap3_isp_iommu.name = "480bd400.mmu"; 176 177 omap3isp_device.dev.platform_data = pdata; 178 omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu; 179 180 return platform_device_register(&omap3isp_device); 181 } 182 183 #else /* !CONFIG_IOMMU_API */ 184 185 int omap3_init_camera(struct isp_platform_data *pdata) 186 { 187 return 0; 188 } 189 190 #endif 191 192 #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) 193 static inline void __init omap_init_mbox(void) 194 { 195 struct omap_hwmod *oh; 196 struct platform_device *pdev; 197 struct omap_mbox_pdata *pdata; 198 199 oh = omap_hwmod_lookup("mailbox"); 200 if (!oh) { 201 pr_err("%s: unable to find hwmod\n", __func__); 202 return; 203 } 204 if (!oh->dev_attr) { 205 pr_err("%s: hwmod doesn't have valid attrs\n", __func__); 206 return; 207 } 208 209 pdata = (struct omap_mbox_pdata *)oh->dev_attr; 210 pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata)); 211 WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", 212 __func__, PTR_ERR(pdev)); 213 } 214 #else 215 static inline void omap_init_mbox(void) { } 216 #endif /* CONFIG_OMAP2PLUS_MBOX */ 217 218 static inline void omap_init_sti(void) {} 219 220 #if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE) 221 222 static struct platform_device omap_pcm = { 223 .name = "omap-pcm-audio", 224 .id = -1, 225 }; 226 227 static void omap_init_audio(void) 228 { 229 platform_device_register(&omap_pcm); 230 } 231 232 #else 233 static inline void omap_init_audio(void) {} 234 #endif 235 236 #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) 237 238 #include <linux/platform_data/spi-omap2-mcspi.h> 239 240 static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) 241 { 242 struct platform_device *pdev; 243 char *name = "omap2_mcspi"; 244 struct omap2_mcspi_platform_config *pdata; 245 static int spi_num; 246 struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; 247 248 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); 249 if (!pdata) { 250 pr_err("Memory allocation for McSPI device failed\n"); 251 return -ENOMEM; 252 } 253 254 pdata->num_cs = mcspi_attrib->num_chipselect; 255 switch (oh->class->rev) { 256 case OMAP2_MCSPI_REV: 257 case OMAP3_MCSPI_REV: 258 pdata->regs_offset = 0; 259 break; 260 case OMAP4_MCSPI_REV: 261 pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; 262 break; 263 default: 264 pr_err("Invalid McSPI Revision value\n"); 265 kfree(pdata); 266 return -EINVAL; 267 } 268 269 spi_num++; 270 pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata)); 271 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", 272 name, oh->name); 273 kfree(pdata); 274 return 0; 275 } 276 277 static void omap_init_mcspi(void) 278 { 279 omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); 280 } 281 282 #else 283 static inline void omap_init_mcspi(void) {} 284 #endif 285 286 /** 287 * omap_init_rng - bind the RNG hwmod to the RNG omap_device 288 * 289 * Bind the RNG hwmod to the RNG omap_device. No return value. 290 */ 291 static void omap_init_rng(void) 292 { 293 struct omap_hwmod *oh; 294 struct platform_device *pdev; 295 296 oh = omap_hwmod_lookup("rng"); 297 if (!oh) 298 return; 299 300 pdev = omap_device_build("omap_rng", -1, oh, NULL, 0); 301 WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); 302 } 303 304 static void __init omap_init_sham(void) 305 { 306 struct omap_hwmod *oh; 307 struct platform_device *pdev; 308 309 oh = omap_hwmod_lookup("sham"); 310 if (!oh) 311 return; 312 313 pdev = omap_device_build("omap-sham", -1, oh, NULL, 0); 314 WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n"); 315 } 316 317 static void __init omap_init_aes(void) 318 { 319 struct omap_hwmod *oh; 320 struct platform_device *pdev; 321 322 oh = omap_hwmod_lookup("aes"); 323 if (!oh) 324 return; 325 326 pdev = omap_device_build("omap-aes", -1, oh, NULL, 0); 327 WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n"); 328 } 329 330 /*-------------------------------------------------------------------------*/ 331 332 #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ 333 defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) 334 #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) 335 static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = { 336 }; 337 #else 338 static struct resource omap_vout_resource[2] = { 339 }; 340 #endif 341 342 static struct platform_device omap_vout_device = { 343 .name = "omap_vout", 344 .num_resources = ARRAY_SIZE(omap_vout_resource), 345 .resource = &omap_vout_resource[0], 346 .id = -1, 347 }; 348 349 int __init omap_init_vout(void) 350 { 351 return platform_device_register(&omap_vout_device); 352 } 353 #else 354 int __init omap_init_vout(void) { return 0; } 355 #endif 356 357 /*-------------------------------------------------------------------------*/ 358 359 static int __init omap2_init_devices(void) 360 { 361 /* Enable dummy states for those platforms without pinctrl support */ 362 if (!of_have_populated_dt()) 363 pinctrl_provide_dummies(); 364 365 /* 366 * please keep these calls, and their implementations above, 367 * in alphabetical order so they're easier to sort through. 368 */ 369 omap_init_audio(); 370 /* If dtb is there, the devices will be created dynamically */ 371 if (!of_have_populated_dt()) { 372 omap_init_mbox(); 373 omap_init_mcspi(); 374 omap_init_sham(); 375 omap_init_aes(); 376 omap_init_rng(); 377 } 378 omap_init_sti(); 379 380 return 0; 381 } 382 omap_arch_initcall(omap2_init_devices); 383 384 static int __init omap_gpmc_init(void) 385 { 386 struct omap_hwmod *oh; 387 struct platform_device *pdev; 388 char *oh_name = "gpmc"; 389 390 /* 391 * if the board boots up with a populated DT, do not 392 * manually add the device from this initcall 393 */ 394 if (of_have_populated_dt()) 395 return -ENODEV; 396 397 oh = omap_hwmod_lookup(oh_name); 398 if (!oh) { 399 pr_err("Could not look up %s\n", oh_name); 400 return -ENODEV; 401 } 402 403 pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0); 404 WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); 405 406 return PTR_RET(pdev); 407 } 408 omap_postcore_initcall(omap_gpmc_init); 409