diff options
Diffstat (limited to 'arch/arm/mach-omap2/devices.c')
-rw-r--r-- | arch/arm/mach-omap2/devices.c | 187 |
1 files changed, 40 insertions, 147 deletions
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 8800486f946..9ee876fd367 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/slab.h> | ||
18 | 19 | ||
19 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
20 | #include <mach/irqs.h> | 21 | #include <mach/irqs.h> |
@@ -320,163 +321,55 @@ static inline void omap_init_audio(void) {} | |||
320 | 321 | ||
321 | #include <plat/mcspi.h> | 322 | #include <plat/mcspi.h> |
322 | 323 | ||
323 | #define OMAP2_MCSPI1_BASE 0x48098000 | 324 | struct omap_device_pm_latency omap_mcspi_latency[] = { |
324 | #define OMAP2_MCSPI2_BASE 0x4809a000 | 325 | [0] = { |
325 | #define OMAP2_MCSPI3_BASE 0x480b8000 | 326 | .deactivate_func = omap_device_idle_hwmods, |
326 | #define OMAP2_MCSPI4_BASE 0x480ba000 | 327 | .activate_func = omap_device_enable_hwmods, |
327 | 328 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | |
328 | #define OMAP4_MCSPI1_BASE 0x48098100 | ||
329 | #define OMAP4_MCSPI2_BASE 0x4809a100 | ||
330 | #define OMAP4_MCSPI3_BASE 0x480b8100 | ||
331 | #define OMAP4_MCSPI4_BASE 0x480ba100 | ||
332 | |||
333 | static struct omap2_mcspi_platform_config omap2_mcspi1_config = { | ||
334 | .num_cs = 4, | ||
335 | }; | ||
336 | |||
337 | static struct resource omap2_mcspi1_resources[] = { | ||
338 | { | ||
339 | .start = OMAP2_MCSPI1_BASE, | ||
340 | .end = OMAP2_MCSPI1_BASE + 0xff, | ||
341 | .flags = IORESOURCE_MEM, | ||
342 | }, | ||
343 | }; | ||
344 | |||
345 | static struct platform_device omap2_mcspi1 = { | ||
346 | .name = "omap2_mcspi", | ||
347 | .id = 1, | ||
348 | .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), | ||
349 | .resource = omap2_mcspi1_resources, | ||
350 | .dev = { | ||
351 | .platform_data = &omap2_mcspi1_config, | ||
352 | }, | ||
353 | }; | ||
354 | |||
355 | static struct omap2_mcspi_platform_config omap2_mcspi2_config = { | ||
356 | .num_cs = 2, | ||
357 | }; | ||
358 | |||
359 | static struct resource omap2_mcspi2_resources[] = { | ||
360 | { | ||
361 | .start = OMAP2_MCSPI2_BASE, | ||
362 | .end = OMAP2_MCSPI2_BASE + 0xff, | ||
363 | .flags = IORESOURCE_MEM, | ||
364 | }, | ||
365 | }; | ||
366 | |||
367 | static struct platform_device omap2_mcspi2 = { | ||
368 | .name = "omap2_mcspi", | ||
369 | .id = 2, | ||
370 | .num_resources = ARRAY_SIZE(omap2_mcspi2_resources), | ||
371 | .resource = omap2_mcspi2_resources, | ||
372 | .dev = { | ||
373 | .platform_data = &omap2_mcspi2_config, | ||
374 | }, | ||
375 | }; | ||
376 | |||
377 | #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ | ||
378 | defined(CONFIG_ARCH_OMAP4) | ||
379 | static struct omap2_mcspi_platform_config omap2_mcspi3_config = { | ||
380 | .num_cs = 2, | ||
381 | }; | ||
382 | |||
383 | static struct resource omap2_mcspi3_resources[] = { | ||
384 | { | ||
385 | .start = OMAP2_MCSPI3_BASE, | ||
386 | .end = OMAP2_MCSPI3_BASE + 0xff, | ||
387 | .flags = IORESOURCE_MEM, | ||
388 | }, | ||
389 | }; | ||
390 | |||
391 | static struct platform_device omap2_mcspi3 = { | ||
392 | .name = "omap2_mcspi", | ||
393 | .id = 3, | ||
394 | .num_resources = ARRAY_SIZE(omap2_mcspi3_resources), | ||
395 | .resource = omap2_mcspi3_resources, | ||
396 | .dev = { | ||
397 | .platform_data = &omap2_mcspi3_config, | ||
398 | }, | ||
399 | }; | ||
400 | #endif | ||
401 | |||
402 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) | ||
403 | static struct omap2_mcspi_platform_config omap2_mcspi4_config = { | ||
404 | .num_cs = 1, | ||
405 | }; | ||
406 | |||
407 | static struct resource omap2_mcspi4_resources[] = { | ||
408 | { | ||
409 | .start = OMAP2_MCSPI4_BASE, | ||
410 | .end = OMAP2_MCSPI4_BASE + 0xff, | ||
411 | .flags = IORESOURCE_MEM, | ||
412 | }, | ||
413 | }; | ||
414 | |||
415 | static struct platform_device omap2_mcspi4 = { | ||
416 | .name = "omap2_mcspi", | ||
417 | .id = 4, | ||
418 | .num_resources = ARRAY_SIZE(omap2_mcspi4_resources), | ||
419 | .resource = omap2_mcspi4_resources, | ||
420 | .dev = { | ||
421 | .platform_data = &omap2_mcspi4_config, | ||
422 | }, | 329 | }, |
423 | }; | 330 | }; |
424 | #endif | ||
425 | 331 | ||
426 | #ifdef CONFIG_ARCH_OMAP4 | 332 | static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) |
427 | static inline void omap4_mcspi_fixup(void) | ||
428 | { | 333 | { |
429 | omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE; | 334 | struct omap_device *od; |
430 | omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff; | 335 | char *name = "omap2_mcspi"; |
431 | omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE; | 336 | struct omap2_mcspi_platform_config *pdata; |
432 | omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff; | 337 | static int spi_num; |
433 | omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE; | 338 | struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; |
434 | omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff; | 339 | |
435 | omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE; | 340 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
436 | omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff; | 341 | if (!pdata) { |
437 | } | 342 | pr_err("Memory allocation for McSPI device failed\n"); |
438 | #else | 343 | return -ENOMEM; |
439 | static inline void omap4_mcspi_fixup(void) | 344 | } |
440 | { | ||
441 | } | ||
442 | #endif | ||
443 | 345 | ||
444 | #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ | 346 | pdata->num_cs = mcspi_attrib->num_chipselect; |
445 | defined(CONFIG_ARCH_OMAP4) | 347 | switch (oh->class->rev) { |
446 | static inline void omap2_mcspi3_init(void) | 348 | case OMAP2_MCSPI_REV: |
447 | { | 349 | case OMAP3_MCSPI_REV: |
448 | platform_device_register(&omap2_mcspi3); | 350 | pdata->regs_offset = 0; |
449 | } | 351 | break; |
450 | #else | 352 | case OMAP4_MCSPI_REV: |
451 | static inline void omap2_mcspi3_init(void) | 353 | pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; |
452 | { | 354 | break; |
453 | } | 355 | default: |
454 | #endif | 356 | pr_err("Invalid McSPI Revision value\n"); |
357 | return -EINVAL; | ||
358 | } | ||
455 | 359 | ||
456 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) | 360 | spi_num++; |
457 | static inline void omap2_mcspi4_init(void) | 361 | od = omap_device_build(name, spi_num, oh, pdata, |
458 | { | 362 | sizeof(*pdata), omap_mcspi_latency, |
459 | platform_device_register(&omap2_mcspi4); | 363 | ARRAY_SIZE(omap_mcspi_latency), 0); |
460 | } | 364 | WARN(IS_ERR(od), "Cant build omap_device for %s:%s\n", |
461 | #else | 365 | name, oh->name); |
462 | static inline void omap2_mcspi4_init(void) | 366 | kfree(pdata); |
463 | { | 367 | return 0; |
464 | } | 368 | } |
465 | #endif | ||
466 | 369 | ||
467 | static void omap_init_mcspi(void) | 370 | static void omap_init_mcspi(void) |
468 | { | 371 | { |
469 | if (cpu_is_omap44xx()) | 372 | omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); |
470 | omap4_mcspi_fixup(); | ||
471 | |||
472 | platform_device_register(&omap2_mcspi1); | ||
473 | platform_device_register(&omap2_mcspi2); | ||
474 | |||
475 | if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) | ||
476 | omap2_mcspi3_init(); | ||
477 | |||
478 | if (cpu_is_omap343x() || cpu_is_omap44xx()) | ||
479 | omap2_mcspi4_init(); | ||
480 | } | 373 | } |
481 | 374 | ||
482 | #else | 375 | #else |