devices.c 9.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 * 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.
 */
11
#include <linux/gpio.h>
12 13 14
#include <linux/kernel.h>
#include <linux/init.h>
#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 24 25

#include <asm/mach-types.h>
#include <asm/mach/map.h>

26
#include <linux/omap-dma.h>
27

28
#include "iomap.h"
29
#include "omap_hwmod.h"
30
#include "omap_device.h"
31

32 33
#include "soc.h"
#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 43 44

static int __init omap3_l3_init(void)
{
	struct omap_hwmod *oh;
45
	struct platform_device *pdev;
46 47 48 49 50 51
	char oh_name[L3_MODULES_MAX_LEN];

	/*
	 * To avoid code running on other OMAPs in
	 * multi-omap builds
	 */
52
	if (!(cpu_is_omap34xx()) || of_have_populated_dt())
53 54
		return -ENODEV;

55
	snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main");
56 57 58 59 60 61

	oh = omap_hwmod_lookup(oh_name);

	if (!oh)
		pr_err("could not look up %s\n", oh_name);

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
}
T
Tony Lindgren 已提交
68
omap_postcore_initcall(omap3_l3_init);
69

70
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
71

72
static struct resource omap2cam_resources[] = {
73
	{
74 75 76 77 78
		.start		= OMAP24XX_CAMERA_BASE,
		.end		= OMAP24XX_CAMERA_BASE + 0xfff,
		.flags		= IORESOURCE_MEM,
	},
	{
79
		.start		= 24 + OMAP_INTC_START,
80 81 82 83
		.flags		= IORESOURCE_IRQ,
	}
};

84
static struct platform_device omap2cam_device = {
85 86
	.name		= "omap24xxcam",
	.id		= -1,
87 88
	.num_resources	= ARRAY_SIZE(omap2cam_resources),
	.resource	= omap2cam_resources,
89
};
90
#endif
91

92 93
#if defined(CONFIG_IOMMU_API)

94
#include <linux/platform_data/iommu-omap.h>
95

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
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,
	},
	{
138 139
		.start		= OMAP3430_ISP_CSI2A_REGS1_BASE,
		.end		= OMAP3430_ISP_CSI2A_REGS1_END,
140 141 142
		.flags		= IORESOURCE_MEM,
	},
	{
143 144 145 146 147 148 149
		.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,
150 151 152
		.flags		= IORESOURCE_MEM,
	},
	{
153 154 155 156 157 158 159 160 161 162 163 164
		.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,
165 166
		.flags		= IORESOURCE_MEM,
	},
167 168 169 170 171 172 173 174 175 176
	{
		.start		= OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE,
		.end		= OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE + 3,
		.flags		= IORESOURCE_MEM,
	},
	{
		.start		= OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL,
		.end		= OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL + 3,
		.flags		= IORESOURCE_MEM,
	},
177
	{
178
		.start		= 24 + OMAP_INTC_START,
179 180 181 182 183 184 185 186 187 188 189
		.flags		= IORESOURCE_IRQ,
	}
};

static struct platform_device omap3isp_device = {
	.name		= "omap3isp",
	.id		= -1,
	.num_resources	= ARRAY_SIZE(omap3isp_resources),
	.resource	= omap3isp_resources,
};

190
static struct omap_iommu_arch_data omap3_isp_iommu = {
191
	.name = "mmu_isp",
192 193
};

194
int omap3_init_camera(struct isp_platform_data *pdata)
195
{
196 197 198
	if (of_have_populated_dt())
		omap3_isp_iommu.name = "480bd400.mmu";

199
	omap3isp_device.dev.platform_data = pdata;
200 201
	omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;

202
	return platform_device_register(&omap3isp_device);
203 204
}

205 206 207 208 209 210 211 212 213
#else /* !CONFIG_IOMMU_API */

int omap3_init_camera(struct isp_platform_data *pdata)
{
	return 0;
}

#endif

214 215
static inline void omap_init_camera(void)
{
216 217 218
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
	if (cpu_is_omap24xx())
		platform_device_register(&omap2cam_device);
219
#endif
220
}
221

222
#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
223
static inline void __init omap_init_mbox(void)
224
{
225
	struct omap_hwmod *oh;
226
	struct platform_device *pdev;
227
	struct omap_mbox_pdata *pdata;
228 229 230 231

	oh = omap_hwmod_lookup("mailbox");
	if (!oh) {
		pr_err("%s: unable to find hwmod\n", __func__);
232 233
		return;
	}
234 235 236 237
	if (!oh->dev_attr) {
		pr_err("%s: hwmod doesn't have valid attrs\n", __func__);
		return;
	}
238

239 240
	pdata = (struct omap_mbox_pdata *)oh->dev_attr;
	pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata));
241 242
	WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
						__func__, PTR_ERR(pdev));
243 244 245
}
#else
static inline void omap_init_mbox(void) { }
246
#endif /* CONFIG_OMAP2PLUS_MBOX */
247

248 249
static inline void omap_init_sti(void) {}

250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
#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

266
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
267

268
#include <linux/platform_data/spi-omap2-mcspi.h>
269

270
static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)
T
Tony Lindgren 已提交
271
{
272
	struct platform_device *pdev;
273 274 275 276 277 278 279 280 281 282
	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;
	}
T
Tony Lindgren 已提交
283

284 285 286 287 288 289 290 291 292 293 294
	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");
295
			kfree(pdata);
296 297
			return -EINVAL;
	}
T
Tony Lindgren 已提交
298

299
	spi_num++;
300
	pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata));
301
	WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",
302 303 304
				name, oh->name);
	kfree(pdata);
	return 0;
T
Tony Lindgren 已提交
305 306 307 308
}

static void omap_init_mcspi(void)
{
309
	omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL);
310 311 312 313 314 315
}

#else
static inline void omap_init_mcspi(void) {}
#endif

316 317 318 319 320 321 322 323 324 325 326 327 328 329
/**
 * 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;

330
	pdev = omap_device_build("omap_rng", -1, oh, NULL, 0);
331 332
	WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");
}
333

334
static void __init omap_init_sham(void)
335
{
336 337 338 339 340 341 342 343 344
	struct omap_hwmod *oh;
	struct platform_device *pdev;

	oh = omap_hwmod_lookup("sham");
	if (!oh)
		return;

	pdev = omap_device_build("omap-sham", -1, oh, NULL, 0);
	WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n");
345 346
}

347
static void __init omap_init_aes(void)
348
{
349 350 351 352 353 354 355 356 357
	struct omap_hwmod *oh;
	struct platform_device *pdev;

	oh = omap_hwmod_lookup("aes");
	if (!oh)
		return;

	pdev = omap_device_build("omap-aes", -1, oh, NULL, 0);
	WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n");
358 359
}

360 361
/*-------------------------------------------------------------------------*/

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
#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,
};
378 379

int __init omap_init_vout(void)
380
{
381
	return platform_device_register(&omap_vout_device);
382 383
}
#else
384
int __init omap_init_vout(void) { return 0; }
385 386
#endif

387 388 389 390
/*-------------------------------------------------------------------------*/

static int __init omap2_init_devices(void)
{
391 392 393 394
	/* Enable dummy states for those platforms without pinctrl support */
	if (!of_have_populated_dt())
		pinctrl_provide_dummies();

395 396
	/*
	 * please keep these calls, and their implementations above,
397 398
	 * in alphabetical order so they're easier to sort through.
	 */
399
	omap_init_audio();
400
	omap_init_camera();
401
	/* If dtb is there, the devices will be created dynamically */
402
	if (!of_have_populated_dt()) {
403
		omap_init_mbox();
404
		omap_init_mcspi();
405
		omap_init_sham();
406
		omap_init_aes();
407
		omap_init_rng();
408
	}
409
	omap_init_sti();
410 411 412

	return 0;
}
T
Tony Lindgren 已提交
413
omap_arch_initcall(omap2_init_devices);