diff options
Diffstat (limited to 'arch/arm/mach-omap2/devices.c')
| -rw-r--r-- | arch/arm/mach-omap2/devices.c | 131 |
1 files changed, 115 insertions, 16 deletions
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index c5cf1ba08a6f..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,15 +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> |
| 28 | #include <plat/mcbsp.h> | 27 | #include <plat/mcbsp.h> |
| 29 | #include <mach/gpio.h> | 28 | #include <mach/gpio.h> |
| 30 | #include <plat/mmc.h> | 29 | #include <plat/mmc.h> |
| 31 | #include <plat/dma.h> | 30 | #include <plat/dma.h> |
| 31 | #include <plat/omap_hwmod.h> | ||
| 32 | #include <plat/omap_device.h> | ||
| 32 | 33 | ||
| 33 | #include "mux.h" | 34 | #include "mux.h" |
| 35 | #include "control.h" | ||
| 34 | 36 | ||
| 35 | #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) | 37 | #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) |
| 36 | 38 | ||
| @@ -538,7 +540,7 @@ static inline void omap_init_sham(void) { } | |||
| 538 | 540 | ||
| 539 | #if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE) | 541 | #if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE) |
| 540 | 542 | ||
| 541 | #ifdef CONFIG_ARCH_OMAP24XX | 543 | #ifdef CONFIG_ARCH_OMAP2 |
| 542 | static struct resource omap2_aes_resources[] = { | 544 | static struct resource omap2_aes_resources[] = { |
| 543 | { | 545 | { |
| 544 | .start = OMAP24XX_SEC_AES_BASE, | 546 | .start = OMAP24XX_SEC_AES_BASE, |
| @@ -560,7 +562,7 @@ static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources); | |||
| 560 | #define omap2_aes_resources_sz 0 | 562 | #define omap2_aes_resources_sz 0 |
| 561 | #endif | 563 | #endif |
| 562 | 564 | ||
| 563 | #ifdef CONFIG_ARCH_OMAP34XX | 565 | #ifdef CONFIG_ARCH_OMAP3 |
| 564 | static struct resource omap3_aes_resources[] = { | 566 | static struct resource omap3_aes_resources[] = { |
| 565 | { | 567 | { |
| 566 | .start = OMAP34XX_SEC_AES_BASE, | 568 | .start = OMAP34XX_SEC_AES_BASE, |
| @@ -732,7 +734,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
| 732 | omap_mux_init_signal("sdmmc_dat0", 0); | 734 | omap_mux_init_signal("sdmmc_dat0", 0); |
| 733 | omap_mux_init_signal("sdmmc_dat_dir0", 0); | 735 | omap_mux_init_signal("sdmmc_dat_dir0", 0); |
| 734 | omap_mux_init_signal("sdmmc_cmd_dir", 0); | 736 | omap_mux_init_signal("sdmmc_cmd_dir", 0); |
| 735 | if (mmc_controller->slots[0].wires == 4) { | 737 | if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { |
| 736 | omap_mux_init_signal("sdmmc_dat1", 0); | 738 | omap_mux_init_signal("sdmmc_dat1", 0); |
| 737 | omap_mux_init_signal("sdmmc_dat2", 0); | 739 | omap_mux_init_signal("sdmmc_dat2", 0); |
| 738 | omap_mux_init_signal("sdmmc_dat3", 0); | 740 | omap_mux_init_signal("sdmmc_dat3", 0); |
| @@ -760,8 +762,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
| 760 | OMAP_PIN_INPUT_PULLUP); | 762 | OMAP_PIN_INPUT_PULLUP); |
| 761 | omap_mux_init_signal("sdmmc1_dat0", | 763 | omap_mux_init_signal("sdmmc1_dat0", |
| 762 | OMAP_PIN_INPUT_PULLUP); | 764 | OMAP_PIN_INPUT_PULLUP); |
| 763 | if (mmc_controller->slots[0].wires == 4 || | 765 | if (mmc_controller->slots[0].caps & |
| 764 | mmc_controller->slots[0].wires == 8) { | 766 | (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { |
| 765 | omap_mux_init_signal("sdmmc1_dat1", | 767 | omap_mux_init_signal("sdmmc1_dat1", |
| 766 | OMAP_PIN_INPUT_PULLUP); | 768 | OMAP_PIN_INPUT_PULLUP); |
| 767 | omap_mux_init_signal("sdmmc1_dat2", | 769 | omap_mux_init_signal("sdmmc1_dat2", |
| @@ -769,7 +771,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
| 769 | omap_mux_init_signal("sdmmc1_dat3", | 771 | omap_mux_init_signal("sdmmc1_dat3", |
| 770 | OMAP_PIN_INPUT_PULLUP); | 772 | OMAP_PIN_INPUT_PULLUP); |
| 771 | } | 773 | } |
| 772 | if (mmc_controller->slots[0].wires == 8) { | 774 | if (mmc_controller->slots[0].caps & |
| 775 | MMC_CAP_8_BIT_DATA) { | ||
| 773 | omap_mux_init_signal("sdmmc1_dat4", | 776 | omap_mux_init_signal("sdmmc1_dat4", |
| 774 | OMAP_PIN_INPUT_PULLUP); | 777 | OMAP_PIN_INPUT_PULLUP); |
| 775 | omap_mux_init_signal("sdmmc1_dat5", | 778 | omap_mux_init_signal("sdmmc1_dat5", |
| @@ -793,8 +796,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
| 793 | * 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 |
| 794 | * in the board-*.c files | 797 | * in the board-*.c files |
| 795 | */ | 798 | */ |
| 796 | if (mmc_controller->slots[0].wires == 4 || | 799 | if (mmc_controller->slots[0].caps & |
| 797 | mmc_controller->slots[0].wires == 8) { | 800 | (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { |
| 798 | omap_mux_init_signal("sdmmc2_dat1", | 801 | omap_mux_init_signal("sdmmc2_dat1", |
| 799 | OMAP_PIN_INPUT_PULLUP); | 802 | OMAP_PIN_INPUT_PULLUP); |
| 800 | omap_mux_init_signal("sdmmc2_dat2", | 803 | omap_mux_init_signal("sdmmc2_dat2", |
| @@ -802,7 +805,8 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
| 802 | omap_mux_init_signal("sdmmc2_dat3", | 805 | omap_mux_init_signal("sdmmc2_dat3", |
| 803 | OMAP_PIN_INPUT_PULLUP); | 806 | OMAP_PIN_INPUT_PULLUP); |
| 804 | } | 807 | } |
| 805 | if (mmc_controller->slots[0].wires == 8) { | 808 | if (mmc_controller->slots[0].caps & |
| 809 | MMC_CAP_8_BIT_DATA) { | ||
| 806 | omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", | 810 | omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", |
| 807 | OMAP_PIN_INPUT_PULLUP); | 811 | OMAP_PIN_INPUT_PULLUP); |
| 808 | omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", | 812 | omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", |
| @@ -853,13 +857,13 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | |||
| 853 | case 3: | 857 | case 3: |
| 854 | if (!cpu_is_omap44xx()) | 858 | if (!cpu_is_omap44xx()) |
| 855 | return; | 859 | return; |
| 856 | base = OMAP4_MMC4_BASE + OMAP4_MMC_REG_OFFSET; | 860 | base = OMAP4_MMC4_BASE; |
| 857 | irq = OMAP44XX_IRQ_MMC4; | 861 | irq = OMAP44XX_IRQ_MMC4; |
| 858 | break; | 862 | break; |
| 859 | case 4: | 863 | case 4: |
| 860 | if (!cpu_is_omap44xx()) | 864 | if (!cpu_is_omap44xx()) |
| 861 | return; | 865 | return; |
| 862 | base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET; | 866 | base = OMAP4_MMC5_BASE; |
| 863 | irq = OMAP44XX_IRQ_MMC5; | 867 | irq = OMAP44XX_IRQ_MMC5; |
| 864 | break; | 868 | break; |
| 865 | default: | 869 | default: |
| @@ -870,10 +874,8 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | |||
| 870 | size = OMAP2420_MMC_SIZE; | 874 | size = OMAP2420_MMC_SIZE; |
| 871 | name = "mmci-omap"; | 875 | name = "mmci-omap"; |
| 872 | } else if (cpu_is_omap44xx()) { | 876 | } else if (cpu_is_omap44xx()) { |
| 873 | if (i < 3) { | 877 | if (i < 3) |
| 874 | base += OMAP4_MMC_REG_OFFSET; | ||
| 875 | irq += OMAP44XX_IRQ_GIC_START; | 878 | irq += OMAP44XX_IRQ_GIC_START; |
| 876 | } | ||
| 877 | size = OMAP4_HSMMC_SIZE; | 879 | size = OMAP4_HSMMC_SIZE; |
| 878 | name = "mmci-omap-hs"; | 880 | name = "mmci-omap-hs"; |
| 879 | } else { | 881 | } else { |
| @@ -949,11 +951,72 @@ static inline void omap_init_vout(void) {} | |||
| 949 | 951 | ||
| 950 | /*-------------------------------------------------------------------------*/ | 952 | /*-------------------------------------------------------------------------*/ |
| 951 | 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 | |||
| 952 | static int __init omap2_init_devices(void) | 1014 | static int __init omap2_init_devices(void) |
| 953 | { | 1015 | { |
| 954 | /* please keep these calls, and their implementations above, | 1016 | /* please keep these calls, and their implementations above, |
| 955 | * in alphabetical order so they're easier to sort through. | 1017 | * in alphabetical order so they're easier to sort through. |
| 956 | */ | 1018 | */ |
| 1019 | omap_disable_wdt(); | ||
| 957 | omap_hsmmc_reset(); | 1020 | omap_hsmmc_reset(); |
| 958 | omap_init_audio(); | 1021 | omap_init_audio(); |
| 959 | omap_init_camera(); | 1022 | omap_init_camera(); |
| @@ -969,3 +1032,39 @@ static int __init omap2_init_devices(void) | |||
| 969 | return 0; | 1032 | return 0; |
| 970 | } | 1033 | } |
| 971 | 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 | ||
