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 41 static 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 } 67 omap_postcore_initcall(omap3_l3_init); 68 69 #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) 70 static 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 92 static inline void omap_init_mbox(void) { } 93 #endif /* CONFIG_OMAP2PLUS_MBOX */ 94 95 static inline void omap_init_sti(void) {} 96 97 #if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE) 98 99 static struct platform_device omap_pcm = { 100 .name = "omap-pcm-audio", 101 .id = -1, 102 }; 103 104 static void omap_init_audio(void) 105 { 106 platform_device_register(&omap_pcm); 107 } 108 109 #else 110 static 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 117 static 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 154 static void omap_init_mcspi(void) 155 { 156 omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); 157 } 158 159 #else 160 static 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 */ 168 static 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 181 static 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 194 static 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) 212 static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = { 213 }; 214 #else 215 static struct resource omap_vout_resource[2] = { 216 }; 217 #endif 218 219 static 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 226 int __init omap_init_vout(void) 227 { 228 return platform_device_register(&omap_vout_device); 229 } 230 #else 231 int __init omap_init_vout(void) { return 0; } 232 #endif 233 234 /*-------------------------------------------------------------------------*/ 235 236 static 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 } 259 omap_arch_initcall(omap2_init_devices); 260 261 static 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 } 285 omap_postcore_initcall(omap_gpmc_init); 286