diff options
70 files changed, 1175 insertions, 447 deletions
| diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig index eb2cb31825c0..f238df66efd4 100644 --- a/arch/arm/configs/rx51_defconfig +++ b/arch/arm/configs/rx51_defconfig | |||
| @@ -282,7 +282,7 @@ CONFIG_ALIGNMENT_TRAP=y | |||
| 282 | # | 282 | # | 
| 283 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 283 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 
| 284 | CONFIG_ZBOOT_ROM_BSS=0x0 | 284 | CONFIG_ZBOOT_ROM_BSS=0x0 | 
| 285 | CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs rootflags=bulk_read,no_chk_data_crc rw console=ttyMTD,log console=tty0" | 285 | CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs rootflags=bulk_read,no_chk_data_crc rw console=ttyMTD,log console=tty0 console=ttyS2,115200n8" | 
| 286 | # CONFIG_XIP_KERNEL is not set | 286 | # CONFIG_XIP_KERNEL is not set | 
| 287 | # CONFIG_KEXEC is not set | 287 | # CONFIG_KEXEC is not set | 
| 288 | 288 | ||
| @@ -1354,7 +1354,7 @@ CONFIG_USB_OTG_UTILS=y | |||
| 1354 | # CONFIG_USB_GPIO_VBUS is not set | 1354 | # CONFIG_USB_GPIO_VBUS is not set | 
| 1355 | # CONFIG_ISP1301_OMAP is not set | 1355 | # CONFIG_ISP1301_OMAP is not set | 
| 1356 | CONFIG_TWL4030_USB=y | 1356 | CONFIG_TWL4030_USB=y | 
| 1357 | CONFIG_MMC=m | 1357 | CONFIG_MMC=y | 
| 1358 | # CONFIG_MMC_DEBUG is not set | 1358 | # CONFIG_MMC_DEBUG is not set | 
| 1359 | # CONFIG_MMC_UNSAFE_RESUME is not set | 1359 | # CONFIG_MMC_UNSAFE_RESUME is not set | 
| 1360 | 1360 | ||
| @@ -1449,7 +1449,8 @@ CONFIG_RTC_DRV_TWL4030=m | |||
| 1449 | # on-CPU RTC drivers | 1449 | # on-CPU RTC drivers | 
| 1450 | # | 1450 | # | 
| 1451 | # CONFIG_DMADEVICES is not set | 1451 | # CONFIG_DMADEVICES is not set | 
| 1452 | # CONFIG_REGULATOR is not set | 1452 | CONFIG_REGULATOR=y | 
| 1453 | CONFIG_REGULATOR_TWL4030=y | ||
| 1453 | # CONFIG_UIO is not set | 1454 | # CONFIG_UIO is not set | 
| 1454 | # CONFIG_STAGING is not set | 1455 | # CONFIG_STAGING is not set | 
| 1455 | 1456 | ||
| diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index ee1304f22f94..5ccce0a9b03c 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h | |||
| @@ -201,7 +201,8 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn } | |||
| 201 | struct membank { | 201 | struct membank { | 
| 202 | unsigned long start; | 202 | unsigned long start; | 
| 203 | unsigned long size; | 203 | unsigned long size; | 
| 204 | int node; | 204 | unsigned short node; | 
| 205 | unsigned short highmem; | ||
| 205 | }; | 206 | }; | 
| 206 | 207 | ||
| 207 | struct meminfo { | 208 | struct meminfo { | 
| diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h index ce63048d45eb..8a947d42a6f1 100644 --- a/arch/arm/mach-ixp4xx/include/mach/io.h +++ b/arch/arm/mach-ixp4xx/include/mach/io.h | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | #include <mach/hardware.h> | 18 | #include <mach/hardware.h> | 
| 19 | 19 | ||
| 20 | #define IO_SPACE_LIMIT 0xffff0000 | 20 | #define IO_SPACE_LIMIT 0x0000ffff | 
| 21 | 21 | ||
| 22 | extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data); | 22 | extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data); | 
| 23 | extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data); | 23 | extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data); | 
| diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c index 4704405165a1..b48581e7dedd 100644 --- a/arch/arm/mach-mx3/mx31moboard-devboard.c +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c | |||
| @@ -63,7 +63,7 @@ static struct imxuart_platform_data uart_pdata = { | |||
| 63 | 63 | ||
| 64 | static int devboard_sdhc2_get_ro(struct device *dev) | 64 | static int devboard_sdhc2_get_ro(struct device *dev) | 
| 65 | { | 65 | { | 
| 66 | return gpio_get_value(SDHC2_WP); | 66 | return !gpio_get_value(SDHC2_WP); | 
| 67 | } | 67 | } | 
| 68 | 68 | ||
| 69 | static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq, | 69 | static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq, | 
| diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 641c3d6153ae..901fb0166c0e 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c | |||
| @@ -67,7 +67,7 @@ static unsigned int marxbot_pins[] = { | |||
| 67 | 67 | ||
| 68 | static int marxbot_sdhc2_get_ro(struct device *dev) | 68 | static int marxbot_sdhc2_get_ro(struct device *dev) | 
| 69 | { | 69 | { | 
| 70 | return gpio_get_value(SDHC2_WP); | 70 | return !gpio_get_value(SDHC2_WP); | 
| 71 | } | 71 | } | 
| 72 | 72 | ||
| 73 | static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq, | 73 | static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq, | 
| diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index a17f2e411609..2a2da4739ecf 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c | |||
| @@ -94,7 +94,7 @@ static struct imxi2c_platform_data moboard_i2c1_pdata = { | |||
| 94 | 94 | ||
| 95 | static int moboard_sdhc1_get_ro(struct device *dev) | 95 | static int moboard_sdhc1_get_ro(struct device *dev) | 
| 96 | { | 96 | { | 
| 97 | return gpio_get_value(SDHC1_WP); | 97 | return !gpio_get_value(SDHC1_WP); | 
| 98 | } | 98 | } | 
| 99 | 99 | ||
| 100 | static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq, | 100 | static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq, | 
| diff --git a/arch/arm/mach-mx3/pcm037_eet.c b/arch/arm/mach-mx3/pcm037_eet.c index fe52fb1bb8b7..8d386000fc40 100644 --- a/arch/arm/mach-mx3/pcm037_eet.c +++ b/arch/arm/mach-mx3/pcm037_eet.c | |||
| @@ -24,15 +24,6 @@ | |||
| 24 | #include "devices.h" | 24 | #include "devices.h" | 
| 25 | 25 | ||
| 26 | static unsigned int pcm037_eet_pins[] = { | 26 | static unsigned int pcm037_eet_pins[] = { | 
| 27 | /* SPI #1 */ | ||
| 28 | MX31_PIN_CSPI1_MISO__MISO, | ||
| 29 | MX31_PIN_CSPI1_MOSI__MOSI, | ||
| 30 | MX31_PIN_CSPI1_SCLK__SCLK, | ||
| 31 | MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, | ||
| 32 | MX31_PIN_CSPI1_SS0__SS0, | ||
| 33 | MX31_PIN_CSPI1_SS1__SS1, | ||
| 34 | MX31_PIN_CSPI1_SS2__SS2, | ||
| 35 | |||
| 36 | /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */ | 27 | /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */ | 
| 37 | IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO), | 28 | IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO), | 
| 38 | /* GPIO keys */ | 29 | /* GPIO keys */ | 
| diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 9c3fdcdf76c3..8ec2a132904d 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c | |||
| @@ -141,7 +141,7 @@ static inline void board_smc91x_init(void) | |||
| 141 | 141 | ||
| 142 | static void __init omap_2430sdp_init_irq(void) | 142 | static void __init omap_2430sdp_init_irq(void) | 
| 143 | { | 143 | { | 
| 144 | omap2_init_common_hw(NULL); | 144 | omap2_init_common_hw(NULL, NULL); | 
| 145 | omap_init_irq(); | 145 | omap_init_irq(); | 
| 146 | omap_gpio_init(); | 146 | omap_gpio_init(); | 
| 147 | } | 147 | } | 
| diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 496a90e4ea7a..ac262cd74503 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
| @@ -169,7 +169,7 @@ static struct platform_device *sdp3430_devices[] __initdata = { | |||
| 169 | 169 | ||
| 170 | static void __init omap_3430sdp_init_irq(void) | 170 | static void __init omap_3430sdp_init_irq(void) | 
| 171 | { | 171 | { | 
| 172 | omap2_init_common_hw(hyb18m512160af6_sdrc_params); | 172 | omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); | 
| 173 | omap_init_irq(); | 173 | omap_init_irq(); | 
| 174 | omap_gpio_init(); | 174 | omap_gpio_init(); | 
| 175 | } | 175 | } | 
| diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 57e477bd89c6..b0c7402248f7 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
| @@ -59,7 +59,7 @@ static void __init gic_init_irq(void) | |||
| 59 | 59 | ||
| 60 | static void __init omap_4430sdp_init_irq(void) | 60 | static void __init omap_4430sdp_init_irq(void) | 
| 61 | { | 61 | { | 
| 62 | omap2_init_common_hw(NULL); | 62 | omap2_init_common_hw(NULL, NULL); | 
| 63 | #ifdef CONFIG_OMAP_32K_TIMER | 63 | #ifdef CONFIG_OMAP_32K_TIMER | 
| 64 | omap2_gp_clockevent_set_gptimer(1); | 64 | omap2_gp_clockevent_set_gptimer(1); | 
| 65 | #endif | 65 | #endif | 
| diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 06dfba888b0c..dcfc20d03894 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c | |||
| @@ -250,7 +250,7 @@ out: | |||
| 250 | 250 | ||
| 251 | static void __init omap_apollon_init_irq(void) | 251 | static void __init omap_apollon_init_irq(void) | 
| 252 | { | 252 | { | 
| 253 | omap2_init_common_hw(NULL); | 253 | omap2_init_common_hw(NULL, NULL); | 
| 254 | omap_init_irq(); | 254 | omap_init_irq(); | 
| 255 | omap_gpio_init(); | 255 | omap_gpio_init(); | 
| 256 | apollon_init_smc91x(); | 256 | apollon_init_smc91x(); | 
| diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 3492162a65c3..fd00aa03690c 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | static void __init omap_generic_init_irq(void) | 34 | static void __init omap_generic_init_irq(void) | 
| 35 | { | 35 | { | 
| 36 | omap2_init_common_hw(NULL); | 36 | omap2_init_common_hw(NULL, NULL); | 
| 37 | omap_init_irq(); | 37 | omap_init_irq(); | 
| 38 | } | 38 | } | 
| 39 | 39 | ||
| diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index e7d017cdc438..7b1d61d5bb2c 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
| @@ -270,7 +270,7 @@ static void __init h4_init_flash(void) | |||
| 270 | 270 | ||
| 271 | static void __init omap_h4_init_irq(void) | 271 | static void __init omap_h4_init_irq(void) | 
| 272 | { | 272 | { | 
| 273 | omap2_init_common_hw(NULL); | 273 | omap2_init_common_hw(NULL, NULL); | 
| 274 | omap_init_irq(); | 274 | omap_init_irq(); | 
| 275 | omap_gpio_init(); | 275 | omap_gpio_init(); | 
| 276 | h4_init_flash(); | 276 | h4_init_flash(); | 
| diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index d8bc0a7dcb8d..ea383f88cb1b 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c | |||
| @@ -270,7 +270,7 @@ static inline void __init ldp_init_smsc911x(void) | |||
| 270 | 270 | ||
| 271 | static void __init omap_ldp_init_irq(void) | 271 | static void __init omap_ldp_init_irq(void) | 
| 272 | { | 272 | { | 
| 273 | omap2_init_common_hw(NULL); | 273 | omap2_init_common_hw(NULL, NULL); | 
| 274 | omap_init_irq(); | 274 | omap_init_irq(); | 
| 275 | omap_gpio_init(); | 275 | omap_gpio_init(); | 
| 276 | ldp_init_smsc911x(); | 276 | ldp_init_smsc911x(); | 
| diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 991ac9c38032..e00ba128cece 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
| @@ -282,7 +282,8 @@ static int __init omap3_beagle_i2c_init(void) | |||
| 282 | 282 | ||
| 283 | static void __init omap3_beagle_init_irq(void) | 283 | static void __init omap3_beagle_init_irq(void) | 
| 284 | { | 284 | { | 
| 285 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params); | 285 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | 
| 286 | mt46h32m32lf6_sdrc_params); | ||
| 286 | omap_init_irq(); | 287 | omap_init_irq(); | 
| 287 | #ifdef CONFIG_OMAP_32K_TIMER | 288 | #ifdef CONFIG_OMAP_32K_TIMER | 
| 288 | omap2_gp_clockevent_set_gptimer(12); | 289 | omap2_gp_clockevent_set_gptimer(12); | 
| @@ -408,6 +409,10 @@ static void __init omap3_beagle_init(void) | |||
| 408 | 409 | ||
| 409 | usb_musb_init(); | 410 | usb_musb_init(); | 
| 410 | omap3beagle_flash_init(); | 411 | omap3beagle_flash_init(); | 
| 412 | |||
| 413 | /* Ensure SDRC pins are mux'd for self-refresh */ | ||
| 414 | omap_cfg_reg(H16_34XX_SDRC_CKE0); | ||
| 415 | omap_cfg_reg(H17_34XX_SDRC_CKE1); | ||
| 411 | } | 416 | } | 
| 412 | 417 | ||
| 413 | static void __init omap3_beagle_map_io(void) | 418 | static void __init omap3_beagle_map_io(void) | 
| diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index cf3dd771a678..c4b144647dc5 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
| @@ -280,7 +280,7 @@ struct spi_board_info omap3evm_spi_board_info[] = { | |||
| 280 | 280 | ||
| 281 | static void __init omap3_evm_init_irq(void) | 281 | static void __init omap3_evm_init_irq(void) | 
| 282 | { | 282 | { | 
| 283 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params); | 283 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL); | 
| 284 | omap_init_irq(); | 284 | omap_init_irq(); | 
| 285 | omap_gpio_init(); | 285 | omap_gpio_init(); | 
| 286 | omap3evm_init_smc911x(); | 286 | omap3evm_init_smc911x(); | 
| diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index e32aa23ce962..864ee3d021f7 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <mach/mcspi.h> | 40 | #include <mach/mcspi.h> | 
| 41 | #include <mach/usb.h> | 41 | #include <mach/usb.h> | 
| 42 | #include <mach/keypad.h> | 42 | #include <mach/keypad.h> | 
| 43 | #include <mach/mux.h> | ||
| 43 | 44 | ||
| 44 | #include "sdram-micron-mt46h32m32lf-6.h" | 45 | #include "sdram-micron-mt46h32m32lf-6.h" | 
| 45 | #include "mmc-twl4030.h" | 46 | #include "mmc-twl4030.h" | 
| @@ -310,7 +311,8 @@ static int __init omap3pandora_i2c_init(void) | |||
| 310 | 311 | ||
| 311 | static void __init omap3pandora_init_irq(void) | 312 | static void __init omap3pandora_init_irq(void) | 
| 312 | { | 313 | { | 
| 313 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params); | 314 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | 
| 315 | mt46h32m32lf6_sdrc_params); | ||
| 314 | omap_init_irq(); | 316 | omap_init_irq(); | 
| 315 | omap_gpio_init(); | 317 | omap_gpio_init(); | 
| 316 | } | 318 | } | 
| @@ -397,6 +399,10 @@ static void __init omap3pandora_init(void) | |||
| 397 | omap3pandora_ads7846_init(); | 399 | omap3pandora_ads7846_init(); | 
| 398 | pandora_keys_gpio_init(); | 400 | pandora_keys_gpio_init(); | 
| 399 | usb_musb_init(); | 401 | usb_musb_init(); | 
| 402 | |||
| 403 | /* Ensure SDRC pins are mux'd for self-refresh */ | ||
| 404 | omap_cfg_reg(H16_34XX_SDRC_CKE0); | ||
| 405 | omap_cfg_reg(H17_34XX_SDRC_CKE1); | ||
| 400 | } | 406 | } | 
| 401 | 407 | ||
| 402 | static void __init omap3pandora_map_io(void) | 408 | static void __init omap3pandora_map_io(void) | 
| diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index dff5528fbfb5..6bce23004aa4 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <mach/gpmc.h> | 44 | #include <mach/gpmc.h> | 
| 45 | #include <mach/hardware.h> | 45 | #include <mach/hardware.h> | 
| 46 | #include <mach/nand.h> | 46 | #include <mach/nand.h> | 
| 47 | #include <mach/mux.h> | ||
| 47 | #include <mach/usb.h> | 48 | #include <mach/usb.h> | 
| 48 | 49 | ||
| 49 | #include "sdram-micron-mt46h32m32lf-6.h" | 50 | #include "sdram-micron-mt46h32m32lf-6.h" | 
| @@ -51,6 +52,7 @@ | |||
| 51 | 52 | ||
| 52 | #define OVERO_GPIO_BT_XGATE 15 | 53 | #define OVERO_GPIO_BT_XGATE 15 | 
| 53 | #define OVERO_GPIO_W2W_NRESET 16 | 54 | #define OVERO_GPIO_W2W_NRESET 16 | 
| 55 | #define OVERO_GPIO_PENDOWN 114 | ||
| 54 | #define OVERO_GPIO_BT_NRESET 164 | 56 | #define OVERO_GPIO_BT_NRESET 164 | 
| 55 | #define OVERO_GPIO_USBH_CPEN 168 | 57 | #define OVERO_GPIO_USBH_CPEN 168 | 
| 56 | #define OVERO_GPIO_USBH_NRESET 183 | 58 | #define OVERO_GPIO_USBH_NRESET 183 | 
| @@ -146,7 +148,7 @@ static struct platform_device overo_smsc911x_device = { | |||
| 146 | .name = "smsc911x", | 148 | .name = "smsc911x", | 
| 147 | .id = -1, | 149 | .id = -1, | 
| 148 | .num_resources = ARRAY_SIZE(overo_smsc911x_resources), | 150 | .num_resources = ARRAY_SIZE(overo_smsc911x_resources), | 
| 149 | .resource = &overo_smsc911x_resources, | 151 | .resource = overo_smsc911x_resources, | 
| 150 | .dev = { | 152 | .dev = { | 
| 151 | .platform_data = &overo_smsc911x_config, | 153 | .platform_data = &overo_smsc911x_config, | 
| 152 | }, | 154 | }, | 
| @@ -360,7 +362,8 @@ static int __init overo_i2c_init(void) | |||
| 360 | 362 | ||
| 361 | static void __init overo_init_irq(void) | 363 | static void __init overo_init_irq(void) | 
| 362 | { | 364 | { | 
| 363 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params); | 365 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | 
| 366 | mt46h32m32lf6_sdrc_params); | ||
| 364 | omap_init_irq(); | 367 | omap_init_irq(); | 
| 365 | omap_gpio_init(); | 368 | omap_gpio_init(); | 
| 366 | } | 369 | } | 
| @@ -395,6 +398,10 @@ static void __init overo_init(void) | |||
| 395 | overo_ads7846_init(); | 398 | overo_ads7846_init(); | 
| 396 | overo_init_smsc911x(); | 399 | overo_init_smsc911x(); | 
| 397 | 400 | ||
| 401 | /* Ensure SDRC pins are mux'd for self-refresh */ | ||
| 402 | omap_cfg_reg(H16_34XX_SDRC_CKE0); | ||
| 403 | omap_cfg_reg(H17_34XX_SDRC_CKE1); | ||
| 404 | |||
| 398 | if ((gpio_request(OVERO_GPIO_W2W_NRESET, | 405 | if ((gpio_request(OVERO_GPIO_W2W_NRESET, | 
| 399 | "OVERO_GPIO_W2W_NRESET") == 0) && | 406 | "OVERO_GPIO_W2W_NRESET") == 0) && | 
| 400 | (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) { | 407 | (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) { | 
| diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 9a0bf6744a05..56d931a425f7 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
| @@ -278,6 +278,10 @@ static struct twl4030_gpio_platform_data rx51_gpio_data = { | |||
| 278 | .setup = rx51_twlgpio_setup, | 278 | .setup = rx51_twlgpio_setup, | 
| 279 | }; | 279 | }; | 
| 280 | 280 | ||
| 281 | static struct twl4030_usb_data rx51_usb_data = { | ||
| 282 | .usb_mode = T2_USB_MODE_ULPI, | ||
| 283 | }; | ||
| 284 | |||
| 281 | static struct twl4030_platform_data rx51_twldata = { | 285 | static struct twl4030_platform_data rx51_twldata = { | 
| 282 | .irq_base = TWL4030_IRQ_BASE, | 286 | .irq_base = TWL4030_IRQ_BASE, | 
| 283 | .irq_end = TWL4030_IRQ_END, | 287 | .irq_end = TWL4030_IRQ_END, | 
| @@ -286,6 +290,7 @@ static struct twl4030_platform_data rx51_twldata = { | |||
| 286 | .gpio = &rx51_gpio_data, | 290 | .gpio = &rx51_gpio_data, | 
| 287 | .keypad = &rx51_kp_data, | 291 | .keypad = &rx51_kp_data, | 
| 288 | .madc = &rx51_madc_data, | 292 | .madc = &rx51_madc_data, | 
| 293 | .usb = &rx51_usb_data, | ||
| 289 | 294 | ||
| 290 | .vaux1 = &rx51_vaux1, | 295 | .vaux1 = &rx51_vaux1, | 
| 291 | .vaux2 = &rx51_vaux2, | 296 | .vaux2 = &rx51_vaux2, | 
| diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 374ff63c3eb2..1c9e07fe8266 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c | |||
| @@ -61,7 +61,7 @@ static struct omap_board_config_kernel rx51_config[] = { | |||
| 61 | 61 | ||
| 62 | static void __init rx51_init_irq(void) | 62 | static void __init rx51_init_irq(void) | 
| 63 | { | 63 | { | 
| 64 | omap2_init_common_hw(NULL); | 64 | omap2_init_common_hw(NULL, NULL); | 
| 65 | omap_init_irq(); | 65 | omap_init_irq(); | 
| 66 | omap_gpio_init(); | 66 | omap_gpio_init(); | 
| 67 | } | 67 | } | 
| @@ -75,6 +75,10 @@ static void __init rx51_init(void) | |||
| 75 | omap_serial_init(); | 75 | omap_serial_init(); | 
| 76 | usb_musb_init(); | 76 | usb_musb_init(); | 
| 77 | rx51_peripherals_init(); | 77 | rx51_peripherals_init(); | 
| 78 | |||
| 79 | /* Ensure SDRC pins are mux'd for self-refresh */ | ||
| 80 | omap_cfg_reg(H16_34XX_SDRC_CKE0); | ||
| 81 | omap_cfg_reg(H17_34XX_SDRC_CKE1); | ||
| 78 | } | 82 | } | 
| 79 | 83 | ||
| 80 | static void __init rx51_map_io(void) | 84 | static void __init rx51_map_io(void) | 
| diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index bcc0f7632dea..427b7b8b1237 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | static void __init omap_zoom2_init_irq(void) | 26 | static void __init omap_zoom2_init_irq(void) | 
| 27 | { | 27 | { | 
| 28 | omap2_init_common_hw(NULL); | 28 | omap2_init_common_hw(NULL, NULL); | 
| 29 | omap_init_irq(); | 29 | omap_init_irq(); | 
| 30 | omap_gpio_init(); | 30 | omap_gpio_init(); | 
| 31 | } | 31 | } | 
| diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index b0665f161c03..456e2ad5f621 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <mach/clock.h> | 27 | #include <mach/clock.h> | 
| 28 | #include <mach/clockdomain.h> | 28 | #include <mach/clockdomain.h> | 
| 29 | #include <mach/cpu.h> | 29 | #include <mach/cpu.h> | 
| 30 | #include <mach/prcm.h> | ||
| 30 | #include <asm/div64.h> | 31 | #include <asm/div64.h> | 
| 31 | 32 | ||
| 32 | #include <mach/sdrc.h> | 33 | #include <mach/sdrc.h> | 
| @@ -38,8 +39,6 @@ | |||
| 38 | #include "cm-regbits-24xx.h" | 39 | #include "cm-regbits-24xx.h" | 
| 39 | #include "cm-regbits-34xx.h" | 40 | #include "cm-regbits-34xx.h" | 
| 40 | 41 | ||
| 41 | #define MAX_CLOCK_ENABLE_WAIT 100000 | ||
| 42 | |||
| 43 | /* DPLL rate rounding: minimum DPLL multiplier, divider values */ | 42 | /* DPLL rate rounding: minimum DPLL multiplier, divider values */ | 
| 44 | #define DPLL_MIN_MULTIPLIER 1 | 43 | #define DPLL_MIN_MULTIPLIER 1 | 
| 45 | #define DPLL_MIN_DIVIDER 1 | 44 | #define DPLL_MIN_DIVIDER 1 | 
| @@ -274,83 +273,97 @@ unsigned long omap2_fixed_divisor_recalc(struct clk *clk) | |||
| 274 | } | 273 | } | 
| 275 | 274 | ||
| 276 | /** | 275 | /** | 
| 277 | * omap2_wait_clock_ready - wait for clock to enable | 276 | * omap2_clk_dflt_find_companion - find companion clock to @clk | 
| 278 | * @reg: physical address of clock IDLEST register | 277 | * @clk: struct clk * to find the companion clock of | 
| 279 | * @mask: value to mask against to determine if the clock is active | 278 | * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in | 
| 280 | * @name: name of the clock (for printk) | 279 | * @other_bit: u8 ** to return the companion clock bit shift in | 
| 280 | * | ||
| 281 | * Note: We don't need special code here for INVERT_ENABLE for the | ||
| 282 | * time being since INVERT_ENABLE only applies to clocks enabled by | ||
| 283 | * CM_CLKEN_PLL | ||
| 281 | * | 284 | * | 
| 282 | * Returns 1 if the clock enabled in time, or 0 if it failed to enable | 285 | * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's | 
| 283 | * in roughly MAX_CLOCK_ENABLE_WAIT microseconds. | 286 | * just a matter of XORing the bits. | 
| 287 | * | ||
| 288 | * Some clocks don't have companion clocks. For example, modules with | ||
| 289 | * only an interface clock (such as MAILBOXES) don't have a companion | ||
| 290 | * clock. Right now, this code relies on the hardware exporting a bit | ||
| 291 | * in the correct companion register that indicates that the | ||
| 292 | * nonexistent 'companion clock' is active. Future patches will | ||
| 293 | * associate this type of code with per-module data structures to | ||
| 294 | * avoid this issue, and remove the casts. No return value. | ||
| 284 | */ | 295 | */ | 
| 285 | int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name) | 296 | void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg, | 
| 297 | u8 *other_bit) | ||
| 286 | { | 298 | { | 
| 287 | int i = 0; | 299 | u32 r; | 
| 288 | int ena = 0; | ||
| 289 | 300 | ||
| 290 | /* | 301 | /* | 
| 291 | * 24xx uses 0 to indicate not ready, and 1 to indicate ready. | 302 | * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes | 
| 292 | * 34xx reverses this, just to keep us on our toes | 303 | * it's just a matter of XORing the bits. | 
| 293 | */ | 304 | */ | 
| 294 | if (cpu_mask & (RATE_IN_242X | RATE_IN_243X)) | 305 | r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN)); | 
| 295 | ena = mask; | ||
| 296 | else if (cpu_mask & RATE_IN_343X) | ||
| 297 | ena = 0; | ||
| 298 | |||
| 299 | /* Wait for lock */ | ||
| 300 | while (((__raw_readl(reg) & mask) != ena) && | ||
| 301 | (i++ < MAX_CLOCK_ENABLE_WAIT)) { | ||
| 302 | udelay(1); | ||
| 303 | } | ||
| 304 | |||
| 305 | if (i <= MAX_CLOCK_ENABLE_WAIT) | ||
| 306 | pr_debug("Clock %s stable after %d loops\n", name, i); | ||
| 307 | else | ||
| 308 | printk(KERN_ERR "Clock %s didn't enable in %d tries\n", | ||
| 309 | name, MAX_CLOCK_ENABLE_WAIT); | ||
| 310 | |||
| 311 | |||
| 312 | return (i < MAX_CLOCK_ENABLE_WAIT) ? 1 : 0; | ||
| 313 | }; | ||
| 314 | 306 | ||
| 307 | *other_reg = (__force void __iomem *)r; | ||
| 308 | *other_bit = clk->enable_bit; | ||
| 309 | } | ||
| 315 | 310 | ||
| 316 | /* | 311 | /** | 
| 317 | * Note: We don't need special code here for INVERT_ENABLE | 312 | * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk | 
| 318 | * for the time being since INVERT_ENABLE only applies to clocks enabled by | 313 | * @clk: struct clk * to find IDLEST info for | 
| 319 | * CM_CLKEN_PLL | 314 | * @idlest_reg: void __iomem ** to return the CM_IDLEST va in | 
| 315 | * @idlest_bit: u8 ** to return the CM_IDLEST bit shift in | ||
| 316 | * | ||
| 317 | * Return the CM_IDLEST register address and bit shift corresponding | ||
| 318 | * to the module that "owns" this clock. This default code assumes | ||
| 319 | * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that | ||
| 320 | * the IDLEST register address ID corresponds to the CM_*CLKEN | ||
| 321 | * register address ID (e.g., that CM_FCLKEN2 corresponds to | ||
| 322 | * CM_IDLEST2). This is not true for all modules. No return value. | ||
| 320 | */ | 323 | */ | 
| 321 | static void omap2_clk_wait_ready(struct clk *clk) | 324 | void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg, | 
| 325 | u8 *idlest_bit) | ||
| 322 | { | 326 | { | 
| 323 | void __iomem *reg, *other_reg, *st_reg; | 327 | u32 r; | 
| 324 | u32 bit; | ||
| 325 | 328 | ||
| 326 | /* | 329 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); | 
| 327 | * REVISIT: This code is pretty ugly. It would be nice to generalize | 330 | *idlest_reg = (__force void __iomem *)r; | 
| 328 | * it and pull it into struct clk itself somehow. | 331 | *idlest_bit = clk->enable_bit; | 
| 329 | */ | 332 | } | 
| 330 | reg = clk->enable_reg; | ||
| 331 | 333 | ||
| 332 | /* | 334 | /** | 
| 333 | * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes | 335 | * omap2_module_wait_ready - wait for an OMAP module to leave IDLE | 
| 334 | * it's just a matter of XORing the bits. | 336 | * @clk: struct clk * belonging to the module | 
| 335 | */ | 337 | * | 
| 336 | other_reg = (void __iomem *)((u32)reg ^ (CM_FCLKEN ^ CM_ICLKEN)); | 338 | * If the necessary clocks for the OMAP hardware IP block that | 
| 339 | * corresponds to clock @clk are enabled, then wait for the module to | ||
| 340 | * indicate readiness (i.e., to leave IDLE). This code does not | ||
| 341 | * belong in the clock code and will be moved in the medium term to | ||
| 342 | * module-dependent code. No return value. | ||
| 343 | */ | ||
| 344 | static void omap2_module_wait_ready(struct clk *clk) | ||
| 345 | { | ||
| 346 | void __iomem *companion_reg, *idlest_reg; | ||
| 347 | u8 other_bit, idlest_bit; | ||
| 348 | |||
| 349 | /* Not all modules have multiple clocks that their IDLEST depends on */ | ||
| 350 | if (clk->ops->find_companion) { | ||
| 351 | clk->ops->find_companion(clk, &companion_reg, &other_bit); | ||
| 352 | if (!(__raw_readl(companion_reg) & (1 << other_bit))) | ||
| 353 | return; | ||
| 354 | } | ||
| 337 | 355 | ||
| 338 | /* Check if both functional and interface clocks | 356 | clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit); | 
| 339 | * are running. */ | ||
| 340 | bit = 1 << clk->enable_bit; | ||
| 341 | if (!(__raw_readl(other_reg) & bit)) | ||
| 342 | return; | ||
| 343 | st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */ | ||
| 344 | 357 | ||
| 345 | omap2_wait_clock_ready(st_reg, bit, clk->name); | 358 | omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name); | 
| 346 | } | 359 | } | 
| 347 | 360 | ||
| 348 | static int omap2_dflt_clk_enable(struct clk *clk) | 361 | int omap2_dflt_clk_enable(struct clk *clk) | 
| 349 | { | 362 | { | 
| 350 | u32 v; | 363 | u32 v; | 
| 351 | 364 | ||
| 352 | if (unlikely(clk->enable_reg == NULL)) { | 365 | if (unlikely(clk->enable_reg == NULL)) { | 
| 353 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | 366 | pr_err("clock.c: Enable for %s without enable code\n", | 
| 354 | clk->name); | 367 | clk->name); | 
| 355 | return 0; /* REVISIT: -EINVAL */ | 368 | return 0; /* REVISIT: -EINVAL */ | 
| 356 | } | 369 | } | 
| @@ -363,26 +376,13 @@ static int omap2_dflt_clk_enable(struct clk *clk) | |||
| 363 | __raw_writel(v, clk->enable_reg); | 376 | __raw_writel(v, clk->enable_reg); | 
| 364 | v = __raw_readl(clk->enable_reg); /* OCP barrier */ | 377 | v = __raw_readl(clk->enable_reg); /* OCP barrier */ | 
| 365 | 378 | ||
| 366 | return 0; | 379 | if (clk->ops->find_idlest) | 
| 367 | } | 380 | omap2_module_wait_ready(clk); | 
| 368 | 381 | ||
| 369 | static int omap2_dflt_clk_enable_wait(struct clk *clk) | 382 | return 0; | 
| 370 | { | ||
| 371 | int ret; | ||
| 372 | |||
| 373 | if (!clk->enable_reg) { | ||
| 374 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | ||
| 375 | clk->name); | ||
| 376 | return 0; /* REVISIT: -EINVAL */ | ||
| 377 | } | ||
| 378 | |||
| 379 | ret = omap2_dflt_clk_enable(clk); | ||
| 380 | if (ret == 0) | ||
| 381 | omap2_clk_wait_ready(clk); | ||
| 382 | return ret; | ||
| 383 | } | 383 | } | 
| 384 | 384 | ||
| 385 | static void omap2_dflt_clk_disable(struct clk *clk) | 385 | void omap2_dflt_clk_disable(struct clk *clk) | 
| 386 | { | 386 | { | 
| 387 | u32 v; | 387 | u32 v; | 
| 388 | 388 | ||
| @@ -406,8 +406,10 @@ static void omap2_dflt_clk_disable(struct clk *clk) | |||
| 406 | } | 406 | } | 
| 407 | 407 | ||
| 408 | const struct clkops clkops_omap2_dflt_wait = { | 408 | const struct clkops clkops_omap2_dflt_wait = { | 
| 409 | .enable = omap2_dflt_clk_enable_wait, | 409 | .enable = omap2_dflt_clk_enable, | 
| 410 | .disable = omap2_dflt_clk_disable, | 410 | .disable = omap2_dflt_clk_disable, | 
| 411 | .find_companion = omap2_clk_dflt_find_companion, | ||
| 412 | .find_idlest = omap2_clk_dflt_find_idlest, | ||
| 411 | }; | 413 | }; | 
| 412 | 414 | ||
| 413 | const struct clkops clkops_omap2_dflt = { | 415 | const struct clkops clkops_omap2_dflt = { | 
| diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 2679ddfa6424..9ae7540f8af2 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
| @@ -65,6 +65,12 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate); | |||
| 65 | u32 omap2_get_dpll_rate(struct clk *clk); | 65 | u32 omap2_get_dpll_rate(struct clk *clk); | 
| 66 | int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); | 66 | int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); | 
| 67 | void omap2_clk_prepare_for_reboot(void); | 67 | void omap2_clk_prepare_for_reboot(void); | 
| 68 | int omap2_dflt_clk_enable(struct clk *clk); | ||
| 69 | void omap2_dflt_clk_disable(struct clk *clk); | ||
| 70 | void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg, | ||
| 71 | u8 *other_bit); | ||
| 72 | void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg, | ||
| 73 | u8 *idlest_bit); | ||
| 68 | 74 | ||
| 69 | extern const struct clkops clkops_omap2_dflt_wait; | 75 | extern const struct clkops clkops_omap2_dflt_wait; | 
| 70 | extern const struct clkops clkops_omap2_dflt; | 76 | extern const struct clkops clkops_omap2_dflt; | 
| diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index 44de0271fc2f..bc5d3ac66611 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | #include <mach/clock.h> | 31 | #include <mach/clock.h> | 
| 32 | #include <mach/sram.h> | 32 | #include <mach/sram.h> | 
| 33 | #include <mach/prcm.h> | ||
| 33 | #include <asm/div64.h> | 34 | #include <asm/div64.h> | 
| 34 | #include <asm/clkdev.h> | 35 | #include <asm/clkdev.h> | 
| 35 | 36 | ||
| @@ -43,6 +44,18 @@ | |||
| 43 | static const struct clkops clkops_oscck; | 44 | static const struct clkops clkops_oscck; | 
| 44 | static const struct clkops clkops_fixed; | 45 | static const struct clkops clkops_fixed; | 
| 45 | 46 | ||
| 47 | static void omap2430_clk_i2chs_find_idlest(struct clk *clk, | ||
| 48 | void __iomem **idlest_reg, | ||
| 49 | u8 *idlest_bit); | ||
| 50 | |||
| 51 | /* 2430 I2CHS has non-standard IDLEST register */ | ||
| 52 | static const struct clkops clkops_omap2430_i2chs_wait = { | ||
| 53 | .enable = omap2_dflt_clk_enable, | ||
| 54 | .disable = omap2_dflt_clk_disable, | ||
| 55 | .find_idlest = omap2430_clk_i2chs_find_idlest, | ||
| 56 | .find_companion = omap2_clk_dflt_find_companion, | ||
| 57 | }; | ||
| 58 | |||
| 46 | #include "clock24xx.h" | 59 | #include "clock24xx.h" | 
| 47 | 60 | ||
| 48 | struct omap_clk { | 61 | struct omap_clk { | 
| @@ -240,6 +253,26 @@ static void __iomem *prcm_clksrc_ctrl; | |||
| 240 | *-------------------------------------------------------------------------*/ | 253 | *-------------------------------------------------------------------------*/ | 
| 241 | 254 | ||
| 242 | /** | 255 | /** | 
| 256 | * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS | ||
| 257 | * @clk: struct clk * being enabled | ||
| 258 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into | ||
| 259 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into | ||
| 260 | * | ||
| 261 | * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the | ||
| 262 | * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function | ||
| 263 | * passes back the correct CM_IDLEST register address for I2CHS | ||
| 264 | * modules. No return value. | ||
| 265 | */ | ||
| 266 | static void omap2430_clk_i2chs_find_idlest(struct clk *clk, | ||
| 267 | void __iomem **idlest_reg, | ||
| 268 | u8 *idlest_bit) | ||
| 269 | { | ||
| 270 | *idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST); | ||
| 271 | *idlest_bit = clk->enable_bit; | ||
| 272 | } | ||
| 273 | |||
| 274 | |||
| 275 | /** | ||
| 243 | * omap2xxx_clk_get_core_rate - return the CORE_CLK rate | 276 | * omap2xxx_clk_get_core_rate - return the CORE_CLK rate | 
| 244 | * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck") | 277 | * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck") | 
| 245 | * | 278 | * | 
| @@ -325,8 +358,8 @@ static int omap2_clk_fixed_enable(struct clk *clk) | |||
| 325 | else if (clk == &apll54_ck) | 358 | else if (clk == &apll54_ck) | 
| 326 | cval = OMAP24XX_ST_54M_APLL; | 359 | cval = OMAP24XX_ST_54M_APLL; | 
| 327 | 360 | ||
| 328 | omap2_wait_clock_ready(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval, | 361 | omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval, | 
| 329 | clk->name); | 362 | clk->name); | 
| 330 | 363 | ||
| 331 | /* | 364 | /* | 
| 332 | * REVISIT: Should we return an error code if omap2_wait_clock_ready() | 365 | * REVISIT: Should we return an error code if omap2_wait_clock_ready() | 
| diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h index 458f00cdcbea..d19cf7a7d8db 100644 --- a/arch/arm/mach-omap2/clock24xx.h +++ b/arch/arm/mach-omap2/clock24xx.h | |||
| @@ -2337,7 +2337,7 @@ static struct clk i2c2_fck = { | |||
| 2337 | 2337 | ||
| 2338 | static struct clk i2chs2_fck = { | 2338 | static struct clk i2chs2_fck = { | 
| 2339 | .name = "i2c_fck", | 2339 | .name = "i2c_fck", | 
| 2340 | .ops = &clkops_omap2_dflt_wait, | 2340 | .ops = &clkops_omap2430_i2chs_wait, | 
| 2341 | .id = 2, | 2341 | .id = 2, | 
| 2342 | .parent = &func_96m_ck, | 2342 | .parent = &func_96m_ck, | 
| 2343 | .clkdm_name = "core_l4_clkdm", | 2343 | .clkdm_name = "core_l4_clkdm", | 
| @@ -2370,7 +2370,7 @@ static struct clk i2c1_fck = { | |||
| 2370 | 2370 | ||
| 2371 | static struct clk i2chs1_fck = { | 2371 | static struct clk i2chs1_fck = { | 
| 2372 | .name = "i2c_fck", | 2372 | .name = "i2c_fck", | 
| 2373 | .ops = &clkops_omap2_dflt_wait, | 2373 | .ops = &clkops_omap2430_i2chs_wait, | 
| 2374 | .id = 1, | 2374 | .id = 1, | 
| 2375 | .parent = &func_96m_ck, | 2375 | .parent = &func_96m_ck, | 
| 2376 | .clkdm_name = "core_l4_clkdm", | 2376 | .clkdm_name = "core_l4_clkdm", | 
| diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 045da923e75b..cd7819cc0c9e 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * OMAP3-specific clock framework functions | 2 | * OMAP3-specific clock framework functions | 
| 3 | * | 3 | * | 
| 4 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 4 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 
| 5 | * Copyright (C) 2007-2008 Nokia Corporation | 5 | * Copyright (C) 2007-2009 Nokia Corporation | 
| 6 | * | 6 | * | 
| 7 | * Written by Paul Walmsley | 7 | * Written by Paul Walmsley | 
| 8 | * Testing and integration fixes by Jouni Högander | 8 | * Testing and integration fixes by Jouni Högander | 
| @@ -41,6 +41,37 @@ | |||
| 41 | 41 | ||
| 42 | static const struct clkops clkops_noncore_dpll_ops; | 42 | static const struct clkops clkops_noncore_dpll_ops; | 
| 43 | 43 | ||
| 44 | static void omap3430es2_clk_ssi_find_idlest(struct clk *clk, | ||
| 45 | void __iomem **idlest_reg, | ||
| 46 | u8 *idlest_bit); | ||
| 47 | static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk, | ||
| 48 | void __iomem **idlest_reg, | ||
| 49 | u8 *idlest_bit); | ||
| 50 | static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk, | ||
| 51 | void __iomem **idlest_reg, | ||
| 52 | u8 *idlest_bit); | ||
| 53 | |||
| 54 | static const struct clkops clkops_omap3430es2_ssi_wait = { | ||
| 55 | .enable = omap2_dflt_clk_enable, | ||
| 56 | .disable = omap2_dflt_clk_disable, | ||
| 57 | .find_idlest = omap3430es2_clk_ssi_find_idlest, | ||
| 58 | .find_companion = omap2_clk_dflt_find_companion, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static const struct clkops clkops_omap3430es2_hsotgusb_wait = { | ||
| 62 | .enable = omap2_dflt_clk_enable, | ||
| 63 | .disable = omap2_dflt_clk_disable, | ||
| 64 | .find_idlest = omap3430es2_clk_hsotgusb_find_idlest, | ||
| 65 | .find_companion = omap2_clk_dflt_find_companion, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static const struct clkops clkops_omap3430es2_dss_usbhost_wait = { | ||
| 69 | .enable = omap2_dflt_clk_enable, | ||
| 70 | .disable = omap2_dflt_clk_disable, | ||
| 71 | .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest, | ||
| 72 | .find_companion = omap2_clk_dflt_find_companion, | ||
| 73 | }; | ||
| 74 | |||
| 44 | #include "clock34xx.h" | 75 | #include "clock34xx.h" | 
| 45 | 76 | ||
| 46 | struct omap_clk { | 77 | struct omap_clk { | 
| @@ -157,10 +188,13 @@ static struct omap_clk omap34xx_clks[] = { | |||
| 157 | CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1), | 188 | CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1), | 
| 158 | CLK(NULL, "core_12m_fck", &core_12m_fck, CK_343X), | 189 | CLK(NULL, "core_12m_fck", &core_12m_fck, CK_343X), | 
| 159 | CLK("omap_hdq.0", "fck", &hdq_fck, CK_343X), | 190 | CLK("omap_hdq.0", "fck", &hdq_fck, CK_343X), | 
| 160 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck, CK_343X), | 191 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1), | 
| 161 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck, CK_343X), | 192 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2), | 
| 193 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1), | ||
| 194 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2, CK_3430ES2), | ||
| 162 | CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X), | 195 | CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X), | 
| 163 | CLK("musb_hdrc", "ick", &hsotgusb_ick, CK_343X), | 196 | CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es1, CK_3430ES1), | 
| 197 | CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es2, CK_3430ES2), | ||
| 164 | CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X), | 198 | CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X), | 
| 165 | CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X), | 199 | CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X), | 
| 166 | CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X), | 200 | CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X), | 
| @@ -193,18 +227,21 @@ static struct omap_clk omap34xx_clks[] = { | |||
| 193 | CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_343X), | 227 | CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_343X), | 
| 194 | CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_343X), | 228 | CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_343X), | 
| 195 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_343X), | 229 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_343X), | 
| 196 | CLK(NULL, "ssi_ick", &ssi_ick, CK_343X), | 230 | CLK(NULL, "ssi_ick", &ssi_ick_3430es1, CK_3430ES1), | 
| 231 | CLK(NULL, "ssi_ick", &ssi_ick_3430es2, CK_3430ES2), | ||
| 197 | CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1), | 232 | CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1), | 
| 198 | CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_343X), | 233 | CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_343X), | 
| 199 | CLK(NULL, "aes1_ick", &aes1_ick, CK_343X), | 234 | CLK(NULL, "aes1_ick", &aes1_ick, CK_343X), | 
| 200 | CLK("omap_rng", "ick", &rng_ick, CK_343X), | 235 | CLK("omap_rng", "ick", &rng_ick, CK_343X), | 
| 201 | CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), | 236 | CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), | 
| 202 | CLK(NULL, "des1_ick", &des1_ick, CK_343X), | 237 | CLK(NULL, "des1_ick", &des1_ick, CK_343X), | 
| 203 | CLK("omapfb", "dss1_fck", &dss1_alwon_fck, CK_343X), | 238 | CLK("omapfb", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), | 
| 239 | CLK("omapfb", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2), | ||
| 204 | CLK("omapfb", "tv_fck", &dss_tv_fck, CK_343X), | 240 | CLK("omapfb", "tv_fck", &dss_tv_fck, CK_343X), | 
| 205 | CLK("omapfb", "video_fck", &dss_96m_fck, CK_343X), | 241 | CLK("omapfb", "video_fck", &dss_96m_fck, CK_343X), | 
| 206 | CLK("omapfb", "dss2_fck", &dss2_alwon_fck, CK_343X), | 242 | CLK("omapfb", "dss2_fck", &dss2_alwon_fck, CK_343X), | 
| 207 | CLK("omapfb", "ick", &dss_ick, CK_343X), | 243 | CLK("omapfb", "ick", &dss_ick_3430es1, CK_3430ES1), | 
| 244 | CLK("omapfb", "ick", &dss_ick_3430es2, CK_3430ES2), | ||
| 208 | CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), | 245 | CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), | 
| 209 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), | 246 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), | 
| 210 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), | 247 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), | 
| @@ -301,6 +338,73 @@ static struct omap_clk omap34xx_clks[] = { | |||
| 301 | #define SDRC_MPURATE_LOOPS 96 | 338 | #define SDRC_MPURATE_LOOPS 96 | 
| 302 | 339 | ||
| 303 | /** | 340 | /** | 
| 341 | * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI | ||
| 342 | * @clk: struct clk * being enabled | ||
| 343 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into | ||
| 344 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into | ||
| 345 | * | ||
| 346 | * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift | ||
| 347 | * from the CM_{I,F}CLKEN bit. Pass back the correct info via | ||
| 348 | * @idlest_reg and @idlest_bit. No return value. | ||
| 349 | */ | ||
| 350 | static void omap3430es2_clk_ssi_find_idlest(struct clk *clk, | ||
| 351 | void __iomem **idlest_reg, | ||
| 352 | u8 *idlest_bit) | ||
| 353 | { | ||
| 354 | u32 r; | ||
| 355 | |||
| 356 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); | ||
| 357 | *idlest_reg = (__force void __iomem *)r; | ||
| 358 | *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT; | ||
| 359 | } | ||
| 360 | |||
| 361 | /** | ||
| 362 | * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST | ||
| 363 | * @clk: struct clk * being enabled | ||
| 364 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into | ||
| 365 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into | ||
| 366 | * | ||
| 367 | * Some OMAP modules on OMAP3 ES2+ chips have both initiator and | ||
| 368 | * target IDLEST bits. For our purposes, we are concerned with the | ||
| 369 | * target IDLEST bits, which exist at a different bit position than | ||
| 370 | * the *CLKEN bit position for these modules (DSS and USBHOST) (The | ||
| 371 | * default find_idlest code assumes that they are at the same | ||
| 372 | * position.) No return value. | ||
| 373 | */ | ||
| 374 | static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk, | ||
| 375 | void __iomem **idlest_reg, | ||
| 376 | u8 *idlest_bit) | ||
| 377 | { | ||
| 378 | u32 r; | ||
| 379 | |||
| 380 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); | ||
| 381 | *idlest_reg = (__force void __iomem *)r; | ||
| 382 | /* USBHOST_IDLE has same shift */ | ||
| 383 | *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT; | ||
| 384 | } | ||
| 385 | |||
| 386 | /** | ||
| 387 | * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB | ||
| 388 | * @clk: struct clk * being enabled | ||
| 389 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into | ||
| 390 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into | ||
| 391 | * | ||
| 392 | * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different | ||
| 393 | * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via | ||
| 394 | * @idlest_reg and @idlest_bit. No return value. | ||
| 395 | */ | ||
| 396 | static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk, | ||
| 397 | void __iomem **idlest_reg, | ||
| 398 | u8 *idlest_bit) | ||
| 399 | { | ||
| 400 | u32 r; | ||
| 401 | |||
| 402 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); | ||
| 403 | *idlest_reg = (__force void __iomem *)r; | ||
| 404 | *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT; | ||
| 405 | } | ||
| 406 | |||
| 407 | /** | ||
| 304 | * omap3_dpll_recalc - recalculate DPLL rate | 408 | * omap3_dpll_recalc - recalculate DPLL rate | 
| 305 | * @clk: DPLL struct clk | 409 | * @clk: DPLL struct clk | 
| 306 | * | 410 | * | 
| @@ -725,7 +829,9 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) | |||
| 725 | u32 unlock_dll = 0; | 829 | u32 unlock_dll = 0; | 
| 726 | u32 c; | 830 | u32 c; | 
| 727 | unsigned long validrate, sdrcrate, mpurate; | 831 | unsigned long validrate, sdrcrate, mpurate; | 
| 728 | struct omap_sdrc_params *sp; | 832 | struct omap_sdrc_params *sdrc_cs0; | 
| 833 | struct omap_sdrc_params *sdrc_cs1; | ||
| 834 | int ret; | ||
| 729 | 835 | ||
| 730 | if (!clk || !rate) | 836 | if (!clk || !rate) | 
| 731 | return -EINVAL; | 837 | return -EINVAL; | 
| @@ -743,8 +849,8 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) | |||
| 743 | else | 849 | else | 
| 744 | sdrcrate >>= ((clk->rate / rate) >> 1); | 850 | sdrcrate >>= ((clk->rate / rate) >> 1); | 
| 745 | 851 | ||
| 746 | sp = omap2_sdrc_get_params(sdrcrate); | 852 | ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1); | 
| 747 | if (!sp) | 853 | if (ret) | 
| 748 | return -EINVAL; | 854 | return -EINVAL; | 
| 749 | 855 | ||
| 750 | if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) { | 856 | if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) { | 
| @@ -765,12 +871,29 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) | |||
| 765 | 871 | ||
| 766 | pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate, | 872 | pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate, | 
| 767 | validrate); | 873 | validrate); | 
| 768 | pr_debug("clock: SDRC timing params used: %08x %08x %08x\n", | 874 | pr_debug("clock: SDRC CS0 timing params used:" | 
| 769 | sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb); | 875 | " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", | 
| 770 | 876 | sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, | |
| 771 | omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla, | 877 | sdrc_cs0->actim_ctrlb, sdrc_cs0->mr); | 
| 772 | sp->actim_ctrlb, new_div, unlock_dll, c, | 878 | if (sdrc_cs1) | 
| 773 | sp->mr, rate > clk->rate); | 879 | pr_debug("clock: SDRC CS1 timing params used: " | 
| 880 | " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", | ||
| 881 | sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, | ||
| 882 | sdrc_cs1->actim_ctrlb, sdrc_cs1->mr); | ||
| 883 | |||
| 884 | if (sdrc_cs1) | ||
| 885 | omap3_configure_core_dpll( | ||
| 886 | new_div, unlock_dll, c, rate > clk->rate, | ||
| 887 | sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, | ||
| 888 | sdrc_cs0->actim_ctrlb, sdrc_cs0->mr, | ||
| 889 | sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, | ||
| 890 | sdrc_cs1->actim_ctrlb, sdrc_cs1->mr); | ||
| 891 | else | ||
| 892 | omap3_configure_core_dpll( | ||
| 893 | new_div, unlock_dll, c, rate > clk->rate, | ||
| 894 | sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, | ||
| 895 | sdrc_cs0->actim_ctrlb, sdrc_cs0->mr, | ||
| 896 | 0, 0, 0, 0); | ||
| 774 | 897 | ||
| 775 | return 0; | 898 | return 0; | 
| 776 | } | 899 | } | 
| diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index e433aec4efdd..57cc2725b923 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
| @@ -1568,7 +1568,7 @@ static const struct clksel ssi_ssr_clksel[] = { | |||
| 1568 | { .parent = NULL } | 1568 | { .parent = NULL } | 
| 1569 | }; | 1569 | }; | 
| 1570 | 1570 | ||
| 1571 | static struct clk ssi_ssr_fck = { | 1571 | static struct clk ssi_ssr_fck_3430es1 = { | 
| 1572 | .name = "ssi_ssr_fck", | 1572 | .name = "ssi_ssr_fck", | 
| 1573 | .ops = &clkops_omap2_dflt, | 1573 | .ops = &clkops_omap2_dflt, | 
| 1574 | .init = &omap2_init_clksel_parent, | 1574 | .init = &omap2_init_clksel_parent, | 
| @@ -1581,10 +1581,31 @@ static struct clk ssi_ssr_fck = { | |||
| 1581 | .recalc = &omap2_clksel_recalc, | 1581 | .recalc = &omap2_clksel_recalc, | 
| 1582 | }; | 1582 | }; | 
| 1583 | 1583 | ||
| 1584 | static struct clk ssi_sst_fck = { | 1584 | static struct clk ssi_ssr_fck_3430es2 = { | 
| 1585 | .name = "ssi_ssr_fck", | ||
| 1586 | .ops = &clkops_omap3430es2_ssi_wait, | ||
| 1587 | .init = &omap2_init_clksel_parent, | ||
| 1588 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | ||
| 1589 | .enable_bit = OMAP3430_EN_SSI_SHIFT, | ||
| 1590 | .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), | ||
| 1591 | .clksel_mask = OMAP3430_CLKSEL_SSI_MASK, | ||
| 1592 | .clksel = ssi_ssr_clksel, | ||
| 1593 | .clkdm_name = "core_l4_clkdm", | ||
| 1594 | .recalc = &omap2_clksel_recalc, | ||
| 1595 | }; | ||
| 1596 | |||
| 1597 | static struct clk ssi_sst_fck_3430es1 = { | ||
| 1585 | .name = "ssi_sst_fck", | 1598 | .name = "ssi_sst_fck", | 
| 1586 | .ops = &clkops_null, | 1599 | .ops = &clkops_null, | 
| 1587 | .parent = &ssi_ssr_fck, | 1600 | .parent = &ssi_ssr_fck_3430es1, | 
| 1601 | .fixed_div = 2, | ||
| 1602 | .recalc = &omap2_fixed_divisor_recalc, | ||
| 1603 | }; | ||
| 1604 | |||
| 1605 | static struct clk ssi_sst_fck_3430es2 = { | ||
| 1606 | .name = "ssi_sst_fck", | ||
| 1607 | .ops = &clkops_null, | ||
| 1608 | .parent = &ssi_ssr_fck_3430es2, | ||
| 1588 | .fixed_div = 2, | 1609 | .fixed_div = 2, | 
| 1589 | .recalc = &omap2_fixed_divisor_recalc, | 1610 | .recalc = &omap2_fixed_divisor_recalc, | 
| 1590 | }; | 1611 | }; | 
| @@ -1606,9 +1627,19 @@ static struct clk core_l3_ick = { | |||
| 1606 | .recalc = &followparent_recalc, | 1627 | .recalc = &followparent_recalc, | 
| 1607 | }; | 1628 | }; | 
| 1608 | 1629 | ||
| 1609 | static struct clk hsotgusb_ick = { | 1630 | static struct clk hsotgusb_ick_3430es1 = { | 
| 1610 | .name = "hsotgusb_ick", | 1631 | .name = "hsotgusb_ick", | 
| 1611 | .ops = &clkops_omap2_dflt_wait, | 1632 | .ops = &clkops_omap2_dflt, | 
| 1633 | .parent = &core_l3_ick, | ||
| 1634 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | ||
| 1635 | .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, | ||
| 1636 | .clkdm_name = "core_l3_clkdm", | ||
| 1637 | .recalc = &followparent_recalc, | ||
| 1638 | }; | ||
| 1639 | |||
| 1640 | static struct clk hsotgusb_ick_3430es2 = { | ||
| 1641 | .name = "hsotgusb_ick", | ||
| 1642 | .ops = &clkops_omap3430es2_hsotgusb_wait, | ||
| 1612 | .parent = &core_l3_ick, | 1643 | .parent = &core_l3_ick, | 
| 1613 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1644 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 
| 1614 | .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, | 1645 | .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, | 
| @@ -1947,7 +1978,7 @@ static struct clk ssi_l4_ick = { | |||
| 1947 | .recalc = &followparent_recalc, | 1978 | .recalc = &followparent_recalc, | 
| 1948 | }; | 1979 | }; | 
| 1949 | 1980 | ||
| 1950 | static struct clk ssi_ick = { | 1981 | static struct clk ssi_ick_3430es1 = { | 
| 1951 | .name = "ssi_ick", | 1982 | .name = "ssi_ick", | 
| 1952 | .ops = &clkops_omap2_dflt, | 1983 | .ops = &clkops_omap2_dflt, | 
| 1953 | .parent = &ssi_l4_ick, | 1984 | .parent = &ssi_l4_ick, | 
| @@ -1957,6 +1988,16 @@ static struct clk ssi_ick = { | |||
| 1957 | .recalc = &followparent_recalc, | 1988 | .recalc = &followparent_recalc, | 
| 1958 | }; | 1989 | }; | 
| 1959 | 1990 | ||
| 1991 | static struct clk ssi_ick_3430es2 = { | ||
| 1992 | .name = "ssi_ick", | ||
| 1993 | .ops = &clkops_omap3430es2_ssi_wait, | ||
| 1994 | .parent = &ssi_l4_ick, | ||
| 1995 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | ||
| 1996 | .enable_bit = OMAP3430_EN_SSI_SHIFT, | ||
| 1997 | .clkdm_name = "core_l4_clkdm", | ||
| 1998 | .recalc = &followparent_recalc, | ||
| 1999 | }; | ||
| 2000 | |||
| 1960 | /* REVISIT: Technically the TRM claims that this is CORE_CLK based, | 2001 | /* REVISIT: Technically the TRM claims that this is CORE_CLK based, | 
| 1961 | * but l4_ick makes more sense to me */ | 2002 | * but l4_ick makes more sense to me */ | 
| 1962 | 2003 | ||
| @@ -2024,7 +2065,7 @@ static struct clk des1_ick = { | |||
| 2024 | }; | 2065 | }; | 
| 2025 | 2066 | ||
| 2026 | /* DSS */ | 2067 | /* DSS */ | 
| 2027 | static struct clk dss1_alwon_fck = { | 2068 | static struct clk dss1_alwon_fck_3430es1 = { | 
| 2028 | .name = "dss1_alwon_fck", | 2069 | .name = "dss1_alwon_fck", | 
| 2029 | .ops = &clkops_omap2_dflt, | 2070 | .ops = &clkops_omap2_dflt, | 
| 2030 | .parent = &dpll4_m4x2_ck, | 2071 | .parent = &dpll4_m4x2_ck, | 
| @@ -2034,6 +2075,16 @@ static struct clk dss1_alwon_fck = { | |||
| 2034 | .recalc = &followparent_recalc, | 2075 | .recalc = &followparent_recalc, | 
| 2035 | }; | 2076 | }; | 
| 2036 | 2077 | ||
| 2078 | static struct clk dss1_alwon_fck_3430es2 = { | ||
| 2079 | .name = "dss1_alwon_fck", | ||
| 2080 | .ops = &clkops_omap3430es2_dss_usbhost_wait, | ||
| 2081 | .parent = &dpll4_m4x2_ck, | ||
| 2082 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), | ||
| 2083 | .enable_bit = OMAP3430_EN_DSS1_SHIFT, | ||
| 2084 | .clkdm_name = "dss_clkdm", | ||
| 2085 | .recalc = &followparent_recalc, | ||
| 2086 | }; | ||
| 2087 | |||
| 2037 | static struct clk dss_tv_fck = { | 2088 | static struct clk dss_tv_fck = { | 
| 2038 | .name = "dss_tv_fck", | 2089 | .name = "dss_tv_fck", | 
| 2039 | .ops = &clkops_omap2_dflt, | 2090 | .ops = &clkops_omap2_dflt, | 
| @@ -2067,7 +2118,7 @@ static struct clk dss2_alwon_fck = { | |||
| 2067 | .recalc = &followparent_recalc, | 2118 | .recalc = &followparent_recalc, | 
| 2068 | }; | 2119 | }; | 
| 2069 | 2120 | ||
| 2070 | static struct clk dss_ick = { | 2121 | static struct clk dss_ick_3430es1 = { | 
| 2071 | /* Handles both L3 and L4 clocks */ | 2122 | /* Handles both L3 and L4 clocks */ | 
| 2072 | .name = "dss_ick", | 2123 | .name = "dss_ick", | 
| 2073 | .ops = &clkops_omap2_dflt, | 2124 | .ops = &clkops_omap2_dflt, | 
| @@ -2079,6 +2130,18 @@ static struct clk dss_ick = { | |||
| 2079 | .recalc = &followparent_recalc, | 2130 | .recalc = &followparent_recalc, | 
| 2080 | }; | 2131 | }; | 
| 2081 | 2132 | ||
| 2133 | static struct clk dss_ick_3430es2 = { | ||
| 2134 | /* Handles both L3 and L4 clocks */ | ||
| 2135 | .name = "dss_ick", | ||
| 2136 | .ops = &clkops_omap3430es2_dss_usbhost_wait, | ||
| 2137 | .parent = &l4_ick, | ||
| 2138 | .init = &omap2_init_clk_clkdm, | ||
| 2139 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), | ||
| 2140 | .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, | ||
| 2141 | .clkdm_name = "dss_clkdm", | ||
| 2142 | .recalc = &followparent_recalc, | ||
| 2143 | }; | ||
| 2144 | |||
| 2082 | /* CAM */ | 2145 | /* CAM */ | 
| 2083 | 2146 | ||
| 2084 | static struct clk cam_mclk = { | 2147 | static struct clk cam_mclk = { | 
| @@ -2118,7 +2181,7 @@ static struct clk csi2_96m_fck = { | |||
| 2118 | 2181 | ||
| 2119 | static struct clk usbhost_120m_fck = { | 2182 | static struct clk usbhost_120m_fck = { | 
| 2120 | .name = "usbhost_120m_fck", | 2183 | .name = "usbhost_120m_fck", | 
| 2121 | .ops = &clkops_omap2_dflt_wait, | 2184 | .ops = &clkops_omap2_dflt, | 
| 2122 | .parent = &dpll5_m2_ck, | 2185 | .parent = &dpll5_m2_ck, | 
| 2123 | .init = &omap2_init_clk_clkdm, | 2186 | .init = &omap2_init_clk_clkdm, | 
| 2124 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), | 2187 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), | 
| @@ -2129,7 +2192,7 @@ static struct clk usbhost_120m_fck = { | |||
| 2129 | 2192 | ||
| 2130 | static struct clk usbhost_48m_fck = { | 2193 | static struct clk usbhost_48m_fck = { | 
| 2131 | .name = "usbhost_48m_fck", | 2194 | .name = "usbhost_48m_fck", | 
| 2132 | .ops = &clkops_omap2_dflt_wait, | 2195 | .ops = &clkops_omap3430es2_dss_usbhost_wait, | 
| 2133 | .parent = &omap_48m_fck, | 2196 | .parent = &omap_48m_fck, | 
| 2134 | .init = &omap2_init_clk_clkdm, | 2197 | .init = &omap2_init_clk_clkdm, | 
| 2135 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), | 2198 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), | 
| @@ -2141,7 +2204,7 @@ static struct clk usbhost_48m_fck = { | |||
| 2141 | static struct clk usbhost_ick = { | 2204 | static struct clk usbhost_ick = { | 
| 2142 | /* Handles both L3 and L4 clocks */ | 2205 | /* Handles both L3 and L4 clocks */ | 
| 2143 | .name = "usbhost_ick", | 2206 | .name = "usbhost_ick", | 
| 2144 | .ops = &clkops_omap2_dflt_wait, | 2207 | .ops = &clkops_omap3430es2_dss_usbhost_wait, | 
| 2145 | .parent = &l4_ick, | 2208 | .parent = &l4_ick, | 
| 2146 | .init = &omap2_init_clk_clkdm, | 2209 | .init = &omap2_init_clk_clkdm, | 
| 2147 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), | 2210 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), | 
| diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 1d3c93bf86d3..f3c91a1ca391 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h | |||
| @@ -29,9 +29,9 @@ | |||
| 29 | * These registers appear once per CM module. | 29 | * These registers appear once per CM module. | 
| 30 | */ | 30 | */ | 
| 31 | 31 | ||
| 32 | #define OMAP3430_CM_REVISION OMAP_CM_REGADDR(OCP_MOD, 0x0000) | 32 | #define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000) | 
| 33 | #define OMAP3430_CM_SYSCONFIG OMAP_CM_REGADDR(OCP_MOD, 0x0010) | 33 | #define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010) | 
| 34 | #define OMAP3430_CM_POLCTRL OMAP_CM_REGADDR(OCP_MOD, 0x009c) | 34 | #define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c) | 
| 35 | 35 | ||
| 36 | #define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070 | 36 | #define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070 | 
| 37 | #define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070) | 37 | #define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070) | 
| diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3a86b0f66031..e9b9bcb19b4e 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
| @@ -276,14 +276,15 @@ static int __init _omap2_init_reprogram_sdrc(void) | |||
| 276 | return v; | 276 | return v; | 
| 277 | } | 277 | } | 
| 278 | 278 | ||
| 279 | void __init omap2_init_common_hw(struct omap_sdrc_params *sp) | 279 | void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, | 
| 280 | struct omap_sdrc_params *sdrc_cs1) | ||
| 280 | { | 281 | { | 
| 281 | omap2_mux_init(); | 282 | omap2_mux_init(); | 
| 282 | #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ | 283 | #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ | 
| 283 | pwrdm_init(powerdomains_omap); | 284 | pwrdm_init(powerdomains_omap); | 
| 284 | clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); | 285 | clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); | 
| 285 | omap2_clk_init(); | 286 | omap2_clk_init(); | 
| 286 | omap2_sdrc_init(sp); | 287 | omap2_sdrc_init(sdrc_cs0, sdrc_cs1); | 
| 287 | _omap2_init_reprogram_sdrc(); | 288 | _omap2_init_reprogram_sdrc(); | 
| 288 | #endif | 289 | #endif | 
| 289 | gpmc_init(); | 290 | gpmc_init(); | 
| diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index 1541fd4c8d0f..3c04c2f1b23f 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c | |||
| @@ -119,6 +119,7 @@ static int twl_mmc_late_init(struct device *dev) | |||
| 119 | if (i != 0) | 119 | if (i != 0) | 
| 120 | break; | 120 | break; | 
| 121 | ret = PTR_ERR(reg); | 121 | ret = PTR_ERR(reg); | 
| 122 | hsmmc[i].vcc = NULL; | ||
| 122 | goto err; | 123 | goto err; | 
| 123 | } | 124 | } | 
| 124 | hsmmc[i].vcc = reg; | 125 | hsmmc[i].vcc = reg; | 
| @@ -165,8 +166,13 @@ done: | |||
| 165 | static void twl_mmc_cleanup(struct device *dev) | 166 | static void twl_mmc_cleanup(struct device *dev) | 
| 166 | { | 167 | { | 
| 167 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 168 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 
| 169 | int i; | ||
| 168 | 170 | ||
| 169 | gpio_free(mmc->slots[0].switch_pin); | 171 | gpio_free(mmc->slots[0].switch_pin); | 
| 172 | for(i = 0; i < ARRAY_SIZE(hsmmc); i++) { | ||
| 173 | regulator_put(hsmmc[i].vcc); | ||
| 174 | regulator_put(hsmmc[i].vcc_aux); | ||
| 175 | } | ||
| 170 | } | 176 | } | 
| 171 | 177 | ||
| 172 | #ifdef CONFIG_PM | 178 | #ifdef CONFIG_PM | 
| diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 026c4fc883a7..43d6b92b65f2 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
| @@ -486,6 +486,12 @@ MUX_CFG_34XX("H19_34XX_GPIO164_OUT", 0x19c, | |||
| 486 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | 486 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) | 
| 487 | MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6, | 487 | MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6, | 
| 488 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | 488 | OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) | 
| 489 | |||
| 490 | /* OMAP3 SDRC CKE signals to SDR/DDR ram chips */ | ||
| 491 | MUX_CFG_34XX("H16_34XX_SDRC_CKE0", 0x262, | ||
| 492 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) | ||
| 493 | MUX_CFG_34XX("H17_34XX_SDRC_CKE1", 0x264, | ||
| 494 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) | ||
| 489 | }; | 495 | }; | 
| 490 | 496 | ||
| 491 | #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) | 497 | #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) | 
| diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index f7b3baf76678..21201cd4117b 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
| @@ -11,9 +11,6 @@ | |||
| 11 | #ifndef __ARCH_ARM_MACH_OMAP2_PM_H | 11 | #ifndef __ARCH_ARM_MACH_OMAP2_PM_H | 
| 12 | #define __ARCH_ARM_MACH_OMAP2_PM_H | 12 | #define __ARCH_ARM_MACH_OMAP2_PM_H | 
| 13 | 13 | ||
| 14 | extern int omap2_pm_init(void); | ||
| 15 | extern int omap3_pm_init(void); | ||
| 16 | |||
| 17 | #ifdef CONFIG_PM_DEBUG | 14 | #ifdef CONFIG_PM_DEBUG | 
| 18 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); | 15 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); | 
| 19 | extern int omap2_pm_debug; | 16 | extern int omap2_pm_debug; | 
| diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index db1025562fb0..528dbdc26e23 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
| @@ -470,7 +470,7 @@ static void __init prcm_setup_regs(void) | |||
| 470 | WKUP_MOD, PM_WKEN); | 470 | WKUP_MOD, PM_WKEN); | 
| 471 | } | 471 | } | 
| 472 | 472 | ||
| 473 | int __init omap2_pm_init(void) | 473 | static int __init omap2_pm_init(void) | 
| 474 | { | 474 | { | 
| 475 | u32 l; | 475 | u32 l; | 
| 476 | 476 | ||
| diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 841d4c5ed8be..488d595d8e4b 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
| @@ -39,7 +39,9 @@ | |||
| 39 | struct power_state { | 39 | struct power_state { | 
| 40 | struct powerdomain *pwrdm; | 40 | struct powerdomain *pwrdm; | 
| 41 | u32 next_state; | 41 | u32 next_state; | 
| 42 | #ifdef CONFIG_SUSPEND | ||
| 42 | u32 saved_state; | 43 | u32 saved_state; | 
| 44 | #endif | ||
| 43 | struct list_head node; | 45 | struct list_head node; | 
| 44 | }; | 46 | }; | 
| 45 | 47 | ||
| @@ -293,6 +295,9 @@ out: | |||
| 293 | local_irq_enable(); | 295 | local_irq_enable(); | 
| 294 | } | 296 | } | 
| 295 | 297 | ||
| 298 | #ifdef CONFIG_SUSPEND | ||
| 299 | static suspend_state_t suspend_state; | ||
| 300 | |||
| 296 | static int omap3_pm_prepare(void) | 301 | static int omap3_pm_prepare(void) | 
| 297 | { | 302 | { | 
| 298 | disable_hlt(); | 303 | disable_hlt(); | 
| @@ -321,7 +326,6 @@ static int omap3_pm_suspend(void) | |||
| 321 | restore: | 326 | restore: | 
| 322 | /* Restore next_pwrsts */ | 327 | /* Restore next_pwrsts */ | 
| 323 | list_for_each_entry(pwrst, &pwrst_list, node) { | 328 | list_for_each_entry(pwrst, &pwrst_list, node) { | 
| 324 | set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); | ||
| 325 | state = pwrdm_read_prev_pwrst(pwrst->pwrdm); | 329 | state = pwrdm_read_prev_pwrst(pwrst->pwrdm); | 
| 326 | if (state > pwrst->next_state) { | 330 | if (state > pwrst->next_state) { | 
| 327 | printk(KERN_INFO "Powerdomain (%s) didn't enter " | 331 | printk(KERN_INFO "Powerdomain (%s) didn't enter " | 
| @@ -329,6 +333,7 @@ restore: | |||
| 329 | pwrst->pwrdm->name, pwrst->next_state); | 333 | pwrst->pwrdm->name, pwrst->next_state); | 
| 330 | ret = -1; | 334 | ret = -1; | 
| 331 | } | 335 | } | 
| 336 | set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); | ||
| 332 | } | 337 | } | 
| 333 | if (ret) | 338 | if (ret) | 
| 334 | printk(KERN_ERR "Could not enter target state in pm_suspend\n"); | 339 | printk(KERN_ERR "Could not enter target state in pm_suspend\n"); | 
| @@ -339,11 +344,11 @@ restore: | |||
| 339 | return ret; | 344 | return ret; | 
| 340 | } | 345 | } | 
| 341 | 346 | ||
| 342 | static int omap3_pm_enter(suspend_state_t state) | 347 | static int omap3_pm_enter(suspend_state_t unused) | 
| 343 | { | 348 | { | 
| 344 | int ret = 0; | 349 | int ret = 0; | 
| 345 | 350 | ||
| 346 | switch (state) { | 351 | switch (suspend_state) { | 
| 347 | case PM_SUSPEND_STANDBY: | 352 | case PM_SUSPEND_STANDBY: | 
| 348 | case PM_SUSPEND_MEM: | 353 | case PM_SUSPEND_MEM: | 
| 349 | ret = omap3_pm_suspend(); | 354 | ret = omap3_pm_suspend(); | 
| @@ -360,12 +365,30 @@ static void omap3_pm_finish(void) | |||
| 360 | enable_hlt(); | 365 | enable_hlt(); | 
| 361 | } | 366 | } | 
| 362 | 367 | ||
| 368 | /* Hooks to enable / disable UART interrupts during suspend */ | ||
| 369 | static int omap3_pm_begin(suspend_state_t state) | ||
| 370 | { | ||
| 371 | suspend_state = state; | ||
| 372 | omap_uart_enable_irqs(0); | ||
| 373 | return 0; | ||
| 374 | } | ||
| 375 | |||
| 376 | static void omap3_pm_end(void) | ||
| 377 | { | ||
| 378 | suspend_state = PM_SUSPEND_ON; | ||
| 379 | omap_uart_enable_irqs(1); | ||
| 380 | return; | ||
| 381 | } | ||
| 382 | |||
| 363 | static struct platform_suspend_ops omap_pm_ops = { | 383 | static struct platform_suspend_ops omap_pm_ops = { | 
| 384 | .begin = omap3_pm_begin, | ||
| 385 | .end = omap3_pm_end, | ||
| 364 | .prepare = omap3_pm_prepare, | 386 | .prepare = omap3_pm_prepare, | 
| 365 | .enter = omap3_pm_enter, | 387 | .enter = omap3_pm_enter, | 
| 366 | .finish = omap3_pm_finish, | 388 | .finish = omap3_pm_finish, | 
| 367 | .valid = suspend_valid_only_mem, | 389 | .valid = suspend_valid_only_mem, | 
| 368 | }; | 390 | }; | 
| 391 | #endif /* CONFIG_SUSPEND */ | ||
| 369 | 392 | ||
| 370 | 393 | ||
| 371 | /** | 394 | /** | 
| @@ -613,6 +636,24 @@ static void __init prcm_setup_regs(void) | |||
| 613 | /* Clear any pending PRCM interrupts */ | 636 | /* Clear any pending PRCM interrupts */ | 
| 614 | prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | 637 | prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | 
| 615 | 638 | ||
| 639 | /* Don't attach IVA interrupts */ | ||
| 640 | prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); | ||
| 641 | prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); | ||
| 642 | prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3); | ||
| 643 | prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL); | ||
| 644 | |||
| 645 | /* Clear any pending 'reset' flags */ | ||
| 646 | prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST); | ||
| 647 | prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST); | ||
| 648 | prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST); | ||
| 649 | prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST); | ||
| 650 | prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST); | ||
| 651 | prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST); | ||
| 652 | prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST); | ||
| 653 | |||
| 654 | /* Clear any pending PRCM interrupts */ | ||
| 655 | prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
| 656 | |||
| 616 | omap3_iva_idle(); | 657 | omap3_iva_idle(); | 
| 617 | omap3_d2d_idle(); | 658 | omap3_d2d_idle(); | 
| 618 | } | 659 | } | 
| @@ -652,7 +693,7 @@ static int __init clkdms_setup(struct clockdomain *clkdm) | |||
| 652 | return 0; | 693 | return 0; | 
| 653 | } | 694 | } | 
| 654 | 695 | ||
| 655 | int __init omap3_pm_init(void) | 696 | static int __init omap3_pm_init(void) | 
| 656 | { | 697 | { | 
| 657 | struct power_state *pwrst, *tmp; | 698 | struct power_state *pwrst, *tmp; | 
| 658 | int ret; | 699 | int ret; | 
| @@ -692,7 +733,9 @@ int __init omap3_pm_init(void) | |||
| 692 | _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, | 733 | _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, | 
| 693 | omap34xx_cpu_suspend_sz); | 734 | omap34xx_cpu_suspend_sz); | 
| 694 | 735 | ||
| 736 | #ifdef CONFIG_SUSPEND | ||
| 695 | suspend_set_ops(&omap_pm_ops); | 737 | suspend_set_ops(&omap_pm_ops); | 
| 738 | #endif /* CONFIG_SUSPEND */ | ||
| 696 | 739 | ||
| 697 | pm_idle = omap3_pm_idle; | 740 | pm_idle = omap3_pm_idle; | 
| 698 | 741 | ||
| diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index f945156d5585..ced555a4cd1a 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> | 
| 18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> | 
| 19 | #include <linux/io.h> | 19 | #include <linux/io.h> | 
| 20 | #include <linux/delay.h> | ||
| 20 | 21 | ||
| 21 | #include <mach/common.h> | 22 | #include <mach/common.h> | 
| 22 | #include <mach/prcm.h> | 23 | #include <mach/prcm.h> | 
| @@ -28,6 +29,8 @@ | |||
| 28 | static void __iomem *prm_base; | 29 | static void __iomem *prm_base; | 
| 29 | static void __iomem *cm_base; | 30 | static void __iomem *cm_base; | 
| 30 | 31 | ||
| 32 | #define MAX_MODULE_ENABLE_WAIT 100000 | ||
| 33 | |||
| 31 | u32 omap_prcm_get_reset_sources(void) | 34 | u32 omap_prcm_get_reset_sources(void) | 
| 32 | { | 35 | { | 
| 33 | /* XXX This presumably needs modification for 34XX */ | 36 | /* XXX This presumably needs modification for 34XX */ | 
| @@ -120,6 +123,46 @@ u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) | |||
| 120 | } | 123 | } | 
| 121 | EXPORT_SYMBOL(cm_rmw_mod_reg_bits); | 124 | EXPORT_SYMBOL(cm_rmw_mod_reg_bits); | 
| 122 | 125 | ||
| 126 | /** | ||
| 127 | * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness | ||
| 128 | * @reg: physical address of module IDLEST register | ||
| 129 | * @mask: value to mask against to determine if the module is active | ||
| 130 | * @name: name of the clock (for printk) | ||
| 131 | * | ||
| 132 | * Returns 1 if the module indicated readiness in time, or 0 if it | ||
| 133 | * failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds. | ||
| 134 | */ | ||
| 135 | int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name) | ||
| 136 | { | ||
| 137 | int i = 0; | ||
| 138 | int ena = 0; | ||
| 139 | |||
| 140 | /* | ||
| 141 | * 24xx uses 0 to indicate not ready, and 1 to indicate ready. | ||
| 142 | * 34xx reverses this, just to keep us on our toes | ||
| 143 | */ | ||
| 144 | if (cpu_is_omap24xx()) | ||
| 145 | ena = mask; | ||
| 146 | else if (cpu_is_omap34xx()) | ||
| 147 | ena = 0; | ||
| 148 | else | ||
| 149 | BUG(); | ||
| 150 | |||
| 151 | /* Wait for lock */ | ||
| 152 | while (((__raw_readl(reg) & mask) != ena) && | ||
| 153 | (i++ < MAX_MODULE_ENABLE_WAIT)) | ||
| 154 | udelay(1); | ||
| 155 | |||
| 156 | if (i < MAX_MODULE_ENABLE_WAIT) | ||
| 157 | pr_debug("cm: Module associated with clock %s ready after %d " | ||
| 158 | "loops\n", name, i); | ||
| 159 | else | ||
| 160 | pr_err("cm: Module associated with clock %s didn't enable in " | ||
| 161 | "%d tries\n", name, MAX_MODULE_ENABLE_WAIT); | ||
| 162 | |||
| 163 | return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0; | ||
| 164 | }; | ||
| 165 | |||
| 123 | void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) | 166 | void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) | 
| 124 | { | 167 | { | 
| 125 | prm_base = omap2_globals->prm; | 168 | prm_base = omap2_globals->prm; | 
| diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c index 2045441e8385..9e3bd4fa7810 100644 --- a/arch/arm/mach-omap2/sdrc.c +++ b/arch/arm/mach-omap2/sdrc.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include <mach/sdrc.h> | 32 | #include <mach/sdrc.h> | 
| 33 | #include "sdrc.h" | 33 | #include "sdrc.h" | 
| 34 | 34 | ||
| 35 | static struct omap_sdrc_params *sdrc_init_params; | 35 | static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; | 
| 36 | 36 | ||
| 37 | void __iomem *omap2_sdrc_base; | 37 | void __iomem *omap2_sdrc_base; | 
| 38 | void __iomem *omap2_sms_base; | 38 | void __iomem *omap2_sms_base; | 
| @@ -45,33 +45,49 @@ void __iomem *omap2_sms_base; | |||
| 45 | /** | 45 | /** | 
| 46 | * omap2_sdrc_get_params - return SDRC register values for a given clock rate | 46 | * omap2_sdrc_get_params - return SDRC register values for a given clock rate | 
| 47 | * @r: SDRC clock rate (in Hz) | 47 | * @r: SDRC clock rate (in Hz) | 
| 48 | * @sdrc_cs0: chip select 0 ram timings ** | ||
| 49 | * @sdrc_cs1: chip select 1 ram timings ** | ||
| 48 | * | 50 | * | 
| 49 | * Return pre-calculated values for the SDRC_ACTIM_CTRLA, | 51 | * Return pre-calculated values for the SDRC_ACTIM_CTRLA, | 
| 50 | * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL, and SDRC_MR registers, for a given | 52 | * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] | 
| 51 | * SDRC clock rate 'r'. These parameters control various timing | 53 | * structs,for a given SDRC clock rate 'r'. | 
| 52 | * delays in the SDRAM controller that are expressed in terms of the | 54 | * These parameters control various timing delays in the SDRAM controller | 
| 53 | * number of SDRC clock cycles to wait; hence the clock rate | 55 | * that are expressed in terms of the number of SDRC clock cycles to | 
| 54 | * dependency. Note that sdrc_init_params must be sorted rate | 56 | * wait; hence the clock rate dependency. | 
| 55 | * descending. Also assumes that both chip-selects use the same | 57 | * | 
| 56 | * timing parameters. Returns a struct omap_sdrc_params * upon | 58 | * Supports 2 different timing parameters for both chip selects. | 
| 57 | * success, or NULL upon failure. | 59 | * | 
| 60 | * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. | ||
| 61 | * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size | ||
| 62 | * as sdrc_init_params_cs_0. | ||
| 63 | * | ||
| 64 | * Fills in the struct omap_sdrc_params * for each chip select. | ||
| 65 | * Returns 0 upon success or -1 upon failure. | ||
| 58 | */ | 66 | */ | 
| 59 | struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r) | 67 | int omap2_sdrc_get_params(unsigned long r, | 
| 68 | struct omap_sdrc_params **sdrc_cs0, | ||
| 69 | struct omap_sdrc_params **sdrc_cs1) | ||
| 60 | { | 70 | { | 
| 61 | struct omap_sdrc_params *sp; | 71 | struct omap_sdrc_params *sp0, *sp1; | 
| 62 | 72 | ||
| 63 | if (!sdrc_init_params) | 73 | if (!sdrc_init_params_cs0) | 
| 64 | return NULL; | 74 | return -1; | 
| 65 | 75 | ||
| 66 | sp = sdrc_init_params; | 76 | sp0 = sdrc_init_params_cs0; | 
| 77 | sp1 = sdrc_init_params_cs1; | ||
| 67 | 78 | ||
| 68 | while (sp->rate && sp->rate != r) | 79 | while (sp0->rate && sp0->rate != r) { | 
| 69 | sp++; | 80 | sp0++; | 
| 81 | if (sdrc_init_params_cs1) | ||
| 82 | sp1++; | ||
| 83 | } | ||
| 70 | 84 | ||
| 71 | if (!sp->rate) | 85 | if (!sp0->rate) | 
| 72 | return NULL; | 86 | return -1; | 
| 73 | 87 | ||
| 74 | return sp; | 88 | *sdrc_cs0 = sp0; | 
| 89 | *sdrc_cs1 = sp1; | ||
| 90 | return 0; | ||
| 75 | } | 91 | } | 
| 76 | 92 | ||
| 77 | 93 | ||
| @@ -83,13 +99,15 @@ void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals) | |||
| 83 | 99 | ||
| 84 | /** | 100 | /** | 
| 85 | * omap2_sdrc_init - initialize SMS, SDRC devices on boot | 101 | * omap2_sdrc_init - initialize SMS, SDRC devices on boot | 
| 86 | * @sp: pointer to a null-terminated list of struct omap_sdrc_params | 102 | * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params | 
| 103 | * Support for 2 chip selects timings | ||
| 87 | * | 104 | * | 
| 88 | * Turn on smart idle modes for SDRAM scheduler and controller. | 105 | * Turn on smart idle modes for SDRAM scheduler and controller. | 
| 89 | * Program a known-good configuration for the SDRC to deal with buggy | 106 | * Program a known-good configuration for the SDRC to deal with buggy | 
| 90 | * bootloaders. | 107 | * bootloaders. | 
| 91 | */ | 108 | */ | 
| 92 | void __init omap2_sdrc_init(struct omap_sdrc_params *sp) | 109 | void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, | 
| 110 | struct omap_sdrc_params *sdrc_cs1) | ||
| 93 | { | 111 | { | 
| 94 | u32 l; | 112 | u32 l; | 
| 95 | 113 | ||
| @@ -103,11 +121,15 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sp) | |||
| 103 | l |= (0x2 << 3); | 121 | l |= (0x2 << 3); | 
| 104 | sdrc_write_reg(l, SDRC_SYSCONFIG); | 122 | sdrc_write_reg(l, SDRC_SYSCONFIG); | 
| 105 | 123 | ||
| 106 | sdrc_init_params = sp; | 124 | sdrc_init_params_cs0 = sdrc_cs0; | 
| 125 | sdrc_init_params_cs1 = sdrc_cs1; | ||
| 107 | 126 | ||
| 108 | /* XXX Enable SRFRONIDLEREQ here also? */ | 127 | /* XXX Enable SRFRONIDLEREQ here also? */ | 
| 128 | /* | ||
| 129 | * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA | ||
| 130 | * can cause random memory corruption | ||
| 131 | */ | ||
| 109 | l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | | 132 | l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | | 
| 110 | (1 << SDRC_POWER_PWDENA_SHIFT) | | ||
| 111 | (1 << SDRC_POWER_PAGEPOLICY_SHIFT); | 133 | (1 << SDRC_POWER_PAGEPOLICY_SHIFT); | 
| 112 | sdrc_write_reg(l, SDRC_POWER); | 134 | sdrc_write_reg(l, SDRC_POWER); | 
| 113 | } | 135 | } | 
| diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index b094c15bfe47..a7421a50410b 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
| @@ -54,6 +54,7 @@ struct omap_uart_state { | |||
| 54 | 54 | ||
| 55 | struct plat_serial8250_port *p; | 55 | struct plat_serial8250_port *p; | 
| 56 | struct list_head node; | 56 | struct list_head node; | 
| 57 | struct platform_device pdev; | ||
| 57 | 58 | ||
| 58 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | 59 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | 
| 59 | int context_valid; | 60 | int context_valid; | 
| @@ -68,10 +69,9 @@ struct omap_uart_state { | |||
| 68 | #endif | 69 | #endif | 
| 69 | }; | 70 | }; | 
| 70 | 71 | ||
| 71 | static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS]; | ||
| 72 | static LIST_HEAD(uart_list); | 72 | static LIST_HEAD(uart_list); | 
| 73 | 73 | ||
| 74 | static struct plat_serial8250_port serial_platform_data[] = { | 74 | static struct plat_serial8250_port serial_platform_data0[] = { | 
| 75 | { | 75 | { | 
| 76 | .membase = IO_ADDRESS(OMAP_UART1_BASE), | 76 | .membase = IO_ADDRESS(OMAP_UART1_BASE), | 
| 77 | .mapbase = OMAP_UART1_BASE, | 77 | .mapbase = OMAP_UART1_BASE, | 
| @@ -81,6 +81,12 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
| 81 | .regshift = 2, | 81 | .regshift = 2, | 
| 82 | .uartclk = OMAP24XX_BASE_BAUD * 16, | 82 | .uartclk = OMAP24XX_BASE_BAUD * 16, | 
| 83 | }, { | 83 | }, { | 
| 84 | .flags = 0 | ||
| 85 | } | ||
| 86 | }; | ||
| 87 | |||
| 88 | static struct plat_serial8250_port serial_platform_data1[] = { | ||
| 89 | { | ||
| 84 | .membase = IO_ADDRESS(OMAP_UART2_BASE), | 90 | .membase = IO_ADDRESS(OMAP_UART2_BASE), | 
| 85 | .mapbase = OMAP_UART2_BASE, | 91 | .mapbase = OMAP_UART2_BASE, | 
| 86 | .irq = 73, | 92 | .irq = 73, | 
| @@ -89,6 +95,12 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
| 89 | .regshift = 2, | 95 | .regshift = 2, | 
| 90 | .uartclk = OMAP24XX_BASE_BAUD * 16, | 96 | .uartclk = OMAP24XX_BASE_BAUD * 16, | 
| 91 | }, { | 97 | }, { | 
| 98 | .flags = 0 | ||
| 99 | } | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct plat_serial8250_port serial_platform_data2[] = { | ||
| 103 | { | ||
| 92 | .membase = IO_ADDRESS(OMAP_UART3_BASE), | 104 | .membase = IO_ADDRESS(OMAP_UART3_BASE), | 
| 93 | .mapbase = OMAP_UART3_BASE, | 105 | .mapbase = OMAP_UART3_BASE, | 
| 94 | .irq = 74, | 106 | .irq = 74, | 
| @@ -217,6 +229,40 @@ static inline void omap_uart_disable_clocks(struct omap_uart_state *uart) | |||
| 217 | clk_disable(uart->fck); | 229 | clk_disable(uart->fck); | 
| 218 | } | 230 | } | 
| 219 | 231 | ||
| 232 | static void omap_uart_enable_wakeup(struct omap_uart_state *uart) | ||
| 233 | { | ||
| 234 | /* Set wake-enable bit */ | ||
| 235 | if (uart->wk_en && uart->wk_mask) { | ||
| 236 | u32 v = __raw_readl(uart->wk_en); | ||
| 237 | v |= uart->wk_mask; | ||
| 238 | __raw_writel(v, uart->wk_en); | ||
| 239 | } | ||
| 240 | |||
| 241 | /* Ensure IOPAD wake-enables are set */ | ||
| 242 | if (cpu_is_omap34xx() && uart->padconf) { | ||
| 243 | u16 v = omap_ctrl_readw(uart->padconf); | ||
| 244 | v |= OMAP3_PADCONF_WAKEUPENABLE0; | ||
| 245 | omap_ctrl_writew(v, uart->padconf); | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | static void omap_uart_disable_wakeup(struct omap_uart_state *uart) | ||
| 250 | { | ||
| 251 | /* Clear wake-enable bit */ | ||
| 252 | if (uart->wk_en && uart->wk_mask) { | ||
| 253 | u32 v = __raw_readl(uart->wk_en); | ||
| 254 | v &= ~uart->wk_mask; | ||
| 255 | __raw_writel(v, uart->wk_en); | ||
| 256 | } | ||
| 257 | |||
| 258 | /* Ensure IOPAD wake-enables are cleared */ | ||
| 259 | if (cpu_is_omap34xx() && uart->padconf) { | ||
| 260 | u16 v = omap_ctrl_readw(uart->padconf); | ||
| 261 | v &= ~OMAP3_PADCONF_WAKEUPENABLE0; | ||
| 262 | omap_ctrl_writew(v, uart->padconf); | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 220 | static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, | 266 | static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, | 
| 221 | int enable) | 267 | int enable) | 
| 222 | { | 268 | { | 
| @@ -246,6 +292,11 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart) | |||
| 246 | 292 | ||
| 247 | static void omap_uart_allow_sleep(struct omap_uart_state *uart) | 293 | static void omap_uart_allow_sleep(struct omap_uart_state *uart) | 
| 248 | { | 294 | { | 
| 295 | if (device_may_wakeup(&uart->pdev.dev)) | ||
| 296 | omap_uart_enable_wakeup(uart); | ||
| 297 | else | ||
| 298 | omap_uart_disable_wakeup(uart); | ||
| 299 | |||
| 249 | if (!uart->clocked) | 300 | if (!uart->clocked) | 
| 250 | return; | 301 | return; | 
| 251 | 302 | ||
| @@ -292,7 +343,6 @@ void omap_uart_resume_idle(int num) | |||
| 292 | /* Check for normal UART wakeup */ | 343 | /* Check for normal UART wakeup */ | 
| 293 | if (__raw_readl(uart->wk_st) & uart->wk_mask) | 344 | if (__raw_readl(uart->wk_st) & uart->wk_mask) | 
| 294 | omap_uart_block_sleep(uart); | 345 | omap_uart_block_sleep(uart); | 
| 295 | |||
| 296 | return; | 346 | return; | 
| 297 | } | 347 | } | 
| 298 | } | 348 | } | 
| @@ -346,16 +396,13 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) | |||
| 346 | return IRQ_NONE; | 396 | return IRQ_NONE; | 
| 347 | } | 397 | } | 
| 348 | 398 | ||
| 349 | static u32 sleep_timeout = DEFAULT_TIMEOUT; | ||
| 350 | |||
| 351 | static void omap_uart_idle_init(struct omap_uart_state *uart) | 399 | static void omap_uart_idle_init(struct omap_uart_state *uart) | 
| 352 | { | 400 | { | 
| 353 | u32 v; | ||
| 354 | struct plat_serial8250_port *p = uart->p; | 401 | struct plat_serial8250_port *p = uart->p; | 
| 355 | int ret; | 402 | int ret; | 
| 356 | 403 | ||
| 357 | uart->can_sleep = 0; | 404 | uart->can_sleep = 0; | 
| 358 | uart->timeout = sleep_timeout; | 405 | uart->timeout = DEFAULT_TIMEOUT; | 
| 359 | setup_timer(&uart->timer, omap_uart_idle_timer, | 406 | setup_timer(&uart->timer, omap_uart_idle_timer, | 
| 360 | (unsigned long) uart); | 407 | (unsigned long) uart); | 
| 361 | mod_timer(&uart->timer, jiffies + uart->timeout); | 408 | mod_timer(&uart->timer, jiffies + uart->timeout); | 
| @@ -413,76 +460,101 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) | |||
| 413 | uart->padconf = 0; | 460 | uart->padconf = 0; | 
| 414 | } | 461 | } | 
| 415 | 462 | ||
| 416 | /* Set wake-enable bit */ | ||
| 417 | if (uart->wk_en && uart->wk_mask) { | ||
| 418 | v = __raw_readl(uart->wk_en); | ||
| 419 | v |= uart->wk_mask; | ||
| 420 | __raw_writel(v, uart->wk_en); | ||
| 421 | } | ||
| 422 | |||
| 423 | /* Ensure IOPAD wake-enables are set */ | ||
| 424 | if (cpu_is_omap34xx() && uart->padconf) { | ||
| 425 | u16 v; | ||
| 426 | |||
| 427 | v = omap_ctrl_readw(uart->padconf); | ||
| 428 | v |= OMAP3_PADCONF_WAKEUPENABLE0; | ||
| 429 | omap_ctrl_writew(v, uart->padconf); | ||
| 430 | } | ||
| 431 | |||
| 432 | p->flags |= UPF_SHARE_IRQ; | 463 | p->flags |= UPF_SHARE_IRQ; | 
| 433 | ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED, | 464 | ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED, | 
| 434 | "serial idle", (void *)uart); | 465 | "serial idle", (void *)uart); | 
| 435 | WARN_ON(ret); | 466 | WARN_ON(ret); | 
| 436 | } | 467 | } | 
| 437 | 468 | ||
| 438 | static ssize_t sleep_timeout_show(struct kobject *kobj, | 469 | void omap_uart_enable_irqs(int enable) | 
| 439 | struct kobj_attribute *attr, | 470 | { | 
| 471 | int ret; | ||
| 472 | struct omap_uart_state *uart; | ||
| 473 | |||
| 474 | list_for_each_entry(uart, &uart_list, node) { | ||
| 475 | if (enable) | ||
| 476 | ret = request_irq(uart->p->irq, omap_uart_interrupt, | ||
| 477 | IRQF_SHARED, "serial idle", (void *)uart); | ||
| 478 | else | ||
| 479 | free_irq(uart->p->irq, (void *)uart); | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | static ssize_t sleep_timeout_show(struct device *dev, | ||
| 484 | struct device_attribute *attr, | ||
| 440 | char *buf) | 485 | char *buf) | 
| 441 | { | 486 | { | 
| 442 | return sprintf(buf, "%u\n", sleep_timeout / HZ); | 487 | struct platform_device *pdev = container_of(dev, | 
| 488 | struct platform_device, dev); | ||
| 489 | struct omap_uart_state *uart = container_of(pdev, | ||
| 490 | struct omap_uart_state, pdev); | ||
| 491 | |||
| 492 | return sprintf(buf, "%u\n", uart->timeout / HZ); | ||
| 443 | } | 493 | } | 
| 444 | 494 | ||
| 445 | static ssize_t sleep_timeout_store(struct kobject *kobj, | 495 | static ssize_t sleep_timeout_store(struct device *dev, | 
| 446 | struct kobj_attribute *attr, | 496 | struct device_attribute *attr, | 
| 447 | const char *buf, size_t n) | 497 | const char *buf, size_t n) | 
| 448 | { | 498 | { | 
| 449 | struct omap_uart_state *uart; | 499 | struct platform_device *pdev = container_of(dev, | 
| 500 | struct platform_device, dev); | ||
| 501 | struct omap_uart_state *uart = container_of(pdev, | ||
| 502 | struct omap_uart_state, pdev); | ||
| 450 | unsigned int value; | 503 | unsigned int value; | 
| 451 | 504 | ||
| 452 | if (sscanf(buf, "%u", &value) != 1) { | 505 | if (sscanf(buf, "%u", &value) != 1) { | 
| 453 | printk(KERN_ERR "sleep_timeout_store: Invalid value\n"); | 506 | printk(KERN_ERR "sleep_timeout_store: Invalid value\n"); | 
| 454 | return -EINVAL; | 507 | return -EINVAL; | 
| 455 | } | 508 | } | 
| 456 | sleep_timeout = value * HZ; | 509 | |
| 457 | list_for_each_entry(uart, &uart_list, node) { | 510 | uart->timeout = value * HZ; | 
| 458 | uart->timeout = sleep_timeout; | 511 | if (uart->timeout) | 
| 459 | if (uart->timeout) | 512 | mod_timer(&uart->timer, jiffies + uart->timeout); | 
| 460 | mod_timer(&uart->timer, jiffies + uart->timeout); | 513 | else | 
| 461 | else | 514 | /* A zero value means disable timeout feature */ | 
| 462 | /* A zero value means disable timeout feature */ | 515 | omap_uart_block_sleep(uart); | 
| 463 | omap_uart_block_sleep(uart); | 516 | |
| 464 | } | ||
| 465 | return n; | 517 | return n; | 
| 466 | } | 518 | } | 
| 467 | 519 | ||
| 468 | static struct kobj_attribute sleep_timeout_attr = | 520 | DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store); | 
| 469 | __ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store); | 521 | #define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr)) | 
| 470 | |||
| 471 | #else | 522 | #else | 
| 472 | static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} | 523 | static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} | 
| 524 | #define DEV_CREATE_FILE(dev, attr) | ||
| 473 | #endif /* CONFIG_PM */ | 525 | #endif /* CONFIG_PM */ | 
| 474 | 526 | ||
| 475 | static struct platform_device serial_device = { | 527 | static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = { | 
| 476 | .name = "serial8250", | 528 | { | 
| 477 | .id = PLAT8250_DEV_PLATFORM, | 529 | .pdev = { | 
| 478 | .dev = { | 530 | .name = "serial8250", | 
| 479 | .platform_data = serial_platform_data, | 531 | .id = PLAT8250_DEV_PLATFORM, | 
| 532 | .dev = { | ||
| 533 | .platform_data = serial_platform_data0, | ||
| 534 | }, | ||
| 535 | }, | ||
| 536 | }, { | ||
| 537 | .pdev = { | ||
| 538 | .name = "serial8250", | ||
| 539 | .id = PLAT8250_DEV_PLATFORM1, | ||
| 540 | .dev = { | ||
| 541 | .platform_data = serial_platform_data1, | ||
| 542 | }, | ||
| 543 | }, | ||
| 544 | }, { | ||
| 545 | .pdev = { | ||
| 546 | .name = "serial8250", | ||
| 547 | .id = PLAT8250_DEV_PLATFORM2, | ||
| 548 | .dev = { | ||
| 549 | .platform_data = serial_platform_data2, | ||
| 550 | }, | ||
| 551 | }, | ||
| 480 | }, | 552 | }, | 
| 481 | }; | 553 | }; | 
| 482 | 554 | ||
| 483 | void __init omap_serial_init(void) | 555 | void __init omap_serial_init(void) | 
| 484 | { | 556 | { | 
| 485 | int i, err; | 557 | int i; | 
| 486 | const struct omap_uart_config *info; | 558 | const struct omap_uart_config *info; | 
| 487 | char name[16]; | 559 | char name[16]; | 
| 488 | 560 | ||
| @@ -496,14 +568,12 @@ void __init omap_serial_init(void) | |||
| 496 | 568 | ||
| 497 | if (info == NULL) | 569 | if (info == NULL) | 
| 498 | return; | 570 | return; | 
| 499 | if (cpu_is_omap44xx()) { | ||
| 500 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) | ||
| 501 | serial_platform_data[i].irq += 32; | ||
| 502 | } | ||
| 503 | 571 | ||
| 504 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | 572 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | 
| 505 | struct plat_serial8250_port *p = serial_platform_data + i; | ||
| 506 | struct omap_uart_state *uart = &omap_uart[i]; | 573 | struct omap_uart_state *uart = &omap_uart[i]; | 
| 574 | struct platform_device *pdev = &uart->pdev; | ||
| 575 | struct device *dev = &pdev->dev; | ||
| 576 | struct plat_serial8250_port *p = dev->platform_data; | ||
| 507 | 577 | ||
| 508 | if (!(info->enabled_uarts & (1 << i))) { | 578 | if (!(info->enabled_uarts & (1 << i))) { | 
| 509 | p->membase = NULL; | 579 | p->membase = NULL; | 
| @@ -531,20 +601,21 @@ void __init omap_serial_init(void) | |||
| 531 | uart->num = i; | 601 | uart->num = i; | 
| 532 | p->private_data = uart; | 602 | p->private_data = uart; | 
| 533 | uart->p = p; | 603 | uart->p = p; | 
| 534 | list_add(&uart->node, &uart_list); | 604 | list_add_tail(&uart->node, &uart_list); | 
| 605 | |||
| 606 | if (cpu_is_omap44xx()) | ||
| 607 | p->irq += 32; | ||
| 535 | 608 | ||
| 536 | omap_uart_enable_clocks(uart); | 609 | omap_uart_enable_clocks(uart); | 
| 537 | omap_uart_reset(uart); | 610 | omap_uart_reset(uart); | 
| 538 | omap_uart_idle_init(uart); | 611 | omap_uart_idle_init(uart); | 
| 539 | } | ||
| 540 | |||
| 541 | err = platform_device_register(&serial_device); | ||
| 542 | |||
| 543 | #ifdef CONFIG_PM | ||
| 544 | if (!err) | ||
| 545 | err = sysfs_create_file(&serial_device.dev.kobj, | ||
| 546 | &sleep_timeout_attr.attr); | ||
| 547 | #endif | ||
| 548 | 612 | ||
| 613 | if (WARN_ON(platform_device_register(pdev))) | ||
| 614 | continue; | ||
| 615 | if ((cpu_is_omap34xx() && uart->padconf) || | ||
| 616 | (uart->wk_en && uart->wk_mask)) { | ||
| 617 | device_init_wakeup(dev, true); | ||
| 618 | DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout); | ||
| 619 | } | ||
| 620 | } | ||
| 549 | } | 621 | } | 
| 550 | |||
| diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index f41f8d96ddba..82aa4a3d160c 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | .text | 37 | .text | 
| 38 | 38 | ||
| 39 | /* r4 parameters */ | 39 | /* r1 parameters */ | 
| 40 | #define SDRC_NO_UNLOCK_DLL 0x0 | 40 | #define SDRC_NO_UNLOCK_DLL 0x0 | 
| 41 | #define SDRC_UNLOCK_DLL 0x1 | 41 | #define SDRC_UNLOCK_DLL 0x1 | 
| 42 | 42 | ||
| @@ -58,7 +58,6 @@ | |||
| 58 | 58 | ||
| 59 | /* SDRC_POWER bit settings */ | 59 | /* SDRC_POWER bit settings */ | 
| 60 | #define SRFRONIDLEREQ_MASK 0x40 | 60 | #define SRFRONIDLEREQ_MASK 0x40 | 
| 61 | #define PWDENA_MASK 0x4 | ||
| 62 | 61 | ||
| 63 | /* CM_IDLEST1_CORE bit settings */ | 62 | /* CM_IDLEST1_CORE bit settings */ | 
| 64 | #define ST_SDRC_MASK 0x2 | 63 | #define ST_SDRC_MASK 0x2 | 
| @@ -71,41 +70,72 @@ | |||
| 71 | 70 | ||
| 72 | /* | 71 | /* | 
| 73 | * omap3_sram_configure_core_dpll - change DPLL3 M2 divider | 72 | * omap3_sram_configure_core_dpll - change DPLL3 M2 divider | 
| 74 | * r0 = new SDRC_RFR_CTRL register contents | 73 | * | 
| 75 | * r1 = new SDRC_ACTIM_CTRLA register contents | 74 | * Params passed in registers: | 
| 76 | * r2 = new SDRC_ACTIM_CTRLB register contents | 75 | * r0 = new M2 divider setting (only 1 and 2 supported right now) | 
| 77 | * r3 = new M2 divider setting (only 1 and 2 supported right now) | 76 | * r1 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for | 
| 78 | * r4 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for | ||
| 79 | * SDRC rates < 83MHz | 77 | * SDRC rates < 83MHz | 
| 80 | * r5 = number of MPU cycles to wait for SDRC to stabilize after | 78 | * r2 = number of MPU cycles to wait for SDRC to stabilize after | 
| 81 | * reprogramming the SDRC when switching to a slower MPU speed | 79 | * reprogramming the SDRC when switching to a slower MPU speed | 
| 82 | * r6 = new SDRC_MR_0 register value | 80 | * r3 = increasing SDRC rate? (1 = yes, 0 = no) | 
| 83 | * r7 = increasing SDRC rate? (1 = yes, 0 = no) | 81 | * | 
| 82 | * Params passed via the stack. The needed params will be copied in SRAM | ||
| 83 | * before use by the code in SRAM (SDRAM is not accessible during SDRC | ||
| 84 | * reconfiguration): | ||
| 85 | * new SDRC_RFR_CTRL_0 register contents | ||
| 86 | * new SDRC_ACTIM_CTRL_A_0 register contents | ||
| 87 | * new SDRC_ACTIM_CTRL_B_0 register contents | ||
| 88 | * new SDRC_MR_0 register value | ||
| 89 | * new SDRC_RFR_CTRL_1 register contents | ||
| 90 | * new SDRC_ACTIM_CTRL_A_1 register contents | ||
| 91 | * new SDRC_ACTIM_CTRL_B_1 register contents | ||
| 92 | * new SDRC_MR_1 register value | ||
| 84 | * | 93 | * | 
| 94 | * If the param SDRC_RFR_CTRL_1 is 0, the parameters | ||
| 95 | * are not programmed into the SDRC CS1 registers | ||
| 85 | */ | 96 | */ | 
| 86 | ENTRY(omap3_sram_configure_core_dpll) | 97 | ENTRY(omap3_sram_configure_core_dpll) | 
| 87 | stmfd sp!, {r1-r12, lr} @ store regs to stack | 98 | stmfd sp!, {r1-r12, lr} @ store regs to stack | 
| 88 | ldr r4, [sp, #52] @ pull extra args off the stack | 99 | |
| 89 | ldr r5, [sp, #56] @ load extra args from the stack | 100 | @ pull the extra args off the stack | 
| 90 | ldr r6, [sp, #60] @ load extra args from the stack | 101 | @ and store them in SRAM | 
| 91 | ldr r7, [sp, #64] @ load extra args from the stack | 102 | ldr r4, [sp, #52] | 
| 103 | str r4, omap_sdrc_rfr_ctrl_0_val | ||
| 104 | ldr r4, [sp, #56] | ||
| 105 | str r4, omap_sdrc_actim_ctrl_a_0_val | ||
| 106 | ldr r4, [sp, #60] | ||
| 107 | str r4, omap_sdrc_actim_ctrl_b_0_val | ||
| 108 | ldr r4, [sp, #64] | ||
| 109 | str r4, omap_sdrc_mr_0_val | ||
| 110 | ldr r4, [sp, #68] | ||
| 111 | str r4, omap_sdrc_rfr_ctrl_1_val | ||
| 112 | cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, | ||
| 113 | beq skip_cs1_params @ do not use cs1 params | ||
| 114 | ldr r4, [sp, #72] | ||
| 115 | str r4, omap_sdrc_actim_ctrl_a_1_val | ||
| 116 | ldr r4, [sp, #76] | ||
| 117 | str r4, omap_sdrc_actim_ctrl_b_1_val | ||
| 118 | ldr r4, [sp, #80] | ||
| 119 | str r4, omap_sdrc_mr_1_val | ||
| 120 | skip_cs1_params: | ||
| 92 | dsb @ flush buffered writes to interconnect | 121 | dsb @ flush buffered writes to interconnect | 
| 93 | cmp r7, #1 @ if increasing SDRC clk rate, | 122 | |
| 123 | cmp r3, #1 @ if increasing SDRC clk rate, | ||
| 94 | bleq configure_sdrc @ program the SDRC regs early (for RFR) | 124 | bleq configure_sdrc @ program the SDRC regs early (for RFR) | 
| 95 | cmp r4, #SDRC_UNLOCK_DLL @ set the intended DLL state | 125 | cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state | 
| 96 | bleq unlock_dll | 126 | bleq unlock_dll | 
| 97 | blne lock_dll | 127 | blne lock_dll | 
| 98 | bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC | 128 | bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC | 
| 99 | bl configure_core_dpll @ change the DPLL3 M2 divider | 129 | bl configure_core_dpll @ change the DPLL3 M2 divider | 
| 130 | mov r12, r2 | ||
| 131 | bl wait_clk_stable @ wait for SDRC to stabilize | ||
| 100 | bl enable_sdrc @ take SDRC out of idle | 132 | bl enable_sdrc @ take SDRC out of idle | 
| 101 | cmp r4, #SDRC_UNLOCK_DLL @ wait for DLL status to change | 133 | cmp r1, #SDRC_UNLOCK_DLL @ wait for DLL status to change | 
| 102 | bleq wait_dll_unlock | 134 | bleq wait_dll_unlock | 
| 103 | blne wait_dll_lock | 135 | blne wait_dll_lock | 
| 104 | cmp r7, #1 @ if increasing SDRC clk rate, | 136 | cmp r3, #1 @ if increasing SDRC clk rate, | 
| 105 | beq return_to_sdram @ return to SDRAM code, otherwise, | 137 | beq return_to_sdram @ return to SDRAM code, otherwise, | 
| 106 | bl configure_sdrc @ reprogram SDRC regs now | 138 | bl configure_sdrc @ reprogram SDRC regs now | 
| 107 | mov r12, r5 | ||
| 108 | bl wait_clk_stable @ wait for SDRC to stabilize | ||
| 109 | return_to_sdram: | 139 | return_to_sdram: | 
| 110 | isb @ prevent speculative exec past here | 140 | isb @ prevent speculative exec past here | 
| 111 | mov r0, #0 @ return value | 141 | mov r0, #0 @ return value | 
| @@ -113,7 +143,7 @@ return_to_sdram: | |||
| 113 | unlock_dll: | 143 | unlock_dll: | 
| 114 | ldr r11, omap3_sdrc_dlla_ctrl | 144 | ldr r11, omap3_sdrc_dlla_ctrl | 
| 115 | ldr r12, [r11] | 145 | ldr r12, [r11] | 
| 116 | and r12, r12, #FIXEDDELAY_MASK | 146 | bic r12, r12, #FIXEDDELAY_MASK | 
| 117 | orr r12, r12, #FIXEDDELAY_DEFAULT | 147 | orr r12, r12, #FIXEDDELAY_DEFAULT | 
| 118 | orr r12, r12, #DLLIDLE_MASK | 148 | orr r12, r12, #DLLIDLE_MASK | 
| 119 | str r12, [r11] @ (no OCP barrier needed) | 149 | str r12, [r11] @ (no OCP barrier needed) | 
| @@ -129,7 +159,6 @@ sdram_in_selfrefresh: | |||
| 129 | ldr r12, [r11] @ read the contents of SDRC_POWER | 159 | ldr r12, [r11] @ read the contents of SDRC_POWER | 
| 130 | mov r9, r12 @ keep a copy of SDRC_POWER bits | 160 | mov r9, r12 @ keep a copy of SDRC_POWER bits | 
| 131 | orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle | 161 | orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle | 
| 132 | bic r12, r12, #PWDENA_MASK @ clear PWDENA | ||
| 133 | str r12, [r11] @ write back to SDRC_POWER register | 162 | str r12, [r11] @ write back to SDRC_POWER register | 
| 134 | ldr r12, [r11] @ posted-write barrier for SDRC | 163 | ldr r12, [r11] @ posted-write barrier for SDRC | 
| 135 | idle_sdrc: | 164 | idle_sdrc: | 
| @@ -149,7 +178,7 @@ configure_core_dpll: | |||
| 149 | ldr r12, [r11] | 178 | ldr r12, [r11] | 
| 150 | ldr r10, core_m2_mask_val @ modify m2 for core dpll | 179 | ldr r10, core_m2_mask_val @ modify m2 for core dpll | 
| 151 | and r12, r12, r10 | 180 | and r12, r12, r10 | 
| 152 | orr r12, r12, r3, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT | 181 | orr r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT | 
| 153 | str r12, [r11] | 182 | str r12, [r11] | 
| 154 | ldr r12, [r11] @ posted-write barrier for CM | 183 | ldr r12, [r11] @ posted-write barrier for CM | 
| 155 | bx lr | 184 | bx lr | 
| @@ -187,15 +216,34 @@ wait_dll_unlock: | |||
| 187 | bne wait_dll_unlock | 216 | bne wait_dll_unlock | 
| 188 | bx lr | 217 | bx lr | 
| 189 | configure_sdrc: | 218 | configure_sdrc: | 
| 190 | ldr r11, omap3_sdrc_rfr_ctrl | 219 | ldr r12, omap_sdrc_rfr_ctrl_0_val @ fetch value from SRAM | 
| 191 | str r0, [r11] | 220 | ldr r11, omap3_sdrc_rfr_ctrl_0 @ fetch addr from SRAM | 
| 192 | ldr r11, omap3_sdrc_actim_ctrla | 221 | str r12, [r11] @ store | 
| 193 | str r1, [r11] | 222 | ldr r12, omap_sdrc_actim_ctrl_a_0_val | 
| 194 | ldr r11, omap3_sdrc_actim_ctrlb | 223 | ldr r11, omap3_sdrc_actim_ctrl_a_0 | 
| 195 | str r2, [r11] | 224 | str r12, [r11] | 
| 225 | ldr r12, omap_sdrc_actim_ctrl_b_0_val | ||
| 226 | ldr r11, omap3_sdrc_actim_ctrl_b_0 | ||
| 227 | str r12, [r11] | ||
| 228 | ldr r12, omap_sdrc_mr_0_val | ||
| 196 | ldr r11, omap3_sdrc_mr_0 | 229 | ldr r11, omap3_sdrc_mr_0 | 
| 197 | str r6, [r11] | 230 | str r12, [r11] | 
| 198 | ldr r6, [r11] @ posted-write barrier for SDRC | 231 | ldr r12, omap_sdrc_rfr_ctrl_1_val | 
| 232 | cmp r12, #0 @ if SDRC_RFR_CTRL_1 is 0, | ||
| 233 | beq skip_cs1_prog @ do not program cs1 params | ||
| 234 | ldr r11, omap3_sdrc_rfr_ctrl_1 | ||
| 235 | str r12, [r11] | ||
| 236 | ldr r12, omap_sdrc_actim_ctrl_a_1_val | ||
| 237 | ldr r11, omap3_sdrc_actim_ctrl_a_1 | ||
| 238 | str r12, [r11] | ||
| 239 | ldr r12, omap_sdrc_actim_ctrl_b_1_val | ||
| 240 | ldr r11, omap3_sdrc_actim_ctrl_b_1 | ||
| 241 | str r12, [r11] | ||
| 242 | ldr r12, omap_sdrc_mr_1_val | ||
| 243 | ldr r11, omap3_sdrc_mr_1 | ||
| 244 | str r12, [r11] | ||
| 245 | skip_cs1_prog: | ||
| 246 | ldr r12, [r11] @ posted-write barrier for SDRC | ||
| 199 | bx lr | 247 | bx lr | 
| 200 | 248 | ||
| 201 | omap3_sdrc_power: | 249 | omap3_sdrc_power: | 
| @@ -206,14 +254,40 @@ omap3_cm_idlest1_core: | |||
| 206 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST) | 254 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST) | 
| 207 | omap3_cm_iclken1_core: | 255 | omap3_cm_iclken1_core: | 
| 208 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1) | 256 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1) | 
| 209 | omap3_sdrc_rfr_ctrl: | 257 | |
| 258 | omap3_sdrc_rfr_ctrl_0: | ||
| 210 | .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 259 | .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 
| 211 | omap3_sdrc_actim_ctrla: | 260 | omap3_sdrc_rfr_ctrl_1: | 
| 261 | .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1) | ||
| 262 | omap3_sdrc_actim_ctrl_a_0: | ||
| 212 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0) | 263 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0) | 
| 213 | omap3_sdrc_actim_ctrlb: | 264 | omap3_sdrc_actim_ctrl_a_1: | 
| 265 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1) | ||
| 266 | omap3_sdrc_actim_ctrl_b_0: | ||
| 214 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0) | 267 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0) | 
| 268 | omap3_sdrc_actim_ctrl_b_1: | ||
| 269 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1) | ||
| 215 | omap3_sdrc_mr_0: | 270 | omap3_sdrc_mr_0: | 
| 216 | .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0) | 271 | .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0) | 
| 272 | omap3_sdrc_mr_1: | ||
| 273 | .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1) | ||
| 274 | omap_sdrc_rfr_ctrl_0_val: | ||
| 275 | .word 0xDEADBEEF | ||
| 276 | omap_sdrc_rfr_ctrl_1_val: | ||
| 277 | .word 0xDEADBEEF | ||
| 278 | omap_sdrc_actim_ctrl_a_0_val: | ||
| 279 | .word 0xDEADBEEF | ||
| 280 | omap_sdrc_actim_ctrl_a_1_val: | ||
| 281 | .word 0xDEADBEEF | ||
| 282 | omap_sdrc_actim_ctrl_b_0_val: | ||
| 283 | .word 0xDEADBEEF | ||
| 284 | omap_sdrc_actim_ctrl_b_1_val: | ||
| 285 | .word 0xDEADBEEF | ||
| 286 | omap_sdrc_mr_0_val: | ||
| 287 | .word 0xDEADBEEF | ||
| 288 | omap_sdrc_mr_1_val: | ||
| 289 | .word 0xDEADBEEF | ||
| 290 | |||
| 217 | omap3_sdrc_dlla_status: | 291 | omap3_sdrc_dlla_status: | 
| 218 | .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) | 292 | .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) | 
| 219 | omap3_sdrc_dlla_ctrl: | 293 | omap3_sdrc_dlla_ctrl: | 
| @@ -223,3 +297,4 @@ core_m2_mask_val: | |||
| 223 | 297 | ||
| 224 | ENTRY(omap3_sram_configure_core_dpll_sz) | 298 | ENTRY(omap3_sram_configure_core_dpll_sz) | 
| 225 | .word . - omap3_sram_configure_core_dpll | 299 | .word . - omap3_sram_configure_core_dpll | 
| 300 | |||
| diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 7936085dd758..2e9b8ccd8ec2 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
| @@ -510,7 +510,7 @@ static struct db_chip db_chips[] __initdata = { | |||
| 510 | } | 510 | } | 
| 511 | }; | 511 | }; | 
| 512 | 512 | ||
| 513 | static void u300_init_check_chip(void) | 513 | static void __init u300_init_check_chip(void) | 
| 514 | { | 514 | { | 
| 515 | 515 | ||
| 516 | u16 val; | 516 | u16 val; | 
| diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 8277802ec859..3a7279c1ce5e 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
| @@ -120,6 +120,32 @@ void show_mem(void) | |||
| 120 | printk("%d pages swap cached\n", cached); | 120 | printk("%d pages swap cached\n", cached); | 
| 121 | } | 121 | } | 
| 122 | 122 | ||
| 123 | static void __init find_node_limits(int node, struct meminfo *mi, | ||
| 124 | unsigned long *min, unsigned long *max_low, unsigned long *max_high) | ||
| 125 | { | ||
| 126 | int i; | ||
| 127 | |||
| 128 | *min = -1UL; | ||
| 129 | *max_low = *max_high = 0; | ||
| 130 | |||
| 131 | for_each_nodebank(i, mi, node) { | ||
| 132 | struct membank *bank = &mi->bank[i]; | ||
| 133 | unsigned long start, end; | ||
| 134 | |||
| 135 | start = bank_pfn_start(bank); | ||
| 136 | end = bank_pfn_end(bank); | ||
| 137 | |||
| 138 | if (*min > start) | ||
| 139 | *min = start; | ||
| 140 | if (*max_high < end) | ||
| 141 | *max_high = end; | ||
| 142 | if (bank->highmem) | ||
| 143 | continue; | ||
| 144 | if (*max_low < end) | ||
| 145 | *max_low = end; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 123 | /* | 149 | /* | 
| 124 | * FIXME: We really want to avoid allocating the bootmap bitmap | 150 | * FIXME: We really want to avoid allocating the bootmap bitmap | 
| 125 | * over the top of the initrd. Hopefully, this is located towards | 151 | * over the top of the initrd. Hopefully, this is located towards | 
| @@ -210,41 +236,25 @@ static inline void map_memory_bank(struct membank *bank) | |||
| 210 | #endif | 236 | #endif | 
| 211 | } | 237 | } | 
| 212 | 238 | ||
| 213 | static unsigned long __init bootmem_init_node(int node, struct meminfo *mi) | 239 | static void __init bootmem_init_node(int node, struct meminfo *mi, | 
| 240 | unsigned long start_pfn, unsigned long end_pfn) | ||
| 214 | { | 241 | { | 
| 215 | unsigned long start_pfn, end_pfn, boot_pfn; | 242 | unsigned long boot_pfn; | 
| 216 | unsigned int boot_pages; | 243 | unsigned int boot_pages; | 
| 217 | pg_data_t *pgdat; | 244 | pg_data_t *pgdat; | 
| 218 | int i; | 245 | int i; | 
| 219 | 246 | ||
| 220 | start_pfn = -1UL; | ||
| 221 | end_pfn = 0; | ||
| 222 | |||
| 223 | /* | 247 | /* | 
| 224 | * Calculate the pfn range, and map the memory banks for this node. | 248 | * Map the memory banks for this node. | 
| 225 | */ | 249 | */ | 
| 226 | for_each_nodebank(i, mi, node) { | 250 | for_each_nodebank(i, mi, node) { | 
| 227 | struct membank *bank = &mi->bank[i]; | 251 | struct membank *bank = &mi->bank[i]; | 
| 228 | unsigned long start, end; | ||
| 229 | 252 | ||
| 230 | start = bank_pfn_start(bank); | 253 | if (!bank->highmem) | 
| 231 | end = bank_pfn_end(bank); | 254 | map_memory_bank(bank); | 
| 232 | |||
| 233 | if (start_pfn > start) | ||
| 234 | start_pfn = start; | ||
| 235 | if (end_pfn < end) | ||
| 236 | end_pfn = end; | ||
| 237 | |||
| 238 | map_memory_bank(bank); | ||
| 239 | } | 255 | } | 
| 240 | 256 | ||
| 241 | /* | 257 | /* | 
| 242 | * If there is no memory in this node, ignore it. | ||
| 243 | */ | ||
| 244 | if (end_pfn == 0) | ||
| 245 | return end_pfn; | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Allocate the bootmem bitmap page. | 258 | * Allocate the bootmem bitmap page. | 
| 249 | */ | 259 | */ | 
| 250 | boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn); | 260 | boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn); | 
| @@ -260,7 +270,8 @@ static unsigned long __init bootmem_init_node(int node, struct meminfo *mi) | |||
| 260 | 270 | ||
| 261 | for_each_nodebank(i, mi, node) { | 271 | for_each_nodebank(i, mi, node) { | 
| 262 | struct membank *bank = &mi->bank[i]; | 272 | struct membank *bank = &mi->bank[i]; | 
| 263 | free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank)); | 273 | if (!bank->highmem) | 
| 274 | free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank)); | ||
| 264 | memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank)); | 275 | memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank)); | 
| 265 | } | 276 | } | 
| 266 | 277 | ||
| @@ -269,8 +280,6 @@ static unsigned long __init bootmem_init_node(int node, struct meminfo *mi) | |||
| 269 | */ | 280 | */ | 
| 270 | reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT, | 281 | reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT, | 
| 271 | boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); | 282 | boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); | 
| 272 | |||
| 273 | return end_pfn; | ||
| 274 | } | 283 | } | 
| 275 | 284 | ||
| 276 | static void __init bootmem_reserve_initrd(int node) | 285 | static void __init bootmem_reserve_initrd(int node) | 
| @@ -297,33 +306,39 @@ static void __init bootmem_reserve_initrd(int node) | |||
| 297 | static void __init bootmem_free_node(int node, struct meminfo *mi) | 306 | static void __init bootmem_free_node(int node, struct meminfo *mi) | 
| 298 | { | 307 | { | 
| 299 | unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; | 308 | unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; | 
| 300 | unsigned long start_pfn, end_pfn; | 309 | unsigned long min, max_low, max_high; | 
| 301 | pg_data_t *pgdat = NODE_DATA(node); | ||
| 302 | int i; | 310 | int i; | 
| 303 | 311 | ||
| 304 | start_pfn = pgdat->bdata->node_min_pfn; | 312 | find_node_limits(node, mi, &min, &max_low, &max_high); | 
| 305 | end_pfn = pgdat->bdata->node_low_pfn; | ||
| 306 | 313 | ||
| 307 | /* | 314 | /* | 
| 308 | * initialise the zones within this node. | 315 | * initialise the zones within this node. | 
| 309 | */ | 316 | */ | 
| 310 | memset(zone_size, 0, sizeof(zone_size)); | 317 | memset(zone_size, 0, sizeof(zone_size)); | 
| 311 | memset(zhole_size, 0, sizeof(zhole_size)); | ||
| 312 | 318 | ||
| 313 | /* | 319 | /* | 
| 314 | * The size of this node has already been determined. If we need | 320 | * The size of this node has already been determined. If we need | 
| 315 | * to do anything fancy with the allocation of this memory to the | 321 | * to do anything fancy with the allocation of this memory to the | 
| 316 | * zones, now is the time to do it. | 322 | * zones, now is the time to do it. | 
| 317 | */ | 323 | */ | 
| 318 | zone_size[0] = end_pfn - start_pfn; | 324 | zone_size[0] = max_low - min; | 
| 325 | #ifdef CONFIG_HIGHMEM | ||
| 326 | zone_size[ZONE_HIGHMEM] = max_high - max_low; | ||
| 327 | #endif | ||
| 319 | 328 | ||
| 320 | /* | 329 | /* | 
| 321 | * For each bank in this node, calculate the size of the holes. | 330 | * For each bank in this node, calculate the size of the holes. | 
| 322 | * holes = node_size - sum(bank_sizes_in_node) | 331 | * holes = node_size - sum(bank_sizes_in_node) | 
| 323 | */ | 332 | */ | 
| 324 | zhole_size[0] = zone_size[0]; | 333 | memcpy(zhole_size, zone_size, sizeof(zhole_size)); | 
| 325 | for_each_nodebank(i, mi, node) | 334 | for_each_nodebank(i, mi, node) { | 
| 326 | zhole_size[0] -= bank_pfn_size(&mi->bank[i]); | 335 | int idx = 0; | 
| 336 | #ifdef CONFIG_HIGHMEM | ||
| 337 | if (mi->bank[i].highmem) | ||
| 338 | idx = ZONE_HIGHMEM; | ||
| 339 | #endif | ||
| 340 | zhole_size[idx] -= bank_pfn_size(&mi->bank[i]); | ||
| 341 | } | ||
| 327 | 342 | ||
| 328 | /* | 343 | /* | 
| 329 | * Adjust the sizes according to any special requirements for | 344 | * Adjust the sizes according to any special requirements for | 
| @@ -331,13 +346,13 @@ static void __init bootmem_free_node(int node, struct meminfo *mi) | |||
| 331 | */ | 346 | */ | 
| 332 | arch_adjust_zones(node, zone_size, zhole_size); | 347 | arch_adjust_zones(node, zone_size, zhole_size); | 
| 333 | 348 | ||
| 334 | free_area_init_node(node, zone_size, start_pfn, zhole_size); | 349 | free_area_init_node(node, zone_size, min, zhole_size); | 
| 335 | } | 350 | } | 
| 336 | 351 | ||
| 337 | void __init bootmem_init(void) | 352 | void __init bootmem_init(void) | 
| 338 | { | 353 | { | 
| 339 | struct meminfo *mi = &meminfo; | 354 | struct meminfo *mi = &meminfo; | 
| 340 | unsigned long memend_pfn = 0; | 355 | unsigned long min, max_low, max_high; | 
| 341 | int node, initrd_node; | 356 | int node, initrd_node; | 
| 342 | 357 | ||
| 343 | /* | 358 | /* | 
| @@ -345,11 +360,29 @@ void __init bootmem_init(void) | |||
| 345 | */ | 360 | */ | 
| 346 | initrd_node = check_initrd(mi); | 361 | initrd_node = check_initrd(mi); | 
| 347 | 362 | ||
| 363 | max_low = max_high = 0; | ||
| 364 | |||
| 348 | /* | 365 | /* | 
| 349 | * Run through each node initialising the bootmem allocator. | 366 | * Run through each node initialising the bootmem allocator. | 
| 350 | */ | 367 | */ | 
| 351 | for_each_node(node) { | 368 | for_each_node(node) { | 
| 352 | unsigned long end_pfn = bootmem_init_node(node, mi); | 369 | unsigned long node_low, node_high; | 
| 370 | |||
| 371 | find_node_limits(node, mi, &min, &node_low, &node_high); | ||
| 372 | |||
| 373 | if (node_low > max_low) | ||
| 374 | max_low = node_low; | ||
| 375 | if (node_high > max_high) | ||
| 376 | max_high = node_high; | ||
| 377 | |||
| 378 | /* | ||
| 379 | * If there is no memory in this node, ignore it. | ||
| 380 | * (We can't have nodes which have no lowmem) | ||
| 381 | */ | ||
| 382 | if (node_low == 0) | ||
| 383 | continue; | ||
| 384 | |||
| 385 | bootmem_init_node(node, mi, min, node_low); | ||
| 353 | 386 | ||
| 354 | /* | 387 | /* | 
| 355 | * Reserve any special node zero regions. | 388 | * Reserve any special node zero regions. | 
| @@ -362,12 +395,6 @@ void __init bootmem_init(void) | |||
| 362 | */ | 395 | */ | 
| 363 | if (node == initrd_node) | 396 | if (node == initrd_node) | 
| 364 | bootmem_reserve_initrd(node); | 397 | bootmem_reserve_initrd(node); | 
| 365 | |||
| 366 | /* | ||
| 367 | * Remember the highest memory PFN. | ||
| 368 | */ | ||
| 369 | if (end_pfn > memend_pfn) | ||
| 370 | memend_pfn = end_pfn; | ||
| 371 | } | 398 | } | 
| 372 | 399 | ||
| 373 | /* | 400 | /* | 
| @@ -383,7 +410,7 @@ void __init bootmem_init(void) | |||
| 383 | for_each_node(node) | 410 | for_each_node(node) | 
| 384 | bootmem_free_node(node, mi); | 411 | bootmem_free_node(node, mi); | 
| 385 | 412 | ||
| 386 | high_memory = __va((memend_pfn << PAGE_SHIFT) - 1) + 1; | 413 | high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1; | 
| 387 | 414 | ||
| 388 | /* | 415 | /* | 
| 389 | * This doesn't seem to be used by the Linux memory manager any | 416 | * This doesn't seem to be used by the Linux memory manager any | 
| @@ -393,7 +420,8 @@ void __init bootmem_init(void) | |||
| 393 | * Note: max_low_pfn and max_pfn reflect the number of _pages_ in | 420 | * Note: max_low_pfn and max_pfn reflect the number of _pages_ in | 
| 394 | * the system, not the maximum PFN. | 421 | * the system, not the maximum PFN. | 
| 395 | */ | 422 | */ | 
| 396 | max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET; | 423 | max_low_pfn = max_low - PHYS_PFN_OFFSET; | 
| 424 | max_pfn = max_high - PHYS_PFN_OFFSET; | ||
| 397 | } | 425 | } | 
| 398 | 426 | ||
| 399 | static inline int free_area(unsigned long pfn, unsigned long end, char *s) | 427 | static inline int free_area(unsigned long pfn, unsigned long end, char *s) | 
| diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4722582b17b8..4426ee67ceca 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
| @@ -687,13 +687,19 @@ __early_param("vmalloc=", early_vmalloc); | |||
| 687 | 687 | ||
| 688 | static void __init sanity_check_meminfo(void) | 688 | static void __init sanity_check_meminfo(void) | 
| 689 | { | 689 | { | 
| 690 | int i, j; | 690 | int i, j, highmem = 0; | 
| 691 | 691 | ||
| 692 | for (i = 0, j = 0; i < meminfo.nr_banks; i++) { | 692 | for (i = 0, j = 0; i < meminfo.nr_banks; i++) { | 
| 693 | struct membank *bank = &meminfo.bank[j]; | 693 | struct membank *bank = &meminfo.bank[j]; | 
| 694 | *bank = meminfo.bank[i]; | 694 | *bank = meminfo.bank[i]; | 
| 695 | 695 | ||
| 696 | #ifdef CONFIG_HIGHMEM | 696 | #ifdef CONFIG_HIGHMEM | 
| 697 | if (__va(bank->start) > VMALLOC_MIN || | ||
| 698 | __va(bank->start) < (void *)PAGE_OFFSET) | ||
| 699 | highmem = 1; | ||
| 700 | |||
| 701 | bank->highmem = highmem; | ||
| 702 | |||
| 697 | /* | 703 | /* | 
| 698 | * Split those memory banks which are partially overlapping | 704 | * Split those memory banks which are partially overlapping | 
| 699 | * the vmalloc area greatly simplifying things later. | 705 | * the vmalloc area greatly simplifying things later. | 
| @@ -714,6 +720,7 @@ static void __init sanity_check_meminfo(void) | |||
| 714 | i++; | 720 | i++; | 
| 715 | bank[1].size -= VMALLOC_MIN - __va(bank->start); | 721 | bank[1].size -= VMALLOC_MIN - __va(bank->start); | 
| 716 | bank[1].start = __pa(VMALLOC_MIN - 1) + 1; | 722 | bank[1].start = __pa(VMALLOC_MIN - 1) + 1; | 
| 723 | bank[1].highmem = highmem = 1; | ||
| 717 | j++; | 724 | j++; | 
| 718 | } | 725 | } | 
| 719 | bank->size = VMALLOC_MIN - __va(bank->start); | 726 | bank->size = VMALLOC_MIN - __va(bank->start); | 
| diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index 843e8af64066..1868c0d8f9b5 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c | |||
| @@ -78,10 +78,10 @@ static int omap_target(struct cpufreq_policy *policy, | |||
| 78 | 78 | ||
| 79 | /* Ensure desired rate is within allowed range. Some govenors | 79 | /* Ensure desired rate is within allowed range. Some govenors | 
| 80 | * (ondemand) will just pass target_freq=0 to get the minimum. */ | 80 | * (ondemand) will just pass target_freq=0 to get the minimum. */ | 
| 81 | if (target_freq < policy->cpuinfo.min_freq) | 81 | if (target_freq < policy->min) | 
| 82 | target_freq = policy->cpuinfo.min_freq; | 82 | target_freq = policy->min; | 
| 83 | if (target_freq > policy->cpuinfo.max_freq) | 83 | if (target_freq > policy->max) | 
| 84 | target_freq = policy->cpuinfo.max_freq; | 84 | target_freq = policy->max; | 
| 85 | 85 | ||
| 86 | freqs.old = omap_getspeed(0); | 86 | freqs.old = omap_getspeed(0); | 
| 87 | freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | 87 | freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | 
| diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 7677a4a1cef2..e3ac94f09006 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
| @@ -946,7 +946,9 @@ void omap_start_dma(int lch) | |||
| 946 | 946 | ||
| 947 | cur_lch = next_lch; | 947 | cur_lch = next_lch; | 
| 948 | } while (next_lch != -1); | 948 | } while (next_lch != -1); | 
| 949 | } else if (cpu_class_is_omap2()) { | 949 | } else if (cpu_is_omap242x() || | 
| 950 | (cpu_is_omap243x() && omap_type() <= OMAP2430_REV_ES1_0)) { | ||
| 951 | |||
| 950 | /* Errata: Need to write lch even if not using chaining */ | 952 | /* Errata: Need to write lch even if not using chaining */ | 
| 951 | dma_write(lch, CLNK_CTRL(lch)); | 953 | dma_write(lch, CLNK_CTRL(lch)); | 
| 952 | } | 954 | } | 
| diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 26b387c12423..9298bc0ab171 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
| @@ -476,14 +476,12 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | |||
| 476 | __raw_writel(l, reg); | 476 | __raw_writel(l, reg); | 
| 477 | } | 477 | } | 
| 478 | 478 | ||
| 479 | static int __omap_get_gpio_datain(int gpio) | 479 | static int _get_gpio_datain(struct gpio_bank *bank, int gpio) | 
| 480 | { | 480 | { | 
| 481 | struct gpio_bank *bank; | ||
| 482 | void __iomem *reg; | 481 | void __iomem *reg; | 
| 483 | 482 | ||
| 484 | if (check_gpio(gpio) < 0) | 483 | if (check_gpio(gpio) < 0) | 
| 485 | return -EINVAL; | 484 | return -EINVAL; | 
| 486 | bank = get_gpio_bank(gpio); | ||
| 487 | reg = bank->base; | 485 | reg = bank->base; | 
| 488 | switch (bank->method) { | 486 | switch (bank->method) { | 
| 489 | #ifdef CONFIG_ARCH_OMAP1 | 487 | #ifdef CONFIG_ARCH_OMAP1 | 
| @@ -524,6 +522,53 @@ static int __omap_get_gpio_datain(int gpio) | |||
| 524 | & (1 << get_gpio_index(gpio))) != 0; | 522 | & (1 << get_gpio_index(gpio))) != 0; | 
| 525 | } | 523 | } | 
| 526 | 524 | ||
| 525 | static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | ||
| 526 | { | ||
| 527 | void __iomem *reg; | ||
| 528 | |||
| 529 | if (check_gpio(gpio) < 0) | ||
| 530 | return -EINVAL; | ||
| 531 | reg = bank->base; | ||
| 532 | |||
| 533 | switch (bank->method) { | ||
| 534 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 535 | case METHOD_MPUIO: | ||
| 536 | reg += OMAP_MPUIO_OUTPUT; | ||
| 537 | break; | ||
| 538 | #endif | ||
| 539 | #ifdef CONFIG_ARCH_OMAP15XX | ||
| 540 | case METHOD_GPIO_1510: | ||
| 541 | reg += OMAP1510_GPIO_DATA_OUTPUT; | ||
| 542 | break; | ||
| 543 | #endif | ||
| 544 | #ifdef CONFIG_ARCH_OMAP16XX | ||
| 545 | case METHOD_GPIO_1610: | ||
| 546 | reg += OMAP1610_GPIO_DATAOUT; | ||
| 547 | break; | ||
| 548 | #endif | ||
| 549 | #ifdef CONFIG_ARCH_OMAP730 | ||
| 550 | case METHOD_GPIO_730: | ||
| 551 | reg += OMAP730_GPIO_DATA_OUTPUT; | ||
| 552 | break; | ||
| 553 | #endif | ||
| 554 | #ifdef CONFIG_ARCH_OMAP850 | ||
| 555 | case METHOD_GPIO_850: | ||
| 556 | reg += OMAP850_GPIO_DATA_OUTPUT; | ||
| 557 | break; | ||
| 558 | #endif | ||
| 559 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | ||
| 560 | defined(CONFIG_ARCH_OMAP4) | ||
| 561 | case METHOD_GPIO_24XX: | ||
| 562 | reg += OMAP24XX_GPIO_DATAOUT; | ||
| 563 | break; | ||
| 564 | #endif | ||
| 565 | default: | ||
| 566 | return -EINVAL; | ||
| 567 | } | ||
| 568 | |||
| 569 | return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; | ||
| 570 | } | ||
| 571 | |||
| 527 | #define MOD_REG_BIT(reg, bit_mask, set) \ | 572 | #define MOD_REG_BIT(reg, bit_mask, set) \ | 
| 528 | do { \ | 573 | do { \ | 
| 529 | int l = __raw_readl(base + reg); \ | 574 | int l = __raw_readl(base + reg); \ | 
| @@ -1189,6 +1234,7 @@ static void gpio_mask_irq(unsigned int irq) | |||
| 1189 | struct gpio_bank *bank = get_irq_chip_data(irq); | 1234 | struct gpio_bank *bank = get_irq_chip_data(irq); | 
| 1190 | 1235 | ||
| 1191 | _set_gpio_irqenable(bank, gpio, 0); | 1236 | _set_gpio_irqenable(bank, gpio, 0); | 
| 1237 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); | ||
| 1192 | } | 1238 | } | 
| 1193 | 1239 | ||
| 1194 | static void gpio_unmask_irq(unsigned int irq) | 1240 | static void gpio_unmask_irq(unsigned int irq) | 
| @@ -1196,6 +1242,11 @@ static void gpio_unmask_irq(unsigned int irq) | |||
| 1196 | unsigned int gpio = irq - IH_GPIO_BASE; | 1242 | unsigned int gpio = irq - IH_GPIO_BASE; | 
| 1197 | struct gpio_bank *bank = get_irq_chip_data(irq); | 1243 | struct gpio_bank *bank = get_irq_chip_data(irq); | 
| 1198 | unsigned int irq_mask = 1 << get_gpio_index(gpio); | 1244 | unsigned int irq_mask = 1 << get_gpio_index(gpio); | 
| 1245 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 1246 | u32 trigger = desc->status & IRQ_TYPE_SENSE_MASK; | ||
| 1247 | |||
| 1248 | if (trigger) | ||
| 1249 | _set_gpio_triggering(bank, get_gpio_index(gpio), trigger); | ||
| 1199 | 1250 | ||
| 1200 | /* For level-triggered GPIOs, the clearing must be done after | 1251 | /* For level-triggered GPIOs, the clearing must be done after | 
| 1201 | * the HW source is cleared, thus after the handler has run */ | 1252 | * the HW source is cleared, thus after the handler has run */ | 
| @@ -1350,9 +1401,49 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) | |||
| 1350 | return 0; | 1401 | return 0; | 
| 1351 | } | 1402 | } | 
| 1352 | 1403 | ||
| 1404 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
| 1405 | { | ||
| 1406 | void __iomem *reg = bank->base; | ||
| 1407 | |||
| 1408 | switch (bank->method) { | ||
| 1409 | case METHOD_MPUIO: | ||
| 1410 | reg += OMAP_MPUIO_IO_CNTL; | ||
| 1411 | break; | ||
| 1412 | case METHOD_GPIO_1510: | ||
| 1413 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
| 1414 | break; | ||
| 1415 | case METHOD_GPIO_1610: | ||
| 1416 | reg += OMAP1610_GPIO_DIRECTION; | ||
| 1417 | break; | ||
| 1418 | case METHOD_GPIO_730: | ||
| 1419 | reg += OMAP730_GPIO_DIR_CONTROL; | ||
| 1420 | break; | ||
| 1421 | case METHOD_GPIO_850: | ||
| 1422 | reg += OMAP850_GPIO_DIR_CONTROL; | ||
| 1423 | break; | ||
| 1424 | case METHOD_GPIO_24XX: | ||
| 1425 | reg += OMAP24XX_GPIO_OE; | ||
| 1426 | break; | ||
| 1427 | } | ||
| 1428 | return __raw_readl(reg) & mask; | ||
| 1429 | } | ||
| 1430 | |||
| 1353 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | 1431 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | 
| 1354 | { | 1432 | { | 
| 1355 | return __omap_get_gpio_datain(chip->base + offset); | 1433 | struct gpio_bank *bank; | 
| 1434 | void __iomem *reg; | ||
| 1435 | int gpio; | ||
| 1436 | u32 mask; | ||
| 1437 | |||
| 1438 | gpio = chip->base + offset; | ||
| 1439 | bank = get_gpio_bank(gpio); | ||
| 1440 | reg = bank->base; | ||
| 1441 | mask = 1 << get_gpio_index(gpio); | ||
| 1442 | |||
| 1443 | if (gpio_is_input(bank, mask)) | ||
| 1444 | return _get_gpio_datain(bank, gpio); | ||
| 1445 | else | ||
| 1446 | return _get_gpio_dataout(bank, gpio); | ||
| 1356 | } | 1447 | } | 
| 1357 | 1448 | ||
| 1358 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | 1449 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | 
| @@ -1886,34 +1977,6 @@ arch_initcall(omap_gpio_sysinit); | |||
| 1886 | #include <linux/debugfs.h> | 1977 | #include <linux/debugfs.h> | 
| 1887 | #include <linux/seq_file.h> | 1978 | #include <linux/seq_file.h> | 
| 1888 | 1979 | ||
| 1889 | static int gpio_is_input(struct gpio_bank *bank, int mask) | ||
| 1890 | { | ||
| 1891 | void __iomem *reg = bank->base; | ||
| 1892 | |||
| 1893 | switch (bank->method) { | ||
| 1894 | case METHOD_MPUIO: | ||
| 1895 | reg += OMAP_MPUIO_IO_CNTL; | ||
| 1896 | break; | ||
| 1897 | case METHOD_GPIO_1510: | ||
| 1898 | reg += OMAP1510_GPIO_DIR_CONTROL; | ||
| 1899 | break; | ||
| 1900 | case METHOD_GPIO_1610: | ||
| 1901 | reg += OMAP1610_GPIO_DIRECTION; | ||
| 1902 | break; | ||
| 1903 | case METHOD_GPIO_730: | ||
| 1904 | reg += OMAP730_GPIO_DIR_CONTROL; | ||
| 1905 | break; | ||
| 1906 | case METHOD_GPIO_850: | ||
| 1907 | reg += OMAP850_GPIO_DIR_CONTROL; | ||
| 1908 | break; | ||
| 1909 | case METHOD_GPIO_24XX: | ||
| 1910 | reg += OMAP24XX_GPIO_OE; | ||
| 1911 | break; | ||
| 1912 | } | ||
| 1913 | return __raw_readl(reg) & mask; | ||
| 1914 | } | ||
| 1915 | |||
| 1916 | |||
| 1917 | static int dbg_gpio_show(struct seq_file *s, void *unused) | 1980 | static int dbg_gpio_show(struct seq_file *s, void *unused) | 
| 1918 | { | 1981 | { | 
| 1919 | unsigned i, j, gpio; | 1982 | unsigned i, j, gpio; | 
| diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h index f9f65e1ba3f1..4b8b0d65cbf2 100644 --- a/arch/arm/plat-omap/include/mach/clock.h +++ b/arch/arm/plat-omap/include/mach/clock.h | |||
| @@ -20,6 +20,8 @@ struct clockdomain; | |||
| 20 | struct clkops { | 20 | struct clkops { | 
| 21 | int (*enable)(struct clk *); | 21 | int (*enable)(struct clk *); | 
| 22 | void (*disable)(struct clk *); | 22 | void (*disable)(struct clk *); | 
| 23 | void (*find_idlest)(struct clk *, void __iomem **, u8 *); | ||
| 24 | void (*find_companion)(struct clk *, void __iomem **, u8 *); | ||
| 23 | }; | 25 | }; | 
| 24 | 26 | ||
| 25 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \ | 27 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \ | 
| diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h index 285eaa3a8275..11e73d9e8928 100644 --- a/arch/arm/plat-omap/include/mach/cpu.h +++ b/arch/arm/plat-omap/include/mach/cpu.h | |||
| @@ -378,9 +378,6 @@ IS_OMAP_TYPE(3430, 0x3430) | |||
| 378 | #define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx() || \ | 378 | #define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx() || \ | 
| 379 | cpu_is_omap44xx()) | 379 | cpu_is_omap44xx()) | 
| 380 | 380 | ||
| 381 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \ | ||
| 382 | defined(CONFIG_ARCH_OMAP4) | ||
| 383 | |||
| 384 | /* Various silicon revisions for omap2 */ | 381 | /* Various silicon revisions for omap2 */ | 
| 385 | #define OMAP242X_CLASS 0x24200024 | 382 | #define OMAP242X_CLASS 0x24200024 | 
| 386 | #define OMAP2420_REV_ES1_0 0x24200024 | 383 | #define OMAP2420_REV_ES1_0 0x24200024 | 
| @@ -436,5 +433,3 @@ IS_OMAP_TYPE(3430, 0x3430) | |||
| 436 | 433 | ||
| 437 | int omap_chip_is(struct omap_chip_id oci); | 434 | int omap_chip_is(struct omap_chip_id oci); | 
| 438 | void omap2_check_revision(void); | 435 | void omap2_check_revision(void); | 
| 439 | |||
| 440 | #endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */ | ||
| diff --git a/arch/arm/plat-omap/include/mach/io.h b/arch/arm/plat-omap/include/mach/io.h index 73f483d56ca6..21fb0efdda86 100644 --- a/arch/arm/plat-omap/include/mach/io.h +++ b/arch/arm/plat-omap/include/mach/io.h | |||
| @@ -228,7 +228,8 @@ extern void omap1_map_common_io(void); | |||
| 228 | extern void omap1_init_common_hw(void); | 228 | extern void omap1_init_common_hw(void); | 
| 229 | 229 | ||
| 230 | extern void omap2_map_common_io(void); | 230 | extern void omap2_map_common_io(void); | 
| 231 | extern void omap2_init_common_hw(struct omap_sdrc_params *sp); | 231 | extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, | 
| 232 | struct omap_sdrc_params *sdrc_cs1); | ||
| 232 | 233 | ||
| 233 | #define __arch_ioremap(p,s,t) omap_ioremap(p,s,t) | 234 | #define __arch_ioremap(p,s,t) omap_ioremap(p,s,t) | 
| 234 | #define __arch_iounmap(v) omap_iounmap(v) | 235 | #define __arch_iounmap(v) omap_iounmap(v) | 
| diff --git a/arch/arm/plat-omap/include/mach/mux.h b/arch/arm/plat-omap/include/mach/mux.h index 85a621705766..80281c458baf 100644 --- a/arch/arm/plat-omap/include/mach/mux.h +++ b/arch/arm/plat-omap/include/mach/mux.h | |||
| @@ -853,6 +853,10 @@ enum omap34xx_index { | |||
| 853 | AE5_34XX_GPIO143, | 853 | AE5_34XX_GPIO143, | 
| 854 | H19_34XX_GPIO164_OUT, | 854 | H19_34XX_GPIO164_OUT, | 
| 855 | J25_34XX_GPIO170, | 855 | J25_34XX_GPIO170, | 
| 856 | |||
| 857 | /* OMAP3 SDRC CKE signals to SDR/DDR ram chips */ | ||
| 858 | H16_34XX_SDRC_CKE0, | ||
| 859 | H17_34XX_SDRC_CKE1, | ||
| 856 | }; | 860 | }; | 
| 857 | 861 | ||
| 858 | struct omap_mux_cfg { | 862 | struct omap_mux_cfg { | 
| diff --git a/arch/arm/plat-omap/include/mach/prcm.h b/arch/arm/plat-omap/include/mach/prcm.h index 24ac3c715912..cda2a70397b4 100644 --- a/arch/arm/plat-omap/include/mach/prcm.h +++ b/arch/arm/plat-omap/include/mach/prcm.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | u32 omap_prcm_get_reset_sources(void); | 26 | u32 omap_prcm_get_reset_sources(void); | 
| 27 | void omap_prcm_arch_reset(char mode); | 27 | void omap_prcm_arch_reset(char mode); | 
| 28 | int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name); | ||
| 28 | 29 | ||
| 29 | #endif | 30 | #endif | 
| 30 | 31 | ||
| diff --git a/arch/arm/plat-omap/include/mach/sdrc.h b/arch/arm/plat-omap/include/mach/sdrc.h index adc73522491f..0be18e4ff182 100644 --- a/arch/arm/plat-omap/include/mach/sdrc.h +++ b/arch/arm/plat-omap/include/mach/sdrc.h | |||
| @@ -30,6 +30,10 @@ | |||
| 30 | #define SDRC_ACTIM_CTRL_A_0 0x09c | 30 | #define SDRC_ACTIM_CTRL_A_0 0x09c | 
| 31 | #define SDRC_ACTIM_CTRL_B_0 0x0a0 | 31 | #define SDRC_ACTIM_CTRL_B_0 0x0a0 | 
| 32 | #define SDRC_RFR_CTRL_0 0x0a4 | 32 | #define SDRC_RFR_CTRL_0 0x0a4 | 
| 33 | #define SDRC_MR_1 0x0B4 | ||
| 34 | #define SDRC_ACTIM_CTRL_A_1 0x0C4 | ||
| 35 | #define SDRC_ACTIM_CTRL_B_1 0x0C8 | ||
| 36 | #define SDRC_RFR_CTRL_1 0x0D4 | ||
| 33 | 37 | ||
| 34 | /* | 38 | /* | 
| 35 | * These values represent the number of memory clock cycles between | 39 | * These values represent the number of memory clock cycles between | 
| @@ -102,8 +106,11 @@ struct omap_sdrc_params { | |||
| 102 | u32 mr; | 106 | u32 mr; | 
| 103 | }; | 107 | }; | 
| 104 | 108 | ||
| 105 | void __init omap2_sdrc_init(struct omap_sdrc_params *sp); | 109 | void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, | 
| 106 | struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r); | 110 | struct omap_sdrc_params *sdrc_cs1); | 
| 111 | int omap2_sdrc_get_params(unsigned long r, | ||
| 112 | struct omap_sdrc_params **sdrc_cs0, | ||
| 113 | struct omap_sdrc_params **sdrc_cs1); | ||
| 107 | 114 | ||
| 108 | #ifdef CONFIG_ARCH_OMAP2 | 115 | #ifdef CONFIG_ARCH_OMAP2 | 
| 109 | 116 | ||
| diff --git a/arch/arm/plat-omap/include/mach/serial.h b/arch/arm/plat-omap/include/mach/serial.h index 13abd02d1527..def0529c75eb 100644 --- a/arch/arm/plat-omap/include/mach/serial.h +++ b/arch/arm/plat-omap/include/mach/serial.h | |||
| @@ -59,6 +59,7 @@ extern void omap_uart_check_wakeup(void); | |||
| 59 | extern void omap_uart_prepare_suspend(void); | 59 | extern void omap_uart_prepare_suspend(void); | 
| 60 | extern void omap_uart_prepare_idle(int num); | 60 | extern void omap_uart_prepare_idle(int num); | 
| 61 | extern void omap_uart_resume_idle(int num); | 61 | extern void omap_uart_resume_idle(int num); | 
| 62 | extern void omap_uart_enable_irqs(int enable); | ||
| 62 | #endif | 63 | #endif | 
| 63 | 64 | ||
| 64 | #endif | 65 | #endif | 
| diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h index 4d53cc59d7a3..8974e3fc2691 100644 --- a/arch/arm/plat-omap/include/mach/sram.h +++ b/arch/arm/plat-omap/include/mach/sram.h | |||
| @@ -21,11 +21,12 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, | |||
| 21 | u32 mem_type); | 21 | u32 mem_type); | 
| 22 | extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); | 22 | extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); | 
| 23 | 23 | ||
| 24 | extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, | 24 | extern u32 omap3_configure_core_dpll( | 
| 25 | u32 sdrc_actim_ctrla, | 25 | u32 m2, u32 unlock_dll, u32 f, u32 inc, | 
| 26 | u32 sdrc_actim_ctrlb, u32 m2, | 26 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | 
| 27 | u32 unlock_dll, u32 f, u32 sdrc_mr, | 27 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | 
| 28 | u32 inc); | 28 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | 
| 29 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); | ||
| 29 | 30 | ||
| 30 | /* Do not use these */ | 31 | /* Do not use these */ | 
| 31 | extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); | 32 | extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); | 
| @@ -59,12 +60,12 @@ extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, | |||
| 59 | u32 mem_type); | 60 | u32 mem_type); | 
| 60 | extern unsigned long omap243x_sram_reprogram_sdrc_sz; | 61 | extern unsigned long omap243x_sram_reprogram_sdrc_sz; | 
| 61 | 62 | ||
| 62 | 63 | extern u32 omap3_sram_configure_core_dpll( | |
| 63 | extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl, | 64 | u32 m2, u32 unlock_dll, u32 f, u32 inc, | 
| 64 | u32 sdrc_actim_ctrla, | 65 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | 
| 65 | u32 sdrc_actim_ctrlb, u32 m2, | 66 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | 
| 66 | u32 unlock_dll, u32 f, u32 sdrc_mr, | 67 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | 
| 67 | u32 inc); | 68 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); | 
| 68 | extern unsigned long omap3_sram_configure_core_dpll_sz; | 69 | extern unsigned long omap3_sram_configure_core_dpll_sz; | 
| 69 | 70 | ||
| 70 | #endif | 71 | #endif | 
| diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 4ea73804d21e..5eae7876979c 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
| @@ -44,9 +44,9 @@ | |||
| 44 | #define OMAP2_SRAM_VA 0xe3000000 | 44 | #define OMAP2_SRAM_VA 0xe3000000 | 
| 45 | #define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800) | 45 | #define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800) | 
| 46 | #define OMAP3_SRAM_PA 0x40200000 | 46 | #define OMAP3_SRAM_PA 0x40200000 | 
| 47 | #define OMAP3_SRAM_VA 0xd7000000 | 47 | #define OMAP3_SRAM_VA 0xe3000000 | 
| 48 | #define OMAP3_SRAM_PUB_PA 0x40208000 | 48 | #define OMAP3_SRAM_PUB_PA 0x40208000 | 
| 49 | #define OMAP3_SRAM_PUB_VA 0xd7008000 | 49 | #define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000) | 
| 50 | #define OMAP4_SRAM_PA 0x40200000 /*0x402f0000*/ | 50 | #define OMAP4_SRAM_PA 0x40200000 /*0x402f0000*/ | 
| 51 | #define OMAP4_SRAM_VA 0xd7000000 /*0xd70f0000*/ | 51 | #define OMAP4_SRAM_VA 0xd7000000 /*0xd70f0000*/ | 
| 52 | 52 | ||
| @@ -373,20 +373,26 @@ static inline int omap243x_sram_init(void) | |||
| 373 | 373 | ||
| 374 | #ifdef CONFIG_ARCH_OMAP3 | 374 | #ifdef CONFIG_ARCH_OMAP3 | 
| 375 | 375 | ||
| 376 | static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl, | 376 | static u32 (*_omap3_sram_configure_core_dpll)( | 
| 377 | u32 sdrc_actim_ctrla, | 377 | u32 m2, u32 unlock_dll, u32 f, u32 inc, | 
| 378 | u32 sdrc_actim_ctrlb, | 378 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | 
| 379 | u32 m2, u32 unlock_dll, | 379 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | 
| 380 | u32 f, u32 sdrc_mr, u32 inc); | 380 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | 
| 381 | u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, | 381 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); | 
| 382 | u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll, | 382 | |
| 383 | u32 f, u32 sdrc_mr, u32 inc) | 383 | u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, | 
| 384 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | ||
| 385 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | ||
| 386 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | ||
| 387 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1) | ||
| 384 | { | 388 | { | 
| 385 | BUG_ON(!_omap3_sram_configure_core_dpll); | 389 | BUG_ON(!_omap3_sram_configure_core_dpll); | 
| 386 | return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl, | 390 | return _omap3_sram_configure_core_dpll( | 
| 387 | sdrc_actim_ctrla, | 391 | m2, unlock_dll, f, inc, | 
| 388 | sdrc_actim_ctrlb, m2, | 392 | sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0, | 
| 389 | unlock_dll, f, sdrc_mr, inc); | 393 | sdrc_actim_ctrl_b_0, sdrc_mr_0, | 
| 394 | sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1, | ||
| 395 | sdrc_actim_ctrl_b_1, sdrc_mr_1); | ||
| 390 | } | 396 | } | 
| 391 | 397 | ||
| 392 | /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */ | 398 | /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */ | 
| diff --git a/arch/arm/plat-s3c24xx/clock-dclk.c b/arch/arm/plat-s3c24xx/clock-dclk.c index 5b75a797b5ab..0afb217a775e 100644 --- a/arch/arm/plat-s3c24xx/clock-dclk.c +++ b/arch/arm/plat-s3c24xx/clock-dclk.c | |||
| @@ -129,7 +129,7 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) | |||
| 129 | 129 | ||
| 130 | /* calculate the MISCCR setting for the clock */ | 130 | /* calculate the MISCCR setting for the clock */ | 
| 131 | 131 | ||
| 132 | if (parent == &clk_xtal) | 132 | if (parent == &clk_mpll) | 
| 133 | source = S3C2410_MISCCR_CLK0_MPLL; | 133 | source = S3C2410_MISCCR_CLK0_MPLL; | 
| 134 | else if (parent == &clk_upll) | 134 | else if (parent == &clk_upll) | 
| 135 | source = S3C2410_MISCCR_CLK0_UPLL; | 135 | source = S3C2410_MISCCR_CLK0_UPLL; | 
| diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 037c1e0b7c4c..6553833c12db 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
| @@ -527,7 +527,7 @@ config SERIAL_S3C24A0 | |||
| 527 | 527 | ||
| 528 | config SERIAL_S3C6400 | 528 | config SERIAL_S3C6400 | 
| 529 | tristate "Samsung S3C6400/S3C6410 Serial port support" | 529 | tristate "Samsung S3C6400/S3C6410 Serial port support" | 
| 530 | depends on SERIAL_SAMSUNG && (CPU_S3C600 || CPU_S3C6410) | 530 | depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410) | 
| 531 | default y | 531 | default y | 
| 532 | help | 532 | help | 
| 533 | Serial port support for the Samsung S3C6400 and S3C6410 | 533 | Serial port support for the Samsung S3C6400 and S3C6410 | 
| diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 47cd258fd24d..5dcbafe72d71 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
| @@ -62,13 +62,14 @@ static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_ev | |||
| 62 | event_priv->wd = wd; | 62 | event_priv->wd = wd; | 
| 63 | 63 | ||
| 64 | ret = fsnotify_add_notify_event(group, event, fsn_event_priv); | 64 | ret = fsnotify_add_notify_event(group, event, fsn_event_priv); | 
| 65 | /* EEXIST is not an error */ | 65 | if (ret) { | 
| 66 | if (ret == -EEXIST) | ||
| 67 | ret = 0; | ||
| 68 | |||
| 69 | /* did event_priv get attached? */ | ||
| 70 | if (list_empty(&fsn_event_priv->event_list)) | ||
| 71 | inotify_free_event_priv(fsn_event_priv); | 66 | inotify_free_event_priv(fsn_event_priv); | 
| 67 | /* EEXIST says we tail matched, EOVERFLOW isn't something | ||
| 68 | * to report up the stack. */ | ||
| 69 | if ((ret == -EEXIST) || | ||
| 70 | (ret == -EOVERFLOW)) | ||
| 71 | ret = 0; | ||
| 72 | } | ||
| 72 | 73 | ||
| 73 | /* | 74 | /* | 
| 74 | * If we hold the entry until after the event is on the queue | 75 | * If we hold the entry until after the event is on the queue | 
| diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index f30d9bbc2e1b..dc32ed8323ba 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
| @@ -386,6 +386,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry, | |||
| 386 | struct fsnotify_event *ignored_event; | 386 | struct fsnotify_event *ignored_event; | 
| 387 | struct inotify_event_private_data *event_priv; | 387 | struct inotify_event_private_data *event_priv; | 
| 388 | struct fsnotify_event_private_data *fsn_event_priv; | 388 | struct fsnotify_event_private_data *fsn_event_priv; | 
| 389 | int ret; | ||
| 389 | 390 | ||
| 390 | ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL, | 391 | ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL, | 
| 391 | FSNOTIFY_EVENT_NONE, NULL, 0, | 392 | FSNOTIFY_EVENT_NONE, NULL, 0, | 
| @@ -404,10 +405,8 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry, | |||
| 404 | fsn_event_priv->group = group; | 405 | fsn_event_priv->group = group; | 
| 405 | event_priv->wd = ientry->wd; | 406 | event_priv->wd = ientry->wd; | 
| 406 | 407 | ||
| 407 | fsnotify_add_notify_event(group, ignored_event, fsn_event_priv); | 408 | ret = fsnotify_add_notify_event(group, ignored_event, fsn_event_priv); | 
| 408 | 409 | if (ret) | |
| 409 | /* did the private data get added? */ | ||
| 410 | if (list_empty(&fsn_event_priv->event_list)) | ||
| 411 | inotify_free_event_priv(fsn_event_priv); | 410 | inotify_free_event_priv(fsn_event_priv); | 
| 412 | 411 | ||
| 413 | skip_send_ignore: | 412 | skip_send_ignore: | 
| @@ -568,7 +567,7 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign | |||
| 568 | 567 | ||
| 569 | spin_lock_init(&group->inotify_data.idr_lock); | 568 | spin_lock_init(&group->inotify_data.idr_lock); | 
| 570 | idr_init(&group->inotify_data.idr); | 569 | idr_init(&group->inotify_data.idr); | 
| 571 | group->inotify_data.last_wd = 0; | 570 | group->inotify_data.last_wd = 1; | 
| 572 | group->inotify_data.user = user; | 571 | group->inotify_data.user = user; | 
| 573 | group->inotify_data.fa = NULL; | 572 | group->inotify_data.fa = NULL; | 
| 574 | 573 | ||
| diff --git a/fs/notify/notification.c b/fs/notify/notification.c index 521368574e97..3816d5750dd5 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
| @@ -153,6 +153,10 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new | |||
| 153 | return true; | 153 | return true; | 
| 154 | break; | 154 | break; | 
| 155 | case (FSNOTIFY_EVENT_NONE): | 155 | case (FSNOTIFY_EVENT_NONE): | 
| 156 | if (old->mask & FS_Q_OVERFLOW) | ||
| 157 | return true; | ||
| 158 | else if (old->mask & FS_IN_IGNORED) | ||
| 159 | return false; | ||
| 156 | return false; | 160 | return false; | 
| 157 | }; | 161 | }; | 
| 158 | } | 162 | } | 
| @@ -171,9 +175,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_even | |||
| 171 | struct list_head *list = &group->notification_list; | 175 | struct list_head *list = &group->notification_list; | 
| 172 | struct fsnotify_event_holder *last_holder; | 176 | struct fsnotify_event_holder *last_holder; | 
| 173 | struct fsnotify_event *last_event; | 177 | struct fsnotify_event *last_event; | 
| 174 | 178 | int ret = 0; | |
| 175 | /* easy to tell if priv was attached to the event */ | ||
| 176 | INIT_LIST_HEAD(&priv->event_list); | ||
| 177 | 179 | ||
| 178 | /* | 180 | /* | 
| 179 | * There is one fsnotify_event_holder embedded inside each fsnotify_event. | 181 | * There is one fsnotify_event_holder embedded inside each fsnotify_event. | 
| @@ -194,6 +196,7 @@ alloc_holder: | |||
| 194 | 196 | ||
| 195 | if (group->q_len >= group->max_events) { | 197 | if (group->q_len >= group->max_events) { | 
| 196 | event = &q_overflow_event; | 198 | event = &q_overflow_event; | 
| 199 | ret = -EOVERFLOW; | ||
| 197 | /* sorry, no private data on the overflow event */ | 200 | /* sorry, no private data on the overflow event */ | 
| 198 | priv = NULL; | 201 | priv = NULL; | 
| 199 | } | 202 | } | 
| @@ -235,7 +238,7 @@ alloc_holder: | |||
| 235 | mutex_unlock(&group->notification_mutex); | 238 | mutex_unlock(&group->notification_mutex); | 
| 236 | 239 | ||
| 237 | wake_up(&group->notification_waitq); | 240 | wake_up(&group->notification_waitq); | 
| 238 | return 0; | 241 | return ret; | 
| 239 | } | 242 | } | 
| 240 | 243 | ||
| 241 | /* | 244 | /* | 
| diff --git a/include/linux/mm.h b/include/linux/mm.h index ba3a7cb1eaa0..9a72cc78e6b8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -34,8 +34,6 @@ extern int sysctl_legacy_va_layout; | |||
| 34 | #define sysctl_legacy_va_layout 0 | 34 | #define sysctl_legacy_va_layout 0 | 
| 35 | #endif | 35 | #endif | 
| 36 | 36 | ||
| 37 | extern unsigned long mmap_min_addr; | ||
| 38 | |||
| 39 | #include <asm/page.h> | 37 | #include <asm/page.h> | 
| 40 | #include <asm/pgtable.h> | 38 | #include <asm/pgtable.h> | 
| 41 | #include <asm/processor.h> | 39 | #include <asm/processor.h> | 
| @@ -575,19 +573,6 @@ static inline void set_page_links(struct page *page, enum zone_type zone, | |||
| 575 | } | 573 | } | 
| 576 | 574 | ||
| 577 | /* | 575 | /* | 
| 578 | * If a hint addr is less than mmap_min_addr change hint to be as | ||
| 579 | * low as possible but still greater than mmap_min_addr | ||
| 580 | */ | ||
| 581 | static inline unsigned long round_hint_to_min(unsigned long hint) | ||
| 582 | { | ||
| 583 | hint &= PAGE_MASK; | ||
| 584 | if (((void *)hint != NULL) && | ||
| 585 | (hint < mmap_min_addr)) | ||
| 586 | return PAGE_ALIGN(mmap_min_addr); | ||
| 587 | return hint; | ||
| 588 | } | ||
| 589 | |||
| 590 | /* | ||
| 591 | * Some inline functions in vmstat.h depend on page_zone() | 576 | * Some inline functions in vmstat.h depend on page_zone() | 
| 592 | */ | 577 | */ | 
| 593 | #include <linux/vmstat.h> | 578 | #include <linux/vmstat.h> | 
| diff --git a/include/linux/security.h b/include/linux/security.h index 5eff459b3833..1f16eea2017b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/resource.h> | 28 | #include <linux/resource.h> | 
| 29 | #include <linux/sem.h> | 29 | #include <linux/sem.h> | 
| 30 | #include <linux/shm.h> | 30 | #include <linux/shm.h> | 
| 31 | #include <linux/mm.h> /* PAGE_ALIGN */ | ||
| 31 | #include <linux/msg.h> | 32 | #include <linux/msg.h> | 
| 32 | #include <linux/sched.h> | 33 | #include <linux/sched.h> | 
| 33 | #include <linux/key.h> | 34 | #include <linux/key.h> | 
| @@ -66,6 +67,9 @@ extern int cap_inode_setxattr(struct dentry *dentry, const char *name, | |||
| 66 | extern int cap_inode_removexattr(struct dentry *dentry, const char *name); | 67 | extern int cap_inode_removexattr(struct dentry *dentry, const char *name); | 
| 67 | extern int cap_inode_need_killpriv(struct dentry *dentry); | 68 | extern int cap_inode_need_killpriv(struct dentry *dentry); | 
| 68 | extern int cap_inode_killpriv(struct dentry *dentry); | 69 | extern int cap_inode_killpriv(struct dentry *dentry); | 
| 70 | extern int cap_file_mmap(struct file *file, unsigned long reqprot, | ||
| 71 | unsigned long prot, unsigned long flags, | ||
| 72 | unsigned long addr, unsigned long addr_only); | ||
| 69 | extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); | 73 | extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); | 
| 70 | extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 74 | extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 
| 71 | unsigned long arg4, unsigned long arg5); | 75 | unsigned long arg4, unsigned long arg5); | 
| @@ -92,6 +96,7 @@ extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); | |||
| 92 | extern int cap_netlink_recv(struct sk_buff *skb, int cap); | 96 | extern int cap_netlink_recv(struct sk_buff *skb, int cap); | 
| 93 | 97 | ||
| 94 | extern unsigned long mmap_min_addr; | 98 | extern unsigned long mmap_min_addr; | 
| 99 | extern unsigned long dac_mmap_min_addr; | ||
| 95 | /* | 100 | /* | 
| 96 | * Values used in the task_security_ops calls | 101 | * Values used in the task_security_ops calls | 
| 97 | */ | 102 | */ | 
| @@ -116,6 +121,21 @@ struct request_sock; | |||
| 116 | #define LSM_UNSAFE_PTRACE 2 | 121 | #define LSM_UNSAFE_PTRACE 2 | 
| 117 | #define LSM_UNSAFE_PTRACE_CAP 4 | 122 | #define LSM_UNSAFE_PTRACE_CAP 4 | 
| 118 | 123 | ||
| 124 | /* | ||
| 125 | * If a hint addr is less than mmap_min_addr change hint to be as | ||
| 126 | * low as possible but still greater than mmap_min_addr | ||
| 127 | */ | ||
| 128 | static inline unsigned long round_hint_to_min(unsigned long hint) | ||
| 129 | { | ||
| 130 | hint &= PAGE_MASK; | ||
| 131 | if (((void *)hint != NULL) && | ||
| 132 | (hint < mmap_min_addr)) | ||
| 133 | return PAGE_ALIGN(mmap_min_addr); | ||
| 134 | return hint; | ||
| 135 | } | ||
| 136 | extern int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp, | ||
| 137 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
| 138 | |||
| 119 | #ifdef CONFIG_SECURITY | 139 | #ifdef CONFIG_SECURITY | 
| 120 | 140 | ||
| 121 | struct security_mnt_opts { | 141 | struct security_mnt_opts { | 
| @@ -2197,9 +2217,7 @@ static inline int security_file_mmap(struct file *file, unsigned long reqprot, | |||
| 2197 | unsigned long addr, | 2217 | unsigned long addr, | 
| 2198 | unsigned long addr_only) | 2218 | unsigned long addr_only) | 
| 2199 | { | 2219 | { | 
| 2200 | if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) | 2220 | return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only); | 
| 2201 | return -EACCES; | ||
| 2202 | return 0; | ||
| 2203 | } | 2221 | } | 
| 2204 | 2222 | ||
| 2205 | static inline int security_file_mprotect(struct vm_area_struct *vma, | 2223 | static inline int security_file_mprotect(struct vm_area_struct *vma, | 
| diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 98e02328c67d..58be76017fd0 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #include <linux/acpi.h> | 49 | #include <linux/acpi.h> | 
| 50 | #include <linux/reboot.h> | 50 | #include <linux/reboot.h> | 
| 51 | #include <linux/ftrace.h> | 51 | #include <linux/ftrace.h> | 
| 52 | #include <linux/security.h> | ||
| 52 | #include <linux/slow-work.h> | 53 | #include <linux/slow-work.h> | 
| 53 | #include <linux/perf_counter.h> | 54 | #include <linux/perf_counter.h> | 
| 54 | 55 | ||
| @@ -1306,10 +1307,10 @@ static struct ctl_table vm_table[] = { | |||
| 1306 | { | 1307 | { | 
| 1307 | .ctl_name = CTL_UNNUMBERED, | 1308 | .ctl_name = CTL_UNNUMBERED, | 
| 1308 | .procname = "mmap_min_addr", | 1309 | .procname = "mmap_min_addr", | 
| 1309 | .data = &mmap_min_addr, | 1310 | .data = &dac_mmap_min_addr, | 
| 1310 | .maxlen = sizeof(unsigned long), | 1311 | .maxlen = sizeof(unsigned long), | 
| 1311 | .mode = 0644, | 1312 | .mode = 0644, | 
| 1312 | .proc_handler = &proc_doulongvec_minmax, | 1313 | .proc_handler = &mmap_min_addr_handler, | 
| 1313 | }, | 1314 | }, | 
| 1314 | #ifdef CONFIG_NUMA | 1315 | #ifdef CONFIG_NUMA | 
| 1315 | { | 1316 | { | 
| diff --git a/mm/Kconfig b/mm/Kconfig index c948d4ca8bde..fe5f674d7a7d 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
| @@ -225,9 +225,9 @@ config DEFAULT_MMAP_MIN_ADDR | |||
| 225 | For most ia64, ppc64 and x86 users with lots of address space | 225 | For most ia64, ppc64 and x86 users with lots of address space | 
| 226 | a value of 65536 is reasonable and should cause no problems. | 226 | a value of 65536 is reasonable and should cause no problems. | 
| 227 | On arm and other archs it should not be higher than 32768. | 227 | On arm and other archs it should not be higher than 32768. | 
| 228 | Programs which use vm86 functionality would either need additional | 228 | Programs which use vm86 functionality or have some need to map | 
| 229 | permissions from either the LSM or the capabilities module or have | 229 | this low address space will need CAP_SYS_RAWIO or disable this | 
| 230 | this protection disabled. | 230 | protection by setting the value to 0. | 
| 231 | 231 | ||
| 232 | This value can be changed after boot using the | 232 | This value can be changed after boot using the | 
| 233 | /proc/sys/vm/mmap_min_addr tunable. | 233 | /proc/sys/vm/mmap_min_addr tunable. | 
| @@ -88,9 +88,6 @@ int sysctl_overcommit_ratio = 50; /* default is 50% */ | |||
| 88 | int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; | 88 | int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; | 
| 89 | struct percpu_counter vm_committed_as; | 89 | struct percpu_counter vm_committed_as; | 
| 90 | 90 | ||
| 91 | /* amount of vm to protect from userspace access */ | ||
| 92 | unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; | ||
| 93 | |||
| 94 | /* | 91 | /* | 
| 95 | * Check that a process has enough memory to allocate a new virtual | 92 | * Check that a process has enough memory to allocate a new virtual | 
| 96 | * mapping. 0 means there is enough memory for the allocation to | 93 | * mapping. 0 means there is enough memory for the allocation to | 
| diff --git a/mm/nommu.c b/mm/nommu.c index 53cab10fece4..28754c40be98 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
| @@ -69,9 +69,6 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT; | |||
| 69 | int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS; | 69 | int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS; | 
| 70 | int heap_stack_gap = 0; | 70 | int heap_stack_gap = 0; | 
| 71 | 71 | ||
| 72 | /* amount of vm to protect from userspace access */ | ||
| 73 | unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; | ||
| 74 | |||
| 75 | atomic_long_t mmap_pages_allocated; | 72 | atomic_long_t mmap_pages_allocated; | 
| 76 | 73 | ||
| 77 | EXPORT_SYMBOL(mem_map); | 74 | EXPORT_SYMBOL(mem_map); | 
| diff --git a/security/Kconfig b/security/Kconfig index d23c839038f0..9c60c346a91d 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
| @@ -113,6 +113,22 @@ config SECURITY_ROOTPLUG | |||
| 113 | 113 | ||
| 114 | If you are unsure how to answer this question, answer N. | 114 | If you are unsure how to answer this question, answer N. | 
| 115 | 115 | ||
| 116 | config LSM_MMAP_MIN_ADDR | ||
| 117 | int "Low address space for LSM to from user allocation" | ||
| 118 | depends on SECURITY && SECURITY_SELINUX | ||
| 119 | default 65535 | ||
| 120 | help | ||
| 121 | This is the portion of low virtual memory which should be protected | ||
| 122 | from userspace allocation. Keeping a user from writing to low pages | ||
| 123 | can help reduce the impact of kernel NULL pointer bugs. | ||
| 124 | |||
| 125 | For most ia64, ppc64 and x86 users with lots of address space | ||
| 126 | a value of 65536 is reasonable and should cause no problems. | ||
| 127 | On arm and other archs it should not be higher than 32768. | ||
| 128 | Programs which use vm86 functionality or have some need to map | ||
| 129 | this low address space will need the permission specific to the | ||
| 130 | systems running LSM. | ||
| 131 | |||
| 116 | source security/selinux/Kconfig | 132 | source security/selinux/Kconfig | 
| 117 | source security/smack/Kconfig | 133 | source security/smack/Kconfig | 
| 118 | source security/tomoyo/Kconfig | 134 | source security/tomoyo/Kconfig | 
| diff --git a/security/Makefile b/security/Makefile index c67557cdaa85..b56e7f9ecbc2 100644 --- a/security/Makefile +++ b/security/Makefile | |||
| @@ -8,7 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack | |||
| 8 | subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo | 8 | subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo | 
| 9 | 9 | ||
| 10 | # always enable default capabilities | 10 | # always enable default capabilities | 
| 11 | obj-y += commoncap.o | 11 | obj-y += commoncap.o min_addr.o | 
| 12 | 12 | ||
| 13 | # Object file lists | 13 | # Object file lists | 
| 14 | obj-$(CONFIG_SECURITY) += security.o capability.o | 14 | obj-$(CONFIG_SECURITY) += security.o capability.o | 
| diff --git a/security/capability.c b/security/capability.c index 21b6cead6a8e..88f752e8152c 100644 --- a/security/capability.c +++ b/security/capability.c | |||
| @@ -330,15 +330,6 @@ static int cap_file_ioctl(struct file *file, unsigned int command, | |||
| 330 | return 0; | 330 | return 0; | 
| 331 | } | 331 | } | 
| 332 | 332 | ||
| 333 | static int cap_file_mmap(struct file *file, unsigned long reqprot, | ||
| 334 | unsigned long prot, unsigned long flags, | ||
| 335 | unsigned long addr, unsigned long addr_only) | ||
| 336 | { | ||
| 337 | if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) | ||
| 338 | return -EACCES; | ||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | 333 | static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | 
| 343 | unsigned long prot) | 334 | unsigned long prot) | 
| 344 | { | 335 | { | 
| diff --git a/security/commoncap.c b/security/commoncap.c index 48b7e0228fa3..e3097c0a1311 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -984,3 +984,33 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 984 | cap_sys_admin = 1; | 984 | cap_sys_admin = 1; | 
| 985 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 985 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 
| 986 | } | 986 | } | 
| 987 | |||
| 988 | /* | ||
| 989 | * cap_file_mmap - check if able to map given addr | ||
| 990 | * @file: unused | ||
| 991 | * @reqprot: unused | ||
| 992 | * @prot: unused | ||
| 993 | * @flags: unused | ||
| 994 | * @addr: address attempting to be mapped | ||
| 995 | * @addr_only: unused | ||
| 996 | * | ||
| 997 | * If the process is attempting to map memory below mmap_min_addr they need | ||
| 998 | * CAP_SYS_RAWIO. The other parameters to this function are unused by the | ||
| 999 | * capability security module. Returns 0 if this mapping should be allowed | ||
| 1000 | * -EPERM if not. | ||
| 1001 | */ | ||
| 1002 | int cap_file_mmap(struct file *file, unsigned long reqprot, | ||
| 1003 | unsigned long prot, unsigned long flags, | ||
| 1004 | unsigned long addr, unsigned long addr_only) | ||
| 1005 | { | ||
| 1006 | int ret = 0; | ||
| 1007 | |||
| 1008 | if (addr < dac_mmap_min_addr) { | ||
| 1009 | ret = cap_capable(current, current_cred(), CAP_SYS_RAWIO, | ||
| 1010 | SECURITY_CAP_AUDIT); | ||
| 1011 | /* set PF_SUPERPRIV if it turns out we allow the low mmap */ | ||
| 1012 | if (ret == 0) | ||
| 1013 | current->flags |= PF_SUPERPRIV; | ||
| 1014 | } | ||
| 1015 | return ret; | ||
| 1016 | } | ||
| diff --git a/security/min_addr.c b/security/min_addr.c new file mode 100644 index 000000000000..14cc7b3b8d03 --- /dev/null +++ b/security/min_addr.c | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #include <linux/init.h> | ||
| 2 | #include <linux/mm.h> | ||
| 3 | #include <linux/security.h> | ||
| 4 | #include <linux/sysctl.h> | ||
| 5 | |||
| 6 | /* amount of vm to protect from userspace access by both DAC and the LSM*/ | ||
| 7 | unsigned long mmap_min_addr; | ||
| 8 | /* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */ | ||
| 9 | unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; | ||
| 10 | /* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */ | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR) | ||
| 14 | */ | ||
| 15 | static void update_mmap_min_addr(void) | ||
| 16 | { | ||
| 17 | #ifdef CONFIG_LSM_MMAP_MIN_ADDR | ||
| 18 | if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR) | ||
| 19 | mmap_min_addr = dac_mmap_min_addr; | ||
| 20 | else | ||
| 21 | mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR; | ||
| 22 | #else | ||
| 23 | mmap_min_addr = dac_mmap_min_addr; | ||
| 24 | #endif | ||
| 25 | } | ||
| 26 | |||
| 27 | /* | ||
| 28 | * sysctl handler which just sets dac_mmap_min_addr = the new value and then | ||
| 29 | * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly | ||
| 30 | */ | ||
| 31 | int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp, | ||
| 32 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
| 33 | { | ||
| 34 | int ret; | ||
| 35 | |||
| 36 | ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); | ||
| 37 | |||
| 38 | update_mmap_min_addr(); | ||
| 39 | |||
| 40 | return ret; | ||
| 41 | } | ||
| 42 | |||
| 43 | int __init init_mmap_min_addr(void) | ||
| 44 | { | ||
| 45 | update_mmap_min_addr(); | ||
| 46 | |||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | pure_initcall(init_mmap_min_addr); | ||
| diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1e8cfc4c2ed6..8d8b69c5664e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -3030,9 +3030,21 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot, | |||
| 3030 | int rc = 0; | 3030 | int rc = 0; | 
| 3031 | u32 sid = current_sid(); | 3031 | u32 sid = current_sid(); | 
| 3032 | 3032 | ||
| 3033 | if (addr < mmap_min_addr) | 3033 | /* | 
| 3034 | * notice that we are intentionally putting the SELinux check before | ||
| 3035 | * the secondary cap_file_mmap check. This is such a likely attempt | ||
| 3036 | * at bad behaviour/exploit that we always want to get the AVC, even | ||
| 3037 | * if DAC would have also denied the operation. | ||
| 3038 | */ | ||
| 3039 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { | ||
| 3034 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, | 3040 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, | 
| 3035 | MEMPROTECT__MMAP_ZERO, NULL); | 3041 | MEMPROTECT__MMAP_ZERO, NULL); | 
| 3042 | if (rc) | ||
| 3043 | return rc; | ||
| 3044 | } | ||
| 3045 | |||
| 3046 | /* do DAC check on address space usage */ | ||
| 3047 | rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only); | ||
| 3036 | if (rc || addr_only) | 3048 | if (rc || addr_only) | 
| 3037 | return rc; | 3049 | return rc; | 
| 3038 | 3050 | ||
