diff options
Diffstat (limited to 'arch/arm/mach-omap2/devices.c')
-rw-r--r-- | arch/arm/mach-omap2/devices.c | 237 |
1 files changed, 223 insertions, 14 deletions
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 2dbb265bedd4..5a0c148e23bc 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -9,12 +9,12 @@ | |||
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
15 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
16 | #include <linux/io.h> | 15 | #include <linux/io.h> |
17 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/err.h> | ||
18 | 18 | ||
19 | #include <mach/hardware.h> | 19 | #include <mach/hardware.h> |
20 | #include <mach/irqs.h> | 20 | #include <mach/irqs.h> |
@@ -22,14 +22,17 @@ | |||
22 | #include <asm/mach/map.h> | 22 | #include <asm/mach/map.h> |
23 | #include <asm/pmu.h> | 23 | #include <asm/pmu.h> |
24 | 24 | ||
25 | #include <plat/control.h> | ||
26 | #include <plat/tc.h> | 25 | #include <plat/tc.h> |
27 | #include <plat/board.h> | 26 | #include <plat/board.h> |
27 | #include <plat/mcbsp.h> | ||
28 | #include <mach/gpio.h> | 28 | #include <mach/gpio.h> |
29 | #include <plat/mmc.h> | 29 | #include <plat/mmc.h> |
30 | #include <plat/dma.h> | 30 | #include <plat/dma.h> |
31 | #include <plat/omap_hwmod.h> | ||
32 | #include <plat/omap_device.h> | ||
31 | 33 | ||
32 | #include "mux.h" | 34 | #include "mux.h" |
35 | #include "control.h" | ||
33 | 36 | ||
34 | #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) | 37 | #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) |
35 | 38 | ||
@@ -235,6 +238,43 @@ static inline void omap_init_mbox(void) { } | |||
235 | 238 | ||
236 | static inline void omap_init_sti(void) {} | 239 | static inline void omap_init_sti(void) {} |
237 | 240 | ||
241 | #if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE) | ||
242 | |||
243 | static struct platform_device omap_pcm = { | ||
244 | .name = "omap-pcm-audio", | ||
245 | .id = -1, | ||
246 | }; | ||
247 | |||
248 | /* | ||
249 | * OMAP2420 has 2 McBSP ports | ||
250 | * OMAP2430 has 5 McBSP ports | ||
251 | * OMAP3 has 5 McBSP ports | ||
252 | * OMAP4 has 4 McBSP ports | ||
253 | */ | ||
254 | OMAP_MCBSP_PLATFORM_DEVICE(1); | ||
255 | OMAP_MCBSP_PLATFORM_DEVICE(2); | ||
256 | OMAP_MCBSP_PLATFORM_DEVICE(3); | ||
257 | OMAP_MCBSP_PLATFORM_DEVICE(4); | ||
258 | OMAP_MCBSP_PLATFORM_DEVICE(5); | ||
259 | |||
260 | static void omap_init_audio(void) | ||
261 | { | ||
262 | platform_device_register(&omap_mcbsp1); | ||
263 | platform_device_register(&omap_mcbsp2); | ||
264 | if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) { | ||
265 | platform_device_register(&omap_mcbsp3); | ||
266 | platform_device_register(&omap_mcbsp4); | ||
267 | } | ||
268 | if (cpu_is_omap243x() || cpu_is_omap34xx()) | ||
269 | platform_device_register(&omap_mcbsp5); | ||
270 | |||
271 | platform_device_register(&omap_pcm); | ||
272 | } | ||
273 | |||
274 | #else | ||
275 | static inline void omap_init_audio(void) {} | ||
276 | #endif | ||
277 | |||
238 | #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) | 278 | #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) |
239 | 279 | ||
240 | #include <plat/mcspi.h> | 280 | #include <plat/mcspi.h> |
@@ -498,6 +538,76 @@ static void omap_init_sham(void) | |||
498 | static inline void omap_init_sham(void) { } | 538 | static inline void omap_init_sham(void) { } |
499 | #endif | 539 | #endif |
500 | 540 | ||
541 | #if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE) | ||
542 | |||
543 | #ifdef CONFIG_ARCH_OMAP2 | ||
544 | static struct resource omap2_aes_resources[] = { | ||
545 | { | ||
546 | .start = OMAP24XX_SEC_AES_BASE, | ||
547 | .end = OMAP24XX_SEC_AES_BASE + 0x4C, | ||
548 | .flags = IORESOURCE_MEM, | ||
549 | }, | ||
550 | { | ||
551 | .start = OMAP24XX_DMA_AES_TX, | ||
552 | .flags = IORESOURCE_DMA, | ||
553 | }, | ||
554 | { | ||
555 | .start = OMAP24XX_DMA_AES_RX, | ||
556 | .flags = IORESOURCE_DMA, | ||
557 | } | ||
558 | }; | ||
559 | static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources); | ||
560 | #else | ||
561 | #define omap2_aes_resources NULL | ||
562 | #define omap2_aes_resources_sz 0 | ||
563 | #endif | ||
564 | |||
565 | #ifdef CONFIG_ARCH_OMAP3 | ||
566 | static struct resource omap3_aes_resources[] = { | ||
567 | { | ||
568 | .start = OMAP34XX_SEC_AES_BASE, | ||
569 | .end = OMAP34XX_SEC_AES_BASE + 0x4C, | ||
570 | .flags = IORESOURCE_MEM, | ||
571 | }, | ||
572 | { | ||
573 | .start = OMAP34XX_DMA_AES2_TX, | ||
574 | .flags = IORESOURCE_DMA, | ||
575 | }, | ||
576 | { | ||
577 | .start = OMAP34XX_DMA_AES2_RX, | ||
578 | .flags = IORESOURCE_DMA, | ||
579 | } | ||
580 | }; | ||
581 | static int omap3_aes_resources_sz = ARRAY_SIZE(omap3_aes_resources); | ||
582 | #else | ||
583 | #define omap3_aes_resources NULL | ||
584 | #define omap3_aes_resources_sz 0 | ||
585 | #endif | ||
586 | |||
587 | static struct platform_device aes_device = { | ||
588 | .name = "omap-aes", | ||
589 | .id = -1, | ||
590 | }; | ||
591 | |||
592 | static void omap_init_aes(void) | ||
593 | { | ||
594 | if (cpu_is_omap24xx()) { | ||
595 | aes_device.resource = omap2_aes_resources; | ||
596 | aes_device.num_resources = omap2_aes_resources_sz; | ||
597 | } else if (cpu_is_omap34xx()) { | ||
598 | aes_device.resource = omap3_aes_resources; | ||
599 | aes_device.num_resources = omap3_aes_resources_sz; | ||
600 | } else { | ||
601 | pr_err("%s: platform not supported\n", __func__); | ||
602 | return; | ||
603 | } | ||
604 | platform_device_register(&aes_device); | ||
605 | } | ||
606 | |||
607 | #else | ||
608 | static inline void omap_init_aes(void) { } | ||
609 | #endif | ||
610 | |||
501 | /*-------------------------------------------------------------------------*/ | 611 | /*-------------------------------------------------------------------------*/ |
502 | 612 | ||
503 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) | 613 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) |
@@ -624,7 +734,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
624 | omap_mux_init_signal("sdmmc_dat0", 0); | 734 | omap_mux_init_signal("sdmmc_dat0", 0); |
625 | omap_mux_init_signal("sdmmc_dat_dir0", 0); | 735 | omap_mux_init_signal("sdmmc_dat_dir0", 0); |
626 | omap_mux_init_signal("sdmmc_cmd_dir", 0); | 736 | omap_mux_init_signal("sdmmc_cmd_dir", 0); |
627 | if (mmc_controller->slots[0].wires == 4) { | 737 | if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { |
628 | omap_mux_init_signal("sdmmc_dat1", 0); | 738 | omap_mux_init_signal("sdmmc_dat1", 0); |
629 | omap_mux_init_signal("sdmmc_dat2", 0); | 739 | omap_mux_init_signal("sdmmc_dat2", 0); |
630 | omap_mux_init_signal("sdmmc_dat3", 0); | 740 | omap_mux_init_signal("sdmmc_dat3", 0); |
@@ -652,8 +762,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
652 | OMAP_PIN_INPUT_PULLUP); | 762 | OMAP_PIN_INPUT_PULLUP); |
653 | omap_mux_init_signal("sdmmc1_dat0", | 763 | omap_mux_init_signal("sdmmc1_dat0", |
654 | OMAP_PIN_INPUT_PULLUP); | 764 | OMAP_PIN_INPUT_PULLUP); |
655 | if (mmc_controller->slots[0].wires == 4 || | 765 | if (mmc_controller->slots[0].caps & |
656 | mmc_controller->slots[0].wires == 8) { | 766 | (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { |
657 | omap_mux_init_signal("sdmmc1_dat1", | 767 | omap_mux_init_signal("sdmmc1_dat1", |
658 | OMAP_PIN_INPUT_PULLUP); | 768 | OMAP_PIN_INPUT_PULLUP); |
659 | omap_mux_init_signal("sdmmc1_dat2", | 769 | omap_mux_init_signal("sdmmc1_dat2", |
@@ -661,7 +771,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
661 | omap_mux_init_signal("sdmmc1_dat3", | 771 | omap_mux_init_signal("sdmmc1_dat3", |
662 | OMAP_PIN_INPUT_PULLUP); | 772 | OMAP_PIN_INPUT_PULLUP); |
663 | } | 773 | } |
664 | if (mmc_controller->slots[0].wires == 8) { | 774 | if (mmc_controller->slots[0].caps & |
775 | MMC_CAP_8_BIT_DATA) { | ||
665 | omap_mux_init_signal("sdmmc1_dat4", | 776 | omap_mux_init_signal("sdmmc1_dat4", |
666 | OMAP_PIN_INPUT_PULLUP); | 777 | OMAP_PIN_INPUT_PULLUP); |
667 | omap_mux_init_signal("sdmmc1_dat5", | 778 | omap_mux_init_signal("sdmmc1_dat5", |
@@ -685,8 +796,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
685 | * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed | 796 | * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed |
686 | * in the board-*.c files | 797 | * in the board-*.c files |
687 | */ | 798 | */ |
688 | if (mmc_controller->slots[0].wires == 4 || | 799 | if (mmc_controller->slots[0].caps & |
689 | mmc_controller->slots[0].wires == 8) { | 800 | (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { |
690 | omap_mux_init_signal("sdmmc2_dat1", | 801 | omap_mux_init_signal("sdmmc2_dat1", |
691 | OMAP_PIN_INPUT_PULLUP); | 802 | OMAP_PIN_INPUT_PULLUP); |
692 | omap_mux_init_signal("sdmmc2_dat2", | 803 | omap_mux_init_signal("sdmmc2_dat2", |
@@ -694,7 +805,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
694 | omap_mux_init_signal("sdmmc2_dat3", | 805 | omap_mux_init_signal("sdmmc2_dat3", |
695 | OMAP_PIN_INPUT_PULLUP); | 806 | OMAP_PIN_INPUT_PULLUP); |
696 | } | 807 | } |
697 | if (mmc_controller->slots[0].wires == 8) { | 808 | if (mmc_controller->slots[0].caps & |
809 | MMC_CAP_8_BIT_DATA) { | ||
698 | omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", | 810 | omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", |
699 | OMAP_PIN_INPUT_PULLUP); | 811 | OMAP_PIN_INPUT_PULLUP); |
700 | omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", | 812 | omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", |
@@ -745,13 +857,13 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | |||
745 | case 3: | 857 | case 3: |
746 | if (!cpu_is_omap44xx()) | 858 | if (!cpu_is_omap44xx()) |
747 | return; | 859 | return; |
748 | base = OMAP4_MMC4_BASE + OMAP4_MMC_REG_OFFSET; | 860 | base = OMAP4_MMC4_BASE; |
749 | irq = OMAP44XX_IRQ_MMC4; | 861 | irq = OMAP44XX_IRQ_MMC4; |
750 | break; | 862 | break; |
751 | case 4: | 863 | case 4: |
752 | if (!cpu_is_omap44xx()) | 864 | if (!cpu_is_omap44xx()) |
753 | return; | 865 | return; |
754 | base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET; | 866 | base = OMAP4_MMC5_BASE; |
755 | irq = OMAP44XX_IRQ_MMC5; | 867 | irq = OMAP44XX_IRQ_MMC5; |
756 | break; | 868 | break; |
757 | default: | 869 | default: |
@@ -762,10 +874,8 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | |||
762 | size = OMAP2420_MMC_SIZE; | 874 | size = OMAP2420_MMC_SIZE; |
763 | name = "mmci-omap"; | 875 | name = "mmci-omap"; |
764 | } else if (cpu_is_omap44xx()) { | 876 | } else if (cpu_is_omap44xx()) { |
765 | if (i < 3) { | 877 | if (i < 3) |
766 | base += OMAP4_MMC_REG_OFFSET; | ||
767 | irq += OMAP44XX_IRQ_GIC_START; | 878 | irq += OMAP44XX_IRQ_GIC_START; |
768 | } | ||
769 | size = OMAP4_HSMMC_SIZE; | 879 | size = OMAP4_HSMMC_SIZE; |
770 | name = "mmci-omap-hs"; | 880 | name = "mmci-omap-hs"; |
771 | } else { | 881 | } else { |
@@ -841,12 +951,74 @@ static inline void omap_init_vout(void) {} | |||
841 | 951 | ||
842 | /*-------------------------------------------------------------------------*/ | 952 | /*-------------------------------------------------------------------------*/ |
843 | 953 | ||
954 | /* | ||
955 | * Inorder to avoid any assumptions from bootloader regarding WDT | ||
956 | * settings, WDT module is reset during init. This enables the watchdog | ||
957 | * timer. Hence it is required to disable the watchdog after the WDT reset | ||
958 | * during init. Otherwise the system would reboot as per the default | ||
959 | * watchdog timer registers settings. | ||
960 | */ | ||
961 | #define OMAP_WDT_WPS (0x34) | ||
962 | #define OMAP_WDT_SPR (0x48) | ||
963 | |||
964 | static int omap2_disable_wdt(struct omap_hwmod *oh, void *unused) | ||
965 | { | ||
966 | void __iomem *base; | ||
967 | int ret; | ||
968 | |||
969 | if (!oh) { | ||
970 | pr_err("%s: Could not look up wdtimer_hwmod\n", __func__); | ||
971 | return -EINVAL; | ||
972 | } | ||
973 | |||
974 | base = omap_hwmod_get_mpu_rt_va(oh); | ||
975 | if (!base) { | ||
976 | pr_err("%s: Could not get the base address for %s\n", | ||
977 | oh->name, __func__); | ||
978 | return -EINVAL; | ||
979 | } | ||
980 | |||
981 | /* Enable the clocks before accessing the WDT registers */ | ||
982 | ret = omap_hwmod_enable(oh); | ||
983 | if (ret) { | ||
984 | pr_err("%s: Could not enable clocks for %s\n", | ||
985 | oh->name, __func__); | ||
986 | return ret; | ||
987 | } | ||
988 | |||
989 | /* sequence required to disable watchdog */ | ||
990 | __raw_writel(0xAAAA, base + OMAP_WDT_SPR); | ||
991 | while (__raw_readl(base + OMAP_WDT_WPS) & 0x10) | ||
992 | cpu_relax(); | ||
993 | |||
994 | __raw_writel(0x5555, base + OMAP_WDT_SPR); | ||
995 | while (__raw_readl(base + OMAP_WDT_WPS) & 0x10) | ||
996 | cpu_relax(); | ||
997 | |||
998 | ret = omap_hwmod_idle(oh); | ||
999 | if (ret) | ||
1000 | pr_err("%s: Could not disable clocks for %s\n", | ||
1001 | oh->name, __func__); | ||
1002 | |||
1003 | return ret; | ||
1004 | } | ||
1005 | |||
1006 | static void __init omap_disable_wdt(void) | ||
1007 | { | ||
1008 | if (cpu_class_is_omap2()) | ||
1009 | omap_hwmod_for_each_by_class("wd_timer", | ||
1010 | omap2_disable_wdt, NULL); | ||
1011 | return; | ||
1012 | } | ||
1013 | |||
844 | static int __init omap2_init_devices(void) | 1014 | static int __init omap2_init_devices(void) |
845 | { | 1015 | { |
846 | /* please keep these calls, and their implementations above, | 1016 | /* please keep these calls, and their implementations above, |
847 | * in alphabetical order so they're easier to sort through. | 1017 | * in alphabetical order so they're easier to sort through. |
848 | */ | 1018 | */ |
1019 | omap_disable_wdt(); | ||
849 | omap_hsmmc_reset(); | 1020 | omap_hsmmc_reset(); |
1021 | omap_init_audio(); | ||
850 | omap_init_camera(); | 1022 | omap_init_camera(); |
851 | omap_init_mbox(); | 1023 | omap_init_mbox(); |
852 | omap_init_mcspi(); | 1024 | omap_init_mcspi(); |
@@ -854,8 +1026,45 @@ static int __init omap2_init_devices(void) | |||
854 | omap_hdq_init(); | 1026 | omap_hdq_init(); |
855 | omap_init_sti(); | 1027 | omap_init_sti(); |
856 | omap_init_sham(); | 1028 | omap_init_sham(); |
1029 | omap_init_aes(); | ||
857 | omap_init_vout(); | 1030 | omap_init_vout(); |
858 | 1031 | ||
859 | return 0; | 1032 | return 0; |
860 | } | 1033 | } |
861 | arch_initcall(omap2_init_devices); | 1034 | arch_initcall(omap2_init_devices); |
1035 | |||
1036 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) | ||
1037 | struct omap_device_pm_latency omap_wdt_latency[] = { | ||
1038 | [0] = { | ||
1039 | .deactivate_func = omap_device_idle_hwmods, | ||
1040 | .activate_func = omap_device_enable_hwmods, | ||
1041 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
1042 | }, | ||
1043 | }; | ||
1044 | |||
1045 | static int __init omap_init_wdt(void) | ||
1046 | { | ||
1047 | int id = -1; | ||
1048 | struct omap_device *od; | ||
1049 | struct omap_hwmod *oh; | ||
1050 | char *oh_name = "wd_timer2"; | ||
1051 | char *dev_name = "omap_wdt"; | ||
1052 | |||
1053 | if (!cpu_class_is_omap2()) | ||
1054 | return 0; | ||
1055 | |||
1056 | oh = omap_hwmod_lookup(oh_name); | ||
1057 | if (!oh) { | ||
1058 | pr_err("Could not look up wd_timer%d hwmod\n", id); | ||
1059 | return -EINVAL; | ||
1060 | } | ||
1061 | |||
1062 | od = omap_device_build(dev_name, id, oh, NULL, 0, | ||
1063 | omap_wdt_latency, | ||
1064 | ARRAY_SIZE(omap_wdt_latency), 0); | ||
1065 | WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n", | ||
1066 | dev_name, oh->name); | ||
1067 | return 0; | ||
1068 | } | ||
1069 | subsys_initcall(omap_init_wdt); | ||
1070 | #endif | ||