]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Jul 2012 00:43:53 +0000 (17:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Jul 2012 00:43:53 +0000 (17:43 -0700)
Pull arm-soc power management changes from Arnd Bergmann:
 "These are various power management related changes, mainly concerning
  cpuidle on i.MX and OMAP, as well as a the move of the omap
  smartreflex driver to live in the power subsystem."

Fix up conflicts in arch/arm/mach-{imx/mach-imx6q.c,omap2/prm2xxx_3xxx.h}

* tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (37 commits)
  ARM: OMAP2+: PM: fix IRQ_NOAUTOEN removal by mis-merge
  ARM: OMAP2+: do not allow SmartReflex to be built as a module
  ARM: OMAP2: Use hwmod to initialize mmc for 2420
  ARM: OMAP3: PM: cpuidle: optimize the clkdm idle latency in C1 state
  ARM: OMAP3: PM: cpuidle: optimize the PER latency in C1 state
  ARM: OMAP3: PM: cpuidle: default to C1 in next_valid_state
  ARM: OMAP3: PM: cleanup cam_pwrdm leftovers
  ARM: OMAP3: PM: call pre/post transition per powerdomain
  ARM: OMAP2+: powerdomain: allow pre/post transtion to be per pwrdm
  ARM: OMAP3: PM: Remove IO Daisychain control from cpuidle
  ARM: OMAP3PLUS: hwmod: reconfigure IO Daisychain during hwmod mux
  ARM: OMAP3+: PRM: Enable IO wake up
  ARM: OMAP4: PRM: Add IO Daisychain support
  ARM: OMAP3: PM: Move IO Daisychain function to omap3 prm file
  ARM: OMAP3: PM: correct enable/disable of daisy io chain
  ARM: OMAP2+: PRM: fix compile for OMAP4-only build
  W1: OMAP HDQ1W: use runtime PM
  ARM: OMAP2+: HDQ1W: use omap_device
  W1: OMAP HDQ1W: use 32-bit register accesses
  W1: OMAP HDQ1W: allow driver to be built on all OMAP2+
  ...

23 files changed:
1  2 
arch/arm/mach-imx/imx53-dt.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-mx53_ard.c
arch/arm/mach-imx/mach-mx53_evk.c
arch/arm/mach-imx/mach-mx53_loco.c
arch/arm/mach-imx/mach-mx53_smd.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/cpuidle34xx.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/powerdomain.c
arch/arm/mach-omap2/powerdomain.h
arch/arm/mach-omap2/prcm-common.h
arch/arm/mach-omap2/prm2xxx_3xxx.h
arch/arm/mach-omap2/voltage.h
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/include/mach/hardware.h
arch/arm/plat-mxc/tzic.c
arch/arm/plat-omap/Kconfig

index fdd90805d98eca19862c5f282d0e9fef3baf234d,481c3e96ad7fd9b719bed94d60b5b18c1be0e541..1b7a2fc36591e1806af4345be6f00fbec9bd70a8
@@@ -15,6 -15,7 +15,6 @@@
  #include <linux/err.h>
  #include <linux/io.h>
  #include <linux/irq.h>
 -#include <linux/irqdomain.h>
  #include <linux/of_irq.h>
  #include <linux/of_platform.h>
  #include <linux/pinctrl/machine.h>
@@@ -51,6 -52,30 +51,6 @@@ static const struct of_dev_auxdata imx5
        { /* sentinel */ }
  };
  
 -static int __init imx53_tzic_add_irq_domain(struct device_node *np,
 -                              struct device_node *interrupt_parent)
 -{
 -      irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
 -      return 0;
 -}
 -
 -static int __init imx53_gpio_add_irq_domain(struct device_node *np,
 -                              struct device_node *interrupt_parent)
 -{
 -      static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 -
 -      gpio_irq_base -= 32;
 -      irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
 -
 -      return 0;
 -}
 -
 -static const struct of_device_id imx53_irq_match[] __initconst = {
 -      { .compatible = "fsl,imx53-tzic", .data = imx53_tzic_add_irq_domain, },
 -      { .compatible = "fsl,imx53-gpio", .data = imx53_gpio_add_irq_domain, },
 -      { /* sentinel */ }
 -};
 -
  static const struct of_device_id imx53_iomuxc_of_match[] __initconst = {
        { .compatible = "fsl,imx53-iomuxc-ard", .data = imx53_ard_common_init, },
        { .compatible = "fsl,imx53-iomuxc-evk", .data = imx53_evk_common_init, },
@@@ -78,6 -103,8 +78,6 @@@ static void __init imx53_dt_init(void
        const struct of_device_id *of_id;
        void (*func)(void);
  
 -      of_irq_init(imx53_irq_match);
 -
        pinctrl_provide_dummies();
  
        node = of_find_matching_node(NULL, imx53_iomuxc_of_match);
@@@ -120,6 -147,7 +120,7 @@@ DT_MACHINE_START(IMX53_DT, "Freescale i
        .handle_irq     = imx53_handle_irq,
        .timer          = &imx53_timer,
        .init_machine   = imx53_dt_init,
+       .init_late      = imx53_init_late,
        .dt_compat      = imx53_dt_board_compat,
        .restart        = mxc_restart,
  MACHINE_END
index 426d2087c460133440e78f7d5500f9a74c5c89de,d4ca2c47014297bccf65a16bf1ca855d4ee1fb42..5ec0608f2a764a9be584ea1bebbe1339f981a259
  
  #include <linux/clk.h>
  #include <linux/clkdev.h>
+ #include <linux/cpuidle.h>
  #include <linux/delay.h>
+ #include <linux/export.h>
  #include <linux/init.h>
  #include <linux/io.h>
  #include <linux/irq.h>
 -#include <linux/irqdomain.h>
  #include <linux/of.h>
  #include <linux/of_address.h>
  #include <linux/of_irq.h>
@@@ -23,7 -26,7 +25,8 @@@
  #include <linux/pinctrl/machine.h>
  #include <linux/phy.h>
  #include <linux/micrel_phy.h>
 +#include <linux/mfd/anatop.h>
+ #include <asm/cpuidle.h>
  #include <asm/smp_twd.h>
  #include <asm/hardware/cache-l2x0.h>
  #include <asm/hardware/gic.h>
  #include <asm/mach/time.h>
  #include <asm/system_misc.h>
  #include <mach/common.h>
+ #include <mach/cpuidle.h>
  #include <mach/hardware.h>
  
  void imx6q_restart(char mode, const char *cmd)
  {
        struct device_node *np;
@@@ -113,45 -118,6 +118,45 @@@ static void __init imx6q_sabrelite_init
        imx6q_sabrelite_cko1_setup();
  }
  
 +static void __init imx6q_usb_init(void)
 +{
 +      struct device_node *np;
 +      struct platform_device *pdev = NULL;
 +      struct anatop *adata = NULL;
 +
 +      np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
 +      if (np)
 +              pdev = of_find_device_by_node(np);
 +      if (pdev)
 +              adata = platform_get_drvdata(pdev);
 +      if (!adata) {
 +              if (np)
 +                      of_node_put(np);
 +              return;
 +      }
 +
 +#define HW_ANADIG_USB1_CHRG_DETECT            0x000001b0
 +#define HW_ANADIG_USB2_CHRG_DETECT            0x00000210
 +
 +#define BM_ANADIG_USB_CHRG_DETECT_EN_B                0x00100000
 +#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B  0x00080000
 +
 +      /*
 +       * The external charger detector needs to be disabled,
 +       * or the signal at DP will be poor
 +       */
 +      anatop_write_reg(adata, HW_ANADIG_USB1_CHRG_DETECT,
 +                      BM_ANADIG_USB_CHRG_DETECT_EN_B
 +                      | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B,
 +                      ~0);
 +      anatop_write_reg(adata, HW_ANADIG_USB2_CHRG_DETECT,
 +                      BM_ANADIG_USB_CHRG_DETECT_EN_B |
 +                      BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B,
 +                      ~0);
 +
 +      of_node_put(np);
 +}
 +
  static void __init imx6q_init_machine(void)
  {
        /*
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  
        imx6q_pm_init();
 +      imx6q_usb_init();
  }
  
+ static struct cpuidle_driver imx6q_cpuidle_driver = {
+       .name                   = "imx6q_cpuidle",
+       .owner                  = THIS_MODULE,
+       .en_core_tk_irqen       = 1,
+       .states[0]              = ARM_CPUIDLE_WFI_STATE,
+       .state_count            = 1,
+ };
+ static void __init imx6q_init_late(void)
+ {
+       imx_cpuidle_init(&imx6q_cpuidle_driver);
+ }
  static void __init imx6q_map_io(void)
  {
        imx_lluart_map_io();
        imx6q_clock_map_io();
  }
  
 -static int __init imx6q_gpio_add_irq_domain(struct device_node *np,
 -                              struct device_node *interrupt_parent)
 -{
 -      static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 -
 -      gpio_irq_base -= 32;
 -      irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
 -                            NULL);
 -
 -      return 0;
 -}
 -
  static const struct of_device_id imx6q_irq_match[] __initconst = {
        { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
 -      { .compatible = "fsl,imx6q-gpio", .data = imx6q_gpio_add_irq_domain, },
        { /* sentinel */ }
  };
  
@@@ -213,6 -204,7 +231,7 @@@ DT_MACHINE_START(IMX6Q, "Freescale i.MX
        .handle_irq     = imx6q_handle_irq,
        .timer          = &imx6q_timer,
        .init_machine   = imx6q_init_machine,
+       .init_late      = imx6q_init_late,
        .dt_compat      = imx6q_dt_compat,
        .restart        = imx6q_restart,
  MACHINE_END
index f641a1758691198eada9818774392c7fa668eedd,f1e83d6d2dfc0e6c43a8497253d2ed975e2b919f..6c28e65f424d012ad4217793c8c04c31e4aacc14
@@@ -135,7 -135,8 +135,7 @@@ static struct resource ard_smsc911x_res
                .flags = IORESOURCE_MEM,
        },
        {
 -              .start =  IMX_GPIO_TO_IRQ(ARD_ETHERNET_INT_B),
 -              .end =  IMX_GPIO_TO_IRQ(ARD_ETHERNET_INT_B),
 +              /* irq number is run-time assigned */
                .flags = IORESOURCE_IRQ,
        },
  };
@@@ -239,12 -240,10 +239,12 @@@ static void __init mx53_ard_board_init(
        imx53_ard_common_init();
        mx53_ard_io_init();
        regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
 +      ard_smsc911x_resources[1].start = gpio_to_irq(ARD_ETHERNET_INT_B);
 +      ard_smsc911x_resources[1].end = gpio_to_irq(ARD_ETHERNET_INT_B);
        platform_add_devices(devices, ARRAY_SIZE(devices));
  
        imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data);
 -      imx53_add_imx2_wdt(0, NULL);
 +      imx53_add_imx2_wdt(0);
        imx53_add_imx_i2c(1, &mx53_ard_i2c2_data);
        imx53_add_imx_i2c(2, &mx53_ard_i2c3_data);
        imx_add_gpio_keys(&ard_button_data);
@@@ -267,5 -266,6 +267,6 @@@ MACHINE_START(MX53_ARD, "Freescale MX5
        .handle_irq = imx53_handle_irq,
        .timer = &mx53_ard_timer,
        .init_machine = mx53_ard_board_init,
+       .init_late      = imx53_init_late,
        .restart        = mxc_restart,
  MACHINE_END
index a1060b26fb23b4864004df6ec87a727306bac253,8387496ef5ec1c83aaa82f43e6eba64e0d7eca46..09fe2197b4919e51cc5016e4f44a4049342816b3
@@@ -154,7 -154,7 +154,7 @@@ static void __init mx53_evk_board_init(
        spi_register_board_info(mx53_evk_spi_board_info,
                ARRAY_SIZE(mx53_evk_spi_board_info));
        imx53_add_ecspi(0, &mx53_evk_spi_data);
 -      imx53_add_imx2_wdt(0, NULL);
 +      imx53_add_imx2_wdt(0);
        gpio_led_register_device(-1, &mx53evk_leds_data);
  }
  
@@@ -174,5 -174,6 +174,6 @@@ MACHINE_START(MX53_EVK, "Freescale MX5
        .handle_irq = imx53_handle_irq,
        .timer = &mx53_evk_timer,
        .init_machine = mx53_evk_board_init,
+       .init_late      = imx53_init_late,
        .restart        = mxc_restart,
  MACHINE_END
index 388c415d6b62c4b45d575f81f863a0e66ba53f71,e266f3f0f08069abd9e5e2512959f4039d375c19..8abe23c1d3c893fc191110717fd8131eea10ab41
@@@ -283,7 -283,7 +283,7 @@@ static void __init mx53_loco_board_init
        imx53_add_imx_uart(0, NULL);
        mx53_loco_fec_reset();
        imx53_add_fec(&mx53_loco_fec_data);
 -      imx53_add_imx2_wdt(0, NULL);
 +      imx53_add_imx2_wdt(0);
  
        ret = gpio_request_one(LOCO_ACCEL_EN, GPIOF_OUT_INIT_HIGH, "accel_en");
        if (ret)
@@@ -316,5 -316,6 +316,6 @@@ MACHINE_START(MX53_LOCO, "Freescale MX5
        .handle_irq = imx53_handle_irq,
        .timer = &mx53_loco_timer,
        .init_machine = mx53_loco_board_init,
+       .init_late      = imx53_init_late,
        .restart        = mxc_restart,
  MACHINE_END
index f297df7ccb39cef69f16c4c8cbf93a49ed144833,4f4c1b93ea662f33bb3d9854069c0685439a0ad9..b15d6a6d3b6873c77e13283ba9103f4da3e62091
@@@ -138,7 -138,7 +138,7 @@@ static void __init mx53_smd_board_init(
        mx53_smd_init_uart();
        mx53_smd_fec_reset();
        imx53_add_fec(&mx53_smd_fec_data);
 -      imx53_add_imx2_wdt(0, NULL);
 +      imx53_add_imx2_wdt(0);
        imx53_add_imx_i2c(0, &mx53_smd_i2c_data);
        imx53_add_sdhci_esdhc_imx(0, NULL);
        imx53_add_sdhci_esdhc_imx(1, NULL);
@@@ -163,5 -163,6 +163,6 @@@ MACHINE_START(MX53_SMD, "Freescale MX5
        .handle_irq = imx53_handle_irq,
        .timer = &mx53_smd_timer,
        .init_machine = mx53_smd_board_init,
+       .init_late      = imx53_init_late,
        .restart        = mxc_restart,
  MACHINE_END
index 19b771d0c0d7b28fd2e93446cfb57b0b5343af32,f74e975027b6f3aa3214e522b762514a23da5227..b7a4ab65faca336ae9f13bae1c504427291f0700
@@@ -6,7 -6,7 +6,7 @@@
  obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
         common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o
  
 -omap-2-3-common                               = irq.o sdrc.o
 +omap-2-3-common                               = irq.o
  hwmod-common                          = omap_hwmod.o \
                                          omap_hwmod_common_data.o
  clock-common                          = clock.o clock_common_data.o \
@@@ -16,24 -16,19 +16,24 @@@ secure-common                              = omap-smc.o omap-secu
  obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
  obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
  obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
 +obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
 +obj-$(CONFIG_SOC_OMAP5)        += prm44xx.o $(hwmod-common) $(secure-common)
  
  ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
  obj-y += mcbsp.o
  endif
  
  obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
 +obj-$(CONFIG_SOC_HAS_OMAP2_SDRC)      += sdrc.o
  
  # SMP support ONLY available for OMAP4
  
  obj-$(CONFIG_SMP)                     += omap-smp.o omap-headsmp.o
  obj-$(CONFIG_HOTPLUG_CPU)             += omap-hotplug.o
 -obj-$(CONFIG_ARCH_OMAP4)              += omap4-common.o omap-wakeupgen.o
 -obj-$(CONFIG_ARCH_OMAP4)              += sleep44xx.o
 +omap-4-5-common                               =  omap4-common.o omap-wakeupgen.o \
 +                                         sleep44xx.o
 +obj-$(CONFIG_ARCH_OMAP4)              += $(omap-4-5-common)
 +obj-$(CONFIG_SOC_OMAP5)                       += $(omap-4-5-common)
  
  plus_sec := $(call as-instr,.arch_extension sec,+sec)
  AFLAGS_omap-headsmp.o                 :=-Wa,-march=armv7-a$(plus_sec)
@@@ -71,11 -66,13 +71,12 @@@ ifeq ($(CONFIG_PM),y
  obj-$(CONFIG_ARCH_OMAP2)              += pm24xx.o
  obj-$(CONFIG_ARCH_OMAP2)              += sleep24xx.o
  obj-$(CONFIG_ARCH_OMAP3)              += pm34xx.o sleep34xx.o
 -obj-$(CONFIG_ARCH_OMAP3)              += cpuidle34xx.o
  obj-$(CONFIG_ARCH_OMAP4)              += pm44xx.o omap-mpuss-lowpower.o
 -obj-$(CONFIG_ARCH_OMAP4)              += cpuidle44xx.o
 +obj-$(CONFIG_SOC_OMAP5)                       += omap-mpuss-lowpower.o
  obj-$(CONFIG_PM_DEBUG)                        += pm-debug.o
- obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
- obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
+ obj-$(CONFIG_POWER_AVS_OMAP)          += sr_device.o
+ obj-$(CONFIG_POWER_AVS_OMAP_CLASS3)    += smartreflex-class3.o
  
  AFLAGS_sleep24xx.o                    :=-Wa,-march=armv6
  AFLAGS_sleep34xx.o                    :=-Wa,-march=armv7-a$(plus_sec)
@@@ -86,22 -83,14 +87,22 @@@ endi
  
  endif
  
 +ifeq ($(CONFIG_CPU_IDLE),y)
 +obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
 +obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
 +endif
 +
  # PRCM
 +omap-prcm-4-5-common                  =  prcm.o cminst44xx.o cm44xx.o \
 +                                         prcm_mpu44xx.o prminst44xx.o \
 +                                         vc44xx_data.o vp44xx_data.o
  obj-y                                 += prm_common.o
  obj-$(CONFIG_ARCH_OMAP2)              += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
  obj-$(CONFIG_ARCH_OMAP3)              += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
  obj-$(CONFIG_ARCH_OMAP3)              += vc3xxx_data.o vp3xxx_data.o
 -obj-$(CONFIG_ARCH_OMAP4)              += prcm.o cminst44xx.o cm44xx.o
 -obj-$(CONFIG_ARCH_OMAP4)              += prcm_mpu44xx.o prminst44xx.o
 -obj-$(CONFIG_ARCH_OMAP4)              += vc44xx_data.o vp44xx_data.o prm44xx.o
 +obj-$(CONFIG_SOC_AM33XX)              += prcm.o prm33xx.o cm33xx.o
 +obj-$(CONFIG_ARCH_OMAP4)              += $(omap-prcm-4-5-common) prm44xx.o
 +obj-$(CONFIG_SOC_OMAP5)                       += $(omap-prcm-4-5-common)
  
  # OMAP voltage domains
  voltagedomain-common                  := voltage.o vc.o vp.o
@@@ -111,9 -100,6 +112,9 @@@ obj-$(CONFIG_ARCH_OMAP3)           += $(voltaged
  obj-$(CONFIG_ARCH_OMAP3)              += voltagedomains3xxx_data.o
  obj-$(CONFIG_ARCH_OMAP4)              += $(voltagedomain-common)
  obj-$(CONFIG_ARCH_OMAP4)              += voltagedomains44xx_data.o
 +obj-$(CONFIG_SOC_AM33XX)              += $(voltagedomain-common)
 +obj-$(CONFIG_SOC_AM33XX)                += voltagedomains33xx_data.o
 +obj-$(CONFIG_SOC_OMAP5)                       += $(voltagedomain-common)
  
  # OMAP powerdomain framework
  powerdomain-common                    += powerdomain.o powerdomain-common.o
@@@ -128,14 -114,10 +129,14 @@@ obj-$(CONFIG_ARCH_OMAP3)                += powerdomai
  obj-$(CONFIG_ARCH_OMAP4)              += $(powerdomain-common)
  obj-$(CONFIG_ARCH_OMAP4)              += powerdomain44xx.o
  obj-$(CONFIG_ARCH_OMAP4)              += powerdomains44xx_data.o
 +obj-$(CONFIG_SOC_AM33XX)              += $(powerdomain-common)
 +obj-$(CONFIG_SOC_AM33XX)              += powerdomain33xx.o
 +obj-$(CONFIG_SOC_AM33XX)              += powerdomains33xx_data.o
 +obj-$(CONFIG_SOC_OMAP5)                       += $(powerdomain-common)
 +obj-$(CONFIG_SOC_OMAP5)                       += powerdomain44xx.o
  
  # PRCM clockdomain control
  clockdomain-common                    += clockdomain.o
 -clockdomain-common                    += clockdomains_common_data.o
  obj-$(CONFIG_ARCH_OMAP2)              += $(clockdomain-common)
  obj-$(CONFIG_ARCH_OMAP2)              += clockdomain2xxx_3xxx.o
  obj-$(CONFIG_ARCH_OMAP2)              += clockdomains2xxx_3xxx_data.o
@@@ -148,11 -130,6 +149,11 @@@ obj-$(CONFIG_ARCH_OMAP3)         += clockdomai
  obj-$(CONFIG_ARCH_OMAP4)              += $(clockdomain-common)
  obj-$(CONFIG_ARCH_OMAP4)              += clockdomain44xx.o
  obj-$(CONFIG_ARCH_OMAP4)              += clockdomains44xx_data.o
 +obj-$(CONFIG_SOC_AM33XX)              += $(clockdomain-common)
 +obj-$(CONFIG_SOC_AM33XX)              += clockdomain33xx.o
 +obj-$(CONFIG_SOC_AM33XX)              += clockdomains33xx_data.o
 +obj-$(CONFIG_SOC_OMAP5)                       += $(clockdomain-common)
 +obj-$(CONFIG_SOC_OMAP5)                       += clockdomain44xx.o
  
  # Clock framework
  obj-$(CONFIG_ARCH_OMAP2)              += $(clock-common) clock2xxx.o
@@@ -170,9 -147,6 +171,9 @@@ obj-$(CONFIG_ARCH_OMAP3)           += dpll3xxx.
  obj-$(CONFIG_ARCH_OMAP3)              += clkt_iclk.o
  obj-$(CONFIG_ARCH_OMAP4)              += $(clock-common) clock44xx_data.o
  obj-$(CONFIG_ARCH_OMAP4)              += dpll3xxx.o dpll44xx.o
 +obj-$(CONFIG_SOC_AM33XX)              += $(clock-common) dpll3xxx.o
 +obj-$(CONFIG_SOC_OMAP5)                       += $(clock-common)
 +obj-$(CONFIG_SOC_OMAP5)                       += dpll3xxx.o dpll44xx.o
  
  # OMAP2 clock rate set data (old "OPP" data)
  obj-$(CONFIG_SOC_OMAP2420)            += opp2420_data.o
@@@ -200,7 -174,6 +201,7 @@@ obj-$(CONFIG_OMAP3_EMU)                    += emu.
  # L3 interconnect
  obj-$(CONFIG_ARCH_OMAP3)              += omap_l3_smx.o
  obj-$(CONFIG_ARCH_OMAP4)              += omap_l3_noc.o
 +obj-$(CONFIG_SOC_OMAP5)                       += omap_l3_noc.o
  
  obj-$(CONFIG_OMAP_MBOX_FWK)           += mailbox_mach.o
  mailbox_mach-objs                     := mailbox.o
@@@ -217,10 -190,6 +218,10 @@@ endi
  # OMAP2420 MSDI controller integration support ("MMC")
  obj-$(CONFIG_SOC_OMAP2420)            += msdi.o
  
 +ifneq ($(CONFIG_DRM_OMAP),)
 +obj-y                                 += drm.o
 +endif
 +
  # Specific board support
  obj-$(CONFIG_MACH_OMAP_GENERIC)               += board-generic.o
  obj-$(CONFIG_MACH_OMAP_H4)            += board-h4.o
@@@ -276,6 -245,9 +277,6 @@@ obj-y                                      += $(omap-flash-y) $(omap-fla
  omap-hsmmc-$(CONFIG_MMC_OMAP_HS)      := hsmmc.o
  obj-y                                 += $(omap-hsmmc-m) $(omap-hsmmc-y)
  
 -
 -usbfs-$(CONFIG_ARCH_OMAP_OTG)         := usb-fs.o
 -obj-y                                 += $(usbfs-m) $(usbfs-y)
  obj-y                                 += usb-musb.o
  obj-y                                 += omap_phy_internal.o
  
index 31344528eb5448905f46252228fc6cdb22a2a4e3,e6ae3fe5cdc6eba21bc4f487da841e2ec7c49701..f2a49a48ef5992bada3566f8e2ab00581a3e6b4d
@@@ -36,6 -36,8 +36,6 @@@
  #include "control.h"
  #include "common.h"
  
 -#ifdef CONFIG_CPU_IDLE
 -
  /* Mach specific information to be recorded in the C-state driver_data */
  struct omap3_idle_statedata {
        u32 mpu_state;
@@@ -75,20 -77,6 +75,6 @@@ static struct omap3_idle_statedata omap
  
  static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
  
- static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
-                               struct clockdomain *clkdm)
- {
-       clkdm_allow_idle(clkdm);
-       return 0;
- }
- static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
-                               struct clockdomain *clkdm)
- {
-       clkdm_deny_idle(clkdm);
-       return 0;
- }
  static int __omap3_enter_idle(struct cpuidle_device *dev,
                                struct cpuidle_driver *drv,
                                int index)
  
        /* Deny idle for C1 */
        if (index == 0) {
-               pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
-               pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
+               clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]);
+               clkdm_deny_idle(core_pd->pwrdm_clkdms[0]);
        }
  
        /*
  
        /* Re-allow idle for C1 */
        if (index == 0) {
-               pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
-               pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
+               clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]);
+               clkdm_allow_idle(core_pd->pwrdm_clkdms[0]);
        }
  
  return_sleep_time:
@@@ -176,7 -164,7 +162,7 @@@ static int next_valid_state(struct cpui
        u32 mpu_deepest_state = PWRDM_POWER_RET;
        u32 core_deepest_state = PWRDM_POWER_RET;
        int idx;
-       int next_index = -1;
+       int next_index = 0; /* C1 is the default value */
  
        if (enable_off_mode) {
                mpu_deepest_state = PWRDM_POWER_OFF;
                }
        }
  
-       /*
-        * C1 is always valid.
-        * So, no need to check for 'next_index == -1' outside
-        * this loop.
-        */
        return next_index;
  }
  
   * the device to the specified or a safer state.
   */
  static int omap3_enter_idle_bm(struct cpuidle_device *dev,
-                               struct cpuidle_driver *drv,
+                              struct cpuidle_driver *drv,
                               int index)
  {
        int new_state_idx;
-       u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
+       u32 core_next_state, per_next_state = 0, per_saved_state = 0;
        struct omap3_idle_statedata *cx;
        int ret;
  
        /*
-        * Prevent idle completely if CAM is active.
+        * Use only C1 if CAM is active.
         * CAM does not have wakeup capability in OMAP3.
         */
-       cam_state = pwrdm_read_pwrst(cam_pd);
-       if (cam_state == PWRDM_POWER_ON) {
+       if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON)
                new_state_idx = drv->safe_state_index;
-               goto select_state;
-       }
+       else
+               new_state_idx = next_valid_state(dev, drv, index);
  
        /*
         * FIXME: we currently manage device-specific idle states
         *        its own code.
         */
  
-       /*
-        * Prevent PER off if CORE is not in retention or off as this
-        * would disable PER wakeups completely.
-        */
-       cx = &omap3_idle_data[index];
+       /* Program PER state */
+       cx = &omap3_idle_data[new_state_idx];
        core_next_state = cx->core_state;
        per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
-       if ((per_next_state == PWRDM_POWER_OFF) &&
-           (core_next_state > PWRDM_POWER_RET))
-               per_next_state = PWRDM_POWER_RET;
+       if (new_state_idx == 0) {
+               /* In C1 do not allow PER state lower than CORE state */
+               if (per_next_state < core_next_state)
+                       per_next_state = core_next_state;
+       } else {
+               /*
+                * Prevent PER OFF if CORE is not in RETention or OFF as this
+                * would disable PER wakeups completely.
+                */
+               if ((per_next_state == PWRDM_POWER_OFF) &&
+                   (core_next_state > PWRDM_POWER_RET))
+                       per_next_state = PWRDM_POWER_RET;
+       }
  
        /* Are we changing PER target state? */
        if (per_next_state != per_saved_state)
                pwrdm_set_next_pwrst(per_pd, per_next_state);
  
-       new_state_idx = next_valid_state(dev, drv, index);
- select_state:
        ret = omap3_enter_idle(dev, drv, new_state_idx);
  
        /* Restore original PER state if it was modified */
@@@ -286,7 -271,7 +269,7 @@@ struct cpuidle_driver omap3_idle_drive
        .owner =        THIS_MODULE,
        .states = {
                {
-                       .enter            = omap3_enter_idle,
+                       .enter            = omap3_enter_idle_bm,
                        .exit_latency     = 2 + 2,
                        .target_residency = 5,
                        .flags            = CPUIDLE_FLAG_TIME_VALID,
@@@ -377,3 -362,9 +360,3 @@@ int __init omap3_idle_init(void
  
        return 0;
  }
 -#else
 -int __init omap3_idle_init(void)
 -{
 -      return 0;
 -}
 -#endif /* CONFIG_CPU_IDLE */
index 71651e20a43ed0e784222c5242dba428641eb299,91ef6699df5ef34fcc523ba895fdd9d0805c1f32..c00c68961bb848d16a68802003a4ee6402cf4710
@@@ -27,7 -27,6 +27,6 @@@
  
  #include "iomap.h"
  #include <plat/board.h>
- #include <plat/mmc.h>
  #include <plat/dma.h>
  #include <plat/omap_hwmod.h>
  #include <plat/omap_device.h>
@@@ -84,7 -83,7 +83,7 @@@ static int __init omap4_l3_init(void
         * To avoid code running on other OMAPs in
         * multi-omap builds
         */
 -      if (!(cpu_is_omap44xx()))
 +      if (!cpu_is_omap44xx() && !soc_is_omap54xx())
                return -ENODEV;
  
        for (i = 0; i < L3_MODULES; i++) {
@@@ -603,112 -602,6 +602,6 @@@ static inline void omap_init_aes(void) 
  
  /*-------------------------------------------------------------------------*/
  
- #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
- static inline void omap242x_mmc_mux(struct omap_mmc_platform_data
-                                                       *mmc_controller)
- {
-       if ((mmc_controller->slots[0].switch_pin > 0) && \
-               (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
-               omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
-                                       OMAP_PIN_INPUT_PULLUP);
-       if ((mmc_controller->slots[0].gpio_wp > 0) && \
-               (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
-               omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
-                                       OMAP_PIN_INPUT_PULLUP);
-       omap_mux_init_signal("sdmmc_cmd", 0);
-       omap_mux_init_signal("sdmmc_clki", 0);
-       omap_mux_init_signal("sdmmc_clko", 0);
-       omap_mux_init_signal("sdmmc_dat0", 0);
-       omap_mux_init_signal("sdmmc_dat_dir0", 0);
-       omap_mux_init_signal("sdmmc_cmd_dir", 0);
-       if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
-               omap_mux_init_signal("sdmmc_dat1", 0);
-               omap_mux_init_signal("sdmmc_dat2", 0);
-               omap_mux_init_signal("sdmmc_dat3", 0);
-               omap_mux_init_signal("sdmmc_dat_dir1", 0);
-               omap_mux_init_signal("sdmmc_dat_dir2", 0);
-               omap_mux_init_signal("sdmmc_dat_dir3", 0);
-       }
-       /*
-        * Use internal loop-back in MMC/SDIO Module Input Clock
-        * selection
-        */
-       if (mmc_controller->slots[0].internal_clock) {
-               u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
-               v |= (1 << 24);
-               omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
-       }
- }
- void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
- {
-       struct platform_device *pdev;
-       struct omap_hwmod *oh;
-       int id = 0;
-       char *oh_name = "msdi1";
-       char *dev_name = "mmci-omap";
-       if (!mmc_data[0]) {
-               pr_err("%s fails: Incomplete platform data\n", __func__);
-               return;
-       }
-       omap242x_mmc_mux(mmc_data[0]);
-       oh = omap_hwmod_lookup(oh_name);
-       if (!oh) {
-               pr_err("Could not look up %s\n", oh_name);
-               return;
-       }
-       pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
-                                sizeof(struct omap_mmc_platform_data), NULL, 0, 0);
-       if (IS_ERR(pdev))
-               WARN(1, "Can'd build omap_device for %s:%s.\n",
-                                       dev_name, oh->name);
- }
- #endif
- /*-------------------------------------------------------------------------*/
- #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
- #define OMAP_HDQ_BASE 0x480B2000
- static struct resource omap_hdq_resources[] = {
-       {
-               .start          = OMAP_HDQ_BASE,
-               .end            = OMAP_HDQ_BASE + 0x1C,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = INT_24XX_HDQ_IRQ,
-               .flags          = IORESOURCE_IRQ,
-       },
- };
- static struct platform_device omap_hdq_dev = {
-       .name = "omap_hdq",
-       .id = 0,
-       .dev = {
-               .platform_data = NULL,
-       },
-       .num_resources  = ARRAY_SIZE(omap_hdq_resources),
-       .resource       = omap_hdq_resources,
- };
- static inline void omap_hdq_init(void)
- {
-       if (cpu_is_omap2420())
-               return;
-       platform_device_register(&omap_hdq_dev);
- }
- #else
- static inline void omap_hdq_init(void) {}
- #endif
- /*---------------------------------------------------------------------------*/
  #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
        defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
  #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
@@@ -753,7 -646,6 +646,6 @@@ static int __init omap2_init_devices(vo
                omap_init_mcspi();
        }
        omap_init_pmu();
-       omap_hdq_init();
        omap_init_sti();
        omap_init_sham();
        omap_init_aes();
@@@ -772,7 -664,7 +664,7 @@@ static int __init omap_init_wdt(void
        char *oh_name = "wd_timer2";
        char *dev_name = "omap_wdt";
  
 -      if (!cpu_class_is_omap2())
 +      if (!cpu_class_is_omap2() || of_have_populated_dt())
                return 0;
  
        oh = omap_hwmod_lookup(oh_name);
index 3f21568f17535cb9aebaaff15ce0416e13d7ccb0,09f44d56e026f7b8292b740a867e09e102193c93..6ca8e519968d0c4e82e94fb384ab84da90a892b1
  #include "prm44xx.h"
  #include "prminst44xx.h"
  #include "mux.h"
+ #include "pm.h"
  
  /* Maximum microseconds to wait for OMAP module to softreset */
  #define MAX_MODULE_SOFTRESET_WAIT     10000
   */
  #define LINKS_PER_OCP_IF              2
  
 +/**
 + * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
 + * @enable_module: function to enable a module (via MODULEMODE)
 + * @disable_module: function to disable a module (via MODULEMODE)
 + *
 + * XXX Eventually this functionality will be hidden inside the PRM/CM
 + * device drivers.  Until then, this should avoid huge blocks of cpu_is_*()
 + * conditionals in this code.
 + */
 +struct omap_hwmod_soc_ops {
 +      void (*enable_module)(struct omap_hwmod *oh);
 +      int (*disable_module)(struct omap_hwmod *oh);
 +      int (*wait_target_ready)(struct omap_hwmod *oh);
 +      int (*assert_hardreset)(struct omap_hwmod *oh,
 +                              struct omap_hwmod_rst_info *ohri);
 +      int (*deassert_hardreset)(struct omap_hwmod *oh,
 +                                struct omap_hwmod_rst_info *ohri);
 +      int (*is_hardreset_asserted)(struct omap_hwmod *oh,
 +                                   struct omap_hwmod_rst_info *ohri);
 +      int (*init_clkdm)(struct omap_hwmod *oh);
 +};
 +
 +/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
 +static struct omap_hwmod_soc_ops soc_ops;
 +
  /* omap_hwmod_list contains all registered struct omap_hwmods */
  static LIST_HEAD(omap_hwmod_list);
  
  /* mpu_oh: used to add/remove MPU initiator from sleepdep list */
  static struct omap_hwmod *mpu_oh;
  
+ /* io_chain_lock: used to serialize reconfigurations of the I/O chain */
+ static DEFINE_SPINLOCK(io_chain_lock);
  /*
   * linkspace: ptr to a buffer that struct omap_hwmod_link records are
   * allocated from - used to reduce the number of small memory
@@@ -211,9 -190,6 +215,9 @@@ static struct omap_hwmod_link *linkspac
   */
  static unsigned short free_ls, max_ls, ls_supp;
  
 +/* inited: set to true once the hwmod code is initialized */
 +static bool inited;
 +
  /* Private functions */
  
  /**
@@@ -415,49 -391,6 +419,49 @@@ static int _set_softreset(struct omap_h
        return 0;
  }
  
 +/**
 + * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
 + * @oh: struct omap_hwmod *
 + *
 + * The DMADISABLE bit is a semi-automatic bit present in sysconfig register
 + * of some modules. When the DMA must perform read/write accesses, the
 + * DMADISABLE bit is cleared by the hardware. But when the DMA must stop
 + * for power management, software must set the DMADISABLE bit back to 1.
 + *
 + * Set the DMADISABLE bit in @v for hwmod @oh.  Returns -EINVAL upon
 + * error or 0 upon success.
 + */
 +static int _set_dmadisable(struct omap_hwmod *oh)
 +{
 +      u32 v;
 +      u32 dmadisable_mask;
 +
 +      if (!oh->class->sysc ||
 +          !(oh->class->sysc->sysc_flags & SYSC_HAS_DMADISABLE))
 +              return -EINVAL;
 +
 +      if (!oh->class->sysc->sysc_fields) {
 +              WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 +              return -EINVAL;
 +      }
 +
 +      /* clocks must be on for this operation */
 +      if (oh->_state != _HWMOD_STATE_ENABLED) {
 +              pr_warn("omap_hwmod: %s: dma can be disabled only from enabled state\n", oh->name);
 +              return -EINVAL;
 +      }
 +
 +      pr_debug("omap_hwmod: %s: setting DMADISABLE\n", oh->name);
 +
 +      v = oh->_sysc_cache;
 +      dmadisable_mask =
 +              (0x1 << oh->class->sysc->sysc_fields->dmadisable_shift);
 +      v |= dmadisable_mask;
 +      _write_sysconfig(v, oh);
 +
 +      return 0;
 +}
 +
  /**
   * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
   * @oh: struct omap_hwmod *
@@@ -842,19 -775,23 +846,19 @@@ static void _disable_optional_clocks(st
  }
  
  /**
 - * _enable_module - enable CLKCTRL modulemode on OMAP4
 + * _omap4_enable_module - enable CLKCTRL modulemode on OMAP4
   * @oh: struct omap_hwmod *
   *
   * Enables the PRCM module mode related to the hwmod @oh.
   * No return value.
   */
 -static void _enable_module(struct omap_hwmod *oh)
 +static void _omap4_enable_module(struct omap_hwmod *oh)
  {
 -      /* The module mode does not exist prior OMAP4 */
 -      if (cpu_is_omap24xx() || cpu_is_omap34xx())
 -              return;
 -
        if (!oh->clkdm || !oh->prcm.omap4.modulemode)
                return;
  
 -      pr_debug("omap_hwmod: %s: _enable_module: %d\n",
 -               oh->name, oh->prcm.omap4.modulemode);
 +      pr_debug("omap_hwmod: %s: %s: %d\n",
 +               oh->name, __func__, oh->prcm.omap4.modulemode);
  
        omap4_cminst_module_enable(oh->prcm.omap4.modulemode,
                                   oh->clkdm->prcm_partition,
   */
  static int _omap4_wait_target_disable(struct omap_hwmod *oh)
  {
 -      if (!cpu_is_omap44xx())
 -              return 0;
 -
 -      if (!oh)
 +      if (!oh || !oh->clkdm)
                return -EINVAL;
  
        if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
@@@ -1188,18 -1128,15 +1192,18 @@@ static struct omap_hwmod_addr_space * _
   * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
   * @oh: struct omap_hwmod *
   *
 - * If module is marked as SWSUP_SIDLE, force the module out of slave
 - * idle; otherwise, configure it for smart-idle.  If module is marked
 - * as SWSUP_MSUSPEND, force the module out of master standby;
 - * otherwise, configure it for smart-standby.  No return value.
 + * Ensure that the OCP_SYSCONFIG register for the IP block represented
 + * by @oh is set to indicate to the PRCM that the IP block is active.
 + * Usually this means placing the module into smart-idle mode and
 + * smart-standby, but if there is a bug in the automatic idle handling
 + * for the IP block, it may need to be placed into the force-idle or
 + * no-idle variants of these modes.  No return value.
   */
  static void _enable_sysc(struct omap_hwmod *oh)
  {
        u8 idlemode, sf;
        u32 v;
 +      bool clkdm_act;
  
        if (!oh->class->sysc)
                return;
        sf = oh->class->sysc->sysc_flags;
  
        if (sf & SYSC_HAS_SIDLEMODE) {
 -              idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
 -                      HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
 +              clkdm_act = ((oh->clkdm &&
 +                            oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) ||
 +                           (oh->_clk && oh->_clk->clkdm &&
 +                            oh->_clk->clkdm->flags & CLKDM_ACTIVE_WITH_MPU));
 +              if (clkdm_act && !(oh->class->sysc->idlemodes &
 +                                 (SIDLE_SMART | SIDLE_SMART_WKUP)))
 +                      idlemode = HWMOD_IDLEMODE_FORCE;
 +              else
 +                      idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
 +                              HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
                _set_slave_idlemode(oh, idlemode, &v);
        }
  
@@@ -1283,13 -1212,8 +1287,13 @@@ static void _idle_sysc(struct omap_hwmo
        sf = oh->class->sysc->sysc_flags;
  
        if (sf & SYSC_HAS_SIDLEMODE) {
 -              idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
 -                      HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
 +              /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */
 +              if (oh->flags & HWMOD_SWSUP_SIDLE ||
 +                  !(oh->class->sysc->idlemodes &
 +                    (SIDLE_SMART | SIDLE_SMART_WKUP)))
 +                      idlemode = HWMOD_IDLEMODE_FORCE;
 +              else
 +                      idlemode = HWMOD_IDLEMODE_SMART;
                _set_slave_idlemode(oh, idlemode, &v);
        }
  
@@@ -1365,20 -1289,24 +1369,20 @@@ static struct omap_hwmod *_lookup(cons
  
        return oh;
  }
 +
  /**
   * _init_clkdm - look up a clockdomain name, store pointer in omap_hwmod
   * @oh: struct omap_hwmod *
   *
   * Convert a clockdomain name stored in a struct omap_hwmod into a
   * clockdomain pointer, and save it into the struct omap_hwmod.
 - * return -EINVAL if clkdm_name does not exist or if the lookup failed.
 + * Return -EINVAL if the clkdm_name lookup failed.
   */
  static int _init_clkdm(struct omap_hwmod *oh)
  {
 -      if (cpu_is_omap24xx() || cpu_is_omap34xx())
 +      if (!oh->clkdm_name)
                return 0;
  
 -      if (!oh->clkdm_name) {
 -              pr_warning("omap_hwmod: %s: no clkdm_name\n", oh->name);
 -              return -EINVAL;
 -      }
 -
        oh->clkdm = clkdm_lookup(oh->clkdm_name);
        if (!oh->clkdm) {
                pr_warning("omap_hwmod: %s: could not associate to clkdm %s\n",
@@@ -1414,8 -1342,7 +1418,8 @@@ static int _init_clocks(struct omap_hwm
        ret |= _init_main_clk(oh);
        ret |= _init_interface_clks(oh);
        ret |= _init_opt_clks(oh);
 -      ret |= _init_clkdm(oh);
 +      if (soc_ops.init_clkdm)
 +              ret |= soc_ops.init_clkdm(oh);
  
        if (!ret)
                oh->_state = _HWMOD_STATE_CLKS_INITED;
        return ret;
  }
  
 -/**
 - * _wait_target_ready - wait for a module to leave slave idle
 - * @oh: struct omap_hwmod *
 - *
 - * Wait for a module @oh to leave slave idle.  Returns 0 if the module
 - * does not have an IDLEST bit or if the module successfully leaves
 - * slave idle; otherwise, pass along the return value of the
 - * appropriate *_cm*_wait_module_ready() function.
 - */
 -static int _wait_target_ready(struct omap_hwmod *oh)
 -{
 -      struct omap_hwmod_ocp_if *os;
 -      int ret;
 -
 -      if (!oh)
 -              return -EINVAL;
 -
 -      if (oh->flags & HWMOD_NO_IDLEST)
 -              return 0;
 -
 -      os = _find_mpu_rt_port(oh);
 -      if (!os)
 -              return 0;
 -
 -      /* XXX check module SIDLEMODE */
 -
 -      /* XXX check clock enable states */
 -
 -      if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
 -              ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
 -                                               oh->prcm.omap2.idlest_reg_id,
 -                                               oh->prcm.omap2.idlest_idle_bit);
 -      } else if (cpu_is_omap44xx()) {
 -              if (!oh->clkdm)
 -                      return -EINVAL;
 -
 -              ret = omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition,
 -                                                   oh->clkdm->cm_inst,
 -                                                   oh->clkdm->clkdm_offs,
 -                                                   oh->prcm.omap4.clkctrl_offs);
 -      } else {
 -              BUG();
 -      };
 -
 -      return ret;
 -}
 -
  /**
   * _lookup_hardreset - fill register bit info for this hwmod/reset line
   * @oh: struct omap_hwmod *
@@@ -1461,31 -1435,32 +1465,31 @@@ static u8 _lookup_hardreset(struct omap
   * @oh: struct omap_hwmod *
   * @name: name of the reset line to lookup and assert
   *
 - * Some IP like dsp, ipu or iva contain processor that require
 - * an HW reset line to be assert / deassert in order to enable fully
 - * the IP.
 + * Some IP like dsp, ipu or iva contain processor that require an HW
 + * reset line to be assert / deassert in order to enable fully the IP.
 + * Returns -EINVAL if @oh is null, -ENOSYS if we have no way of
 + * asserting the hardreset line on the currently-booted SoC, or passes
 + * along the return value from _lookup_hardreset() or the SoC's
 + * assert_hardreset code.
   */
  static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
  {
        struct omap_hwmod_rst_info ohri;
 -      u8 ret;
 +      u8 ret = -EINVAL;
  
        if (!oh)
                return -EINVAL;
  
 +      if (!soc_ops.assert_hardreset)
 +              return -ENOSYS;
 +
        ret = _lookup_hardreset(oh, name, &ohri);
        if (IS_ERR_VALUE(ret))
                return ret;
  
 -      if (cpu_is_omap24xx() || cpu_is_omap34xx())
 -              return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
 -                                                ohri.rst_shift);
 -      else if (cpu_is_omap44xx())
 -              return omap4_prminst_assert_hardreset(ohri.rst_shift,
 -                                oh->clkdm->pwrdm.ptr->prcm_partition,
 -                                oh->clkdm->pwrdm.ptr->prcm_offs,
 -                                oh->prcm.omap4.rstctrl_offs);
 -      else
 -              return -EINVAL;
 +      ret = soc_ops.assert_hardreset(oh, &ohri);
 +
 +      return ret;
  }
  
  /**
   * @oh: struct omap_hwmod *
   * @name: name of the reset line to look up and deassert
   *
 - * Some IP like dsp, ipu or iva contain processor that require
 - * an HW reset line to be assert / deassert in order to enable fully
 - * the IP.
 + * Some IP like dsp, ipu or iva contain processor that require an HW
 + * reset line to be assert / deassert in order to enable fully the IP.
 + * Returns -EINVAL if @oh is null, -ENOSYS if we have no way of
 + * deasserting the hardreset line on the currently-booted SoC, or passes
 + * along the return value from _lookup_hardreset() or the SoC's
 + * deassert_hardreset code.
   */
  static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
  {
        struct omap_hwmod_rst_info ohri;
 -      int ret;
 +      int ret = -EINVAL;
  
        if (!oh)
                return -EINVAL;
  
 +      if (!soc_ops.deassert_hardreset)
 +              return -ENOSYS;
 +
        ret = _lookup_hardreset(oh, name, &ohri);
        if (IS_ERR_VALUE(ret))
                return ret;
  
 -      if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
 -              ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
 -                                                 ohri.rst_shift,
 -                                                 ohri.st_shift);
 -      } else if (cpu_is_omap44xx()) {
 -              if (ohri.st_shift)
 -                      pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
 -                             oh->name, name);
 -              ret = omap4_prminst_deassert_hardreset(ohri.rst_shift,
 -                                oh->clkdm->pwrdm.ptr->prcm_partition,
 -                                oh->clkdm->pwrdm.ptr->prcm_offs,
 -                                oh->prcm.omap4.rstctrl_offs);
 -      } else {
 -              return -EINVAL;
 -      }
 -
 +      ret = soc_ops.deassert_hardreset(oh, &ohri);
        if (ret == -EBUSY)
                pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
  
   * @oh: struct omap_hwmod *
   * @name: name of the reset line to look up and read
   *
 - * Return the state of the reset line.
 + * Return the state of the reset line.  Returns -EINVAL if @oh is
 + * null, -ENOSYS if we have no way of reading the hardreset line
 + * status on the currently-booted SoC, or passes along the return
 + * value from _lookup_hardreset() or the SoC's is_hardreset_asserted
 + * code.
   */
  static int _read_hardreset(struct omap_hwmod *oh, const char *name)
  {
        struct omap_hwmod_rst_info ohri;
 -      u8 ret;
 +      u8 ret = -EINVAL;
  
        if (!oh)
                return -EINVAL;
  
 +      if (!soc_ops.is_hardreset_asserted)
 +              return -ENOSYS;
 +
        ret = _lookup_hardreset(oh, name, &ohri);
        if (IS_ERR_VALUE(ret))
                return ret;
  
 -      if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
 -              return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
 -                                                     ohri.st_shift);
 -      } else if (cpu_is_omap44xx()) {
 -              return omap4_prminst_is_hardreset_asserted(ohri.rst_shift,
 -                                oh->clkdm->pwrdm.ptr->prcm_partition,
 -                                oh->clkdm->pwrdm.ptr->prcm_offs,
 -                                oh->prcm.omap4.rstctrl_offs);
 -      } else {
 -              return -EINVAL;
 -      }
 +      return soc_ops.is_hardreset_asserted(oh, &ohri);
  }
  
  /**
@@@ -1588,6 -1575,10 +1592,6 @@@ static int _omap4_disable_module(struc
  {
        int v;
  
 -      /* The module mode does not exist prior OMAP4 */
 -      if (!cpu_is_omap44xx())
 -              return -EINVAL;
 -
        if (!oh->clkdm || !oh->prcm.omap4.modulemode)
                return -EINVAL;
  
@@@ -1711,17 -1702,11 +1715,17 @@@ dis_opt_clks
   * therefore have no OCP header registers to access.  Others (like the
   * IVA) have idiosyncratic reset sequences.  So for these relatively
   * rare cases, custom reset code can be supplied in the struct
 - * omap_hwmod_class .reset function pointer.  Passes along the return
 - * value from either _ocp_softreset() or the custom reset function -
 - * these must return -EINVAL if the hwmod cannot be reset this way or
 - * if the hwmod is in the wrong state, -ETIMEDOUT if the module did
 - * not reset in time, or 0 upon success.
 + * omap_hwmod_class .reset function pointer.
 + *
 + * _set_dmadisable() is called to set the DMADISABLE bit so that it
 + * does not prevent idling of the system. This is necessary for cases
 + * where ROMCODE/BOOTLOADER uses dma and transfers control to the
 + * kernel without disabling dma.
 + *
 + * Passes along the return value from either _ocp_softreset() or the
 + * custom reset function - these must return -EINVAL if the hwmod
 + * cannot be reset this way or if the hwmod is in the wrong state,
 + * -ETIMEDOUT if the module did not reset in time, or 0 upon success.
   */
  static int _reset(struct omap_hwmod *oh)
  {
                }
        }
  
 +      _set_dmadisable(oh);
 +
        /*
         * OCP_SYSCONFIG bits need to be reprogrammed after a
         * softreset.  The _enable() function should be split to avoid
        return r;
  }
  
+ /**
+  * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain
+  *
+  * Call the appropriate PRM function to clear any logged I/O chain
+  * wakeups and to reconfigure the chain.  This apparently needs to be
+  * done upon every mux change.  Since hwmods can be concurrently
+  * enabled and idled, hold a spinlock around the I/O chain
+  * reconfiguration sequence.  No return value.
+  *
+  * XXX When the PRM code is moved to drivers, this function can be removed,
+  * as the PRM infrastructure should abstract this.
+  */
+ static void _reconfigure_io_chain(void)
+ {
+       unsigned long flags;
+       spin_lock_irqsave(&io_chain_lock, flags);
+       if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl())
+               omap3xxx_prm_reconfigure_io_chain();
+       else if (cpu_is_omap44xx())
+               omap44xx_prm_reconfigure_io_chain();
+       spin_unlock_irqrestore(&io_chain_lock, flags);
+ }
  /**
   * _enable - enable an omap_hwmod
   * @oh: struct omap_hwmod *
@@@ -1814,8 -1823,10 +1844,10 @@@ static int _enable(struct omap_hwmod *o
        /* Mux pins for device runtime if populated */
        if (oh->mux && (!oh->mux->enabled ||
                        ((oh->_state == _HWMOD_STATE_IDLE) &&
-                        oh->mux->pads_dynamic)))
+                        oh->mux->pads_dynamic))) {
                omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
+               _reconfigure_io_chain();
+       }
  
        _add_initiator_dep(oh, mpu_oh);
  
        }
  
        _enable_clocks(oh);
 -      _enable_module(oh);
 +      if (soc_ops.enable_module)
 +              soc_ops.enable_module(oh);
  
 -      r = _wait_target_ready(oh);
 +      r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
 +              -EINVAL;
        if (!r) {
                /*
                 * Set the clockdomain to HW_AUTO only if the target is ready,
@@@ -1893,8 -1902,7 +1925,8 @@@ static int _idle(struct omap_hwmod *oh
                _idle_sysc(oh);
        _del_initiator_dep(oh, mpu_oh);
  
 -      _omap4_disable_module(oh);
 +      if (soc_ops.disable_module)
 +              soc_ops.disable_module(oh);
  
        /*
         * The module must be in idle mode before disabling any parents
                clkdm_hwmod_disable(oh->clkdm, oh);
  
        /* Mux pins for device idle if populated */
-       if (oh->mux && oh->mux->pads_dynamic)
+       if (oh->mux && oh->mux->pads_dynamic) {
                omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+               _reconfigure_io_chain();
+       }
  
        oh->_state = _HWMOD_STATE_IDLE;
  
@@@ -1999,8 -2009,7 +2033,8 @@@ static int _shutdown(struct omap_hwmod 
        if (oh->_state == _HWMOD_STATE_ENABLED) {
                _del_initiator_dep(oh, mpu_oh);
                /* XXX what about the other system initiators here? dma, dsp */
 -              _omap4_disable_module(oh);
 +              if (soc_ops.disable_module)
 +                      soc_ops.disable_module(oh);
                _disable_clocks(oh);
                if (oh->clkdm)
                        clkdm_hwmod_disable(oh->clkdm, oh);
@@@ -2456,194 -2465,6 +2490,194 @@@ static int __init _alloc_linkspace(stru
        return 0;
  }
  
 +/* Static functions intended only for use in soc_ops field function pointers */
 +
 +/**
 + * _omap2_wait_target_ready - wait for a module to leave slave idle
 + * @oh: struct omap_hwmod *
 + *
 + * Wait for a module @oh to leave slave idle.  Returns 0 if the module
 + * does not have an IDLEST bit or if the module successfully leaves
 + * slave idle; otherwise, pass along the return value of the
 + * appropriate *_cm*_wait_module_ready() function.
 + */
 +static int _omap2_wait_target_ready(struct omap_hwmod *oh)
 +{
 +      if (!oh)
 +              return -EINVAL;
 +
 +      if (oh->flags & HWMOD_NO_IDLEST)
 +              return 0;
 +
 +      if (!_find_mpu_rt_port(oh))
 +              return 0;
 +
 +      /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
 +
 +      return omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
 +                                        oh->prcm.omap2.idlest_reg_id,
 +                                        oh->prcm.omap2.idlest_idle_bit);
 +}
 +
 +/**
 + * _omap4_wait_target_ready - wait for a module to leave slave idle
 + * @oh: struct omap_hwmod *
 + *
 + * Wait for a module @oh to leave slave idle.  Returns 0 if the module
 + * does not have an IDLEST bit or if the module successfully leaves
 + * slave idle; otherwise, pass along the return value of the
 + * appropriate *_cm*_wait_module_ready() function.
 + */
 +static int _omap4_wait_target_ready(struct omap_hwmod *oh)
 +{
 +      if (!oh || !oh->clkdm)
 +              return -EINVAL;
 +
 +      if (oh->flags & HWMOD_NO_IDLEST)
 +              return 0;
 +
 +      if (!_find_mpu_rt_port(oh))
 +              return 0;
 +
 +      /* XXX check module SIDLEMODE, hardreset status */
 +
 +      return omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition,
 +                                            oh->clkdm->cm_inst,
 +                                            oh->clkdm->clkdm_offs,
 +                                            oh->prcm.omap4.clkctrl_offs);
 +}
 +
 +/**
 + * _omap2_assert_hardreset - call OMAP2 PRM hardreset fn with hwmod args
 + * @oh: struct omap_hwmod * to assert hardreset
 + * @ohri: hardreset line data
 + *
 + * Call omap2_prm_assert_hardreset() with parameters extracted from
 + * the hwmod @oh and the hardreset line data @ohri.  Only intended for
 + * use as an soc_ops function pointer.  Passes along the return value
 + * from omap2_prm_assert_hardreset().  XXX This function is scheduled
 + * for removal when the PRM code is moved into drivers/.
 + */
 +static int _omap2_assert_hardreset(struct omap_hwmod *oh,
 +                                 struct omap_hwmod_rst_info *ohri)
 +{
 +      return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
 +                                        ohri->rst_shift);
 +}
 +
 +/**
 + * _omap2_deassert_hardreset - call OMAP2 PRM hardreset fn with hwmod args
 + * @oh: struct omap_hwmod * to deassert hardreset
 + * @ohri: hardreset line data
 + *
 + * Call omap2_prm_deassert_hardreset() with parameters extracted from
 + * the hwmod @oh and the hardreset line data @ohri.  Only intended for
 + * use as an soc_ops function pointer.  Passes along the return value
 + * from omap2_prm_deassert_hardreset().  XXX This function is
 + * scheduled for removal when the PRM code is moved into drivers/.
 + */
 +static int _omap2_deassert_hardreset(struct omap_hwmod *oh,
 +                                   struct omap_hwmod_rst_info *ohri)
 +{
 +      return omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
 +                                          ohri->rst_shift,
 +                                          ohri->st_shift);
 +}
 +
 +/**
 + * _omap2_is_hardreset_asserted - call OMAP2 PRM hardreset fn with hwmod args
 + * @oh: struct omap_hwmod * to test hardreset
 + * @ohri: hardreset line data
 + *
 + * Call omap2_prm_is_hardreset_asserted() with parameters extracted
 + * from the hwmod @oh and the hardreset line data @ohri.  Only
 + * intended for use as an soc_ops function pointer.  Passes along the
 + * return value from omap2_prm_is_hardreset_asserted().  XXX This
 + * function is scheduled for removal when the PRM code is moved into
 + * drivers/.
 + */
 +static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh,
 +                                      struct omap_hwmod_rst_info *ohri)
 +{
 +      return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
 +                                             ohri->st_shift);
 +}
 +
 +/**
 + * _omap4_assert_hardreset - call OMAP4 PRM hardreset fn with hwmod args
 + * @oh: struct omap_hwmod * to assert hardreset
 + * @ohri: hardreset line data
 + *
 + * Call omap4_prminst_assert_hardreset() with parameters extracted
 + * from the hwmod @oh and the hardreset line data @ohri.  Only
 + * intended for use as an soc_ops function pointer.  Passes along the
 + * return value from omap4_prminst_assert_hardreset().  XXX This
 + * function is scheduled for removal when the PRM code is moved into
 + * drivers/.
 + */
 +static int _omap4_assert_hardreset(struct omap_hwmod *oh,
 +                                 struct omap_hwmod_rst_info *ohri)
 +{
 +      if (!oh->clkdm)
 +              return -EINVAL;
 +
 +      return omap4_prminst_assert_hardreset(ohri->rst_shift,
 +                              oh->clkdm->pwrdm.ptr->prcm_partition,
 +                              oh->clkdm->pwrdm.ptr->prcm_offs,
 +                              oh->prcm.omap4.rstctrl_offs);
 +}
 +
 +/**
 + * _omap4_deassert_hardreset - call OMAP4 PRM hardreset fn with hwmod args
 + * @oh: struct omap_hwmod * to deassert hardreset
 + * @ohri: hardreset line data
 + *
 + * Call omap4_prminst_deassert_hardreset() with parameters extracted
 + * from the hwmod @oh and the hardreset line data @ohri.  Only
 + * intended for use as an soc_ops function pointer.  Passes along the
 + * return value from omap4_prminst_deassert_hardreset().  XXX This
 + * function is scheduled for removal when the PRM code is moved into
 + * drivers/.
 + */
 +static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
 +                                   struct omap_hwmod_rst_info *ohri)
 +{
 +      if (!oh->clkdm)
 +              return -EINVAL;
 +
 +      if (ohri->st_shift)
 +              pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
 +                     oh->name, ohri->name);
 +      return omap4_prminst_deassert_hardreset(ohri->rst_shift,
 +                              oh->clkdm->pwrdm.ptr->prcm_partition,
 +                              oh->clkdm->pwrdm.ptr->prcm_offs,
 +                              oh->prcm.omap4.rstctrl_offs);
 +}
 +
 +/**
 + * _omap4_is_hardreset_asserted - call OMAP4 PRM hardreset fn with hwmod args
 + * @oh: struct omap_hwmod * to test hardreset
 + * @ohri: hardreset line data
 + *
 + * Call omap4_prminst_is_hardreset_asserted() with parameters
 + * extracted from the hwmod @oh and the hardreset line data @ohri.
 + * Only intended for use as an soc_ops function pointer.  Passes along
 + * the return value from omap4_prminst_is_hardreset_asserted().  XXX
 + * This function is scheduled for removal when the PRM code is moved
 + * into drivers/.
 + */
 +static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
 +                                      struct omap_hwmod_rst_info *ohri)
 +{
 +      if (!oh->clkdm)
 +              return -EINVAL;
 +
 +      return omap4_prminst_is_hardreset_asserted(ohri->rst_shift,
 +                              oh->clkdm->pwrdm.ptr->prcm_partition,
 +                              oh->clkdm->pwrdm.ptr->prcm_offs,
 +                              oh->prcm.omap4.rstctrl_offs);
 +}
 +
  /* Public functions */
  
  u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
@@@ -2776,18 -2597,12 +2810,18 @@@ int omap_hwmod_for_each(int (*fn)(struc
   *
   * Intended to be called early in boot before the clock framework is
   * initialized.  If @ois is not null, will register all omap_hwmods
 - * listed in @ois that are valid for this chip.  Returns 0.
 + * listed in @ois that are valid for this chip.  Returns -EINVAL if
 + * omap_hwmod_init() hasn't been called before calling this function,
 + * -ENOMEM if the link memory area can't be allocated, or 0 upon
 + * success.
   */
  int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois)
  {
        int r, i;
  
 +      if (!inited)
 +              return -EINVAL;
 +
        if (!ois)
                return 0;
  
@@@ -3620,47 -3435,3 +3654,47 @@@ int omap_hwmod_pad_route_irq(struct oma
  
        return 0;
  }
 +
 +/**
 + * omap_hwmod_init - initialize the hwmod code
 + *
 + * Sets up some function pointers needed by the hwmod code to operate on the
 + * currently-booted SoC.  Intended to be called once during kernel init
 + * before any hwmods are registered.  No return value.
 + */
 +void __init omap_hwmod_init(void)
 +{
 +      if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
 +              soc_ops.wait_target_ready = _omap2_wait_target_ready;
 +              soc_ops.assert_hardreset = _omap2_assert_hardreset;
 +              soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
 +              soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
 +      } else if (cpu_is_omap44xx() || soc_is_omap54xx()) {
 +              soc_ops.enable_module = _omap4_enable_module;
 +              soc_ops.disable_module = _omap4_disable_module;
 +              soc_ops.wait_target_ready = _omap4_wait_target_ready;
 +              soc_ops.assert_hardreset = _omap4_assert_hardreset;
 +              soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
 +              soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
 +              soc_ops.init_clkdm = _init_clkdm;
 +      } else {
 +              WARN(1, "omap_hwmod: unknown SoC type\n");
 +      }
 +
 +      inited = true;
 +}
 +
 +/**
 + * omap_hwmod_get_main_clk - get pointer to main clock name
 + * @oh: struct omap_hwmod *
 + *
 + * Returns the main clock name assocated with @oh upon success,
 + * or NULL if @oh is NULL.
 + */
 +const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh)
 +{
 +      if (!oh)
 +              return NULL;
 +
 +      return oh->main_clk;
 +}
index cdb9637aab19d26d5b1acf1a7601a122b963663c,ab1f40125ffd3c65bdb13c7c195f0a2a2c07108a..c9e38200216b2985cb3ef997e530891b8e3b19dd
@@@ -14,6 -14,8 +14,8 @@@
   *
   * XXX these should be marked initdata for multi-OMAP kernels
   */
+ #include <linux/power/smartreflex.h>
  #include <plat/omap_hwmod.h>
  #include <mach/irqs.h>
  #include <plat/cpu.h>
@@@ -29,8 -31,6 +31,6 @@@
  #include <plat/dmtimer.h>
  
  #include "omap_hwmod_common_data.h"
- #include "smartreflex.h"
  #include "prm-regbits-34xx.h"
  #include "cm-regbits-34xx.h"
  #include "wd_timer.h"
@@@ -129,6 -129,7 +129,6 @@@ static struct omap_hwmod_class_sysconfi
  static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = {
        .name = "timer",
        .sysc = &omap3xxx_timer_1ms_sysc,
 -      .rev = OMAP_TIMER_IP_VERSION_1,
  };
  
  static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
  static struct omap_hwmod_class omap3xxx_timer_hwmod_class = {
        .name = "timer",
        .sysc = &omap3xxx_timer_sysc,
 -      .rev =  OMAP_TIMER_IP_VERSION_1,
  };
  
  /* secure timers dev attribute */
  static struct omap_timer_capability_dev_attr capability_secure_dev_attr = {
 -      .timer_capability       = OMAP_TIMER_SECURE,
 +      .timer_capability       = OMAP_TIMER_ALWON | OMAP_TIMER_SECURE,
  };
  
  /* always-on timers dev attribute */
@@@ -193,6 -195,7 +193,6 @@@ static struct omap_hwmod omap3xxx_timer
                        .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
        .class          = &omap3xxx_timer_1ms_hwmod_class,
  };
  
@@@ -210,6 -213,7 +210,6 @@@ static struct omap_hwmod omap3xxx_timer
                        .idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
        .class          = &omap3xxx_timer_hwmod_class,
  };
  
@@@ -227,6 -231,7 +227,6 @@@ static struct omap_hwmod omap3xxx_timer
                        .idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
        .class          = &omap3xxx_timer_hwmod_class,
  };
  
@@@ -244,6 -249,7 +244,6 @@@ static struct omap_hwmod omap3xxx_timer
                        .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
        .class          = &omap3xxx_timer_hwmod_class,
  };
  
@@@ -261,6 -267,7 +261,6 @@@ static struct omap_hwmod omap3xxx_timer
                        .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
        .class          = &omap3xxx_timer_hwmod_class,
  };
  
@@@ -278,6 -285,7 +278,6 @@@ static struct omap_hwmod omap3xxx_timer
                        .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
        .class          = &omap3xxx_timer_hwmod_class,
  };
  
@@@ -519,27 -527,11 +519,27 @@@ static struct omap_hwmod omap36xx_uart4
  
  static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = {
        { .irq = INT_35XX_UART4_IRQ, },
 +      { .irq = -1 }
  };
  
  static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = {
        { .name = "rx", .dma_req = AM35XX_DMA_UART4_RX, },
        { .name = "tx", .dma_req = AM35XX_DMA_UART4_TX, },
 +      { .dma_req = -1 }
 +};
 +
 +/*
 + * XXX AM35xx UART4 cannot complete its softreset without uart1_fck or
 + * uart2_fck being enabled.  So we add uart1_fck as an optional clock,
 + * below, and set the HWMOD_CONTROL_OPT_CLKS_IN_RESET.  This really
 + * should not be needed.  The functional clock structure of the AM35xx
 + * UART4 is extremely unclear and opaque; it is unclear what the role
 + * of uart1/2_fck is for the UART4.  Any clarification from either
 + * empirical testing or the AM3505/3517 hardware designers would be
 + * most welcome.
 + */
 +static struct omap_hwmod_opt_clk am35xx_uart4_opt_clks[] = {
 +      { .role = "softreset_uart1_fck", .clk = "uart1_fck" },
  };
  
  static struct omap_hwmod am35xx_uart4_hwmod = {
                .omap2 = {
                        .module_offs = CORE_MOD,
                        .prcm_reg_id = 1,
 -                      .module_bit = OMAP3430_EN_UART4_SHIFT,
 +                      .module_bit = AM35XX_EN_UART4_SHIFT,
                        .idlest_reg_id = 1,
 -                      .idlest_idle_bit = OMAP3430_EN_UART4_SHIFT,
 +                      .idlest_idle_bit = AM35XX_ST_UART4_SHIFT,
                },
        },
 +      .opt_clks       = am35xx_uart4_opt_clks,
 +      .opt_clks_cnt   = ARRAY_SIZE(am35xx_uart4_opt_clks),
 +      .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .class          = &omap2_uart_class,
  };
  
@@@ -1085,17 -1074,6 +1085,17 @@@ static struct omap_hwmod_class omap3xxx
        .rev  = MCBSP_CONFIG_TYPE3,
  };
  
 +/* McBSP functional clock mapping */
 +static struct omap_hwmod_opt_clk mcbsp15_opt_clks[] = {
 +      { .role = "pad_fck", .clk = "mcbsp_clks" },
 +      { .role = "prcm_fck", .clk = "core_96m_fck" },
 +};
 +
 +static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = {
 +      { .role = "pad_fck", .clk = "mcbsp_clks" },
 +      { .role = "prcm_fck", .clk = "per_96m_fck" },
 +};
 +
  /* mcbsp1 */
  static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = {
        { .name = "common", .irq = 16 },
@@@ -1119,8 -1097,6 +1119,8 @@@ static struct omap_hwmod omap3xxx_mcbsp
                        .idlest_idle_bit = OMAP3430_ST_MCBSP1_SHIFT,
                },
        },
 +      .opt_clks       = mcbsp15_opt_clks,
 +      .opt_clks_cnt   = ARRAY_SIZE(mcbsp15_opt_clks),
  };
  
  /* mcbsp2 */
@@@ -1150,8 -1126,6 +1150,8 @@@ static struct omap_hwmod omap3xxx_mcbsp
                        .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT,
                },
        },
 +      .opt_clks       = mcbsp234_opt_clks,
 +      .opt_clks_cnt   = ARRAY_SIZE(mcbsp234_opt_clks),
        .dev_attr       = &omap34xx_mcbsp2_dev_attr,
  };
  
@@@ -1182,8 -1156,6 +1182,8 @@@ static struct omap_hwmod omap3xxx_mcbsp
                        .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT,
                },
        },
 +      .opt_clks       = mcbsp234_opt_clks,
 +      .opt_clks_cnt   = ARRAY_SIZE(mcbsp234_opt_clks),
        .dev_attr       = &omap34xx_mcbsp3_dev_attr,
  };
  
@@@ -1216,8 -1188,6 +1216,8 @@@ static struct omap_hwmod omap3xxx_mcbsp
                        .idlest_idle_bit = OMAP3430_ST_MCBSP4_SHIFT,
                },
        },
 +      .opt_clks       = mcbsp234_opt_clks,
 +      .opt_clks_cnt   = ARRAY_SIZE(mcbsp234_opt_clks),
  };
  
  /* mcbsp5 */
@@@ -1249,8 -1219,6 +1249,8 @@@ static struct omap_hwmod omap3xxx_mcbsp
                        .idlest_idle_bit = OMAP3430_ST_MCBSP5_SHIFT,
                },
        },
 +      .opt_clks       = mcbsp15_opt_clks,
 +      .opt_clks_cnt   = ARRAY_SIZE(mcbsp15_opt_clks),
  };
  
  /* 'mcbsp sidetone' class */
@@@ -1357,7 -1325,7 +1357,7 @@@ static struct omap_hwmod_irq_info omap3
  };
  
  static struct omap_hwmod omap34xx_sr1_hwmod = {
-       .name           = "sr1",
+       .name           = "smartreflex_mpu_iva",
        .class          = &omap34xx_smartreflex_hwmod_class,
        .main_clk       = "sr1_fck",
        .prcm           = {
  };
  
  static struct omap_hwmod omap36xx_sr1_hwmod = {
-       .name           = "sr1",
+       .name           = "smartreflex_mpu_iva",
        .class          = &omap36xx_smartreflex_hwmod_class,
        .main_clk       = "sr1_fck",
        .prcm           = {
@@@ -1402,7 -1370,7 +1402,7 @@@ static struct omap_hwmod_irq_info omap3
  };
  
  static struct omap_hwmod omap34xx_sr2_hwmod = {
-       .name           = "sr2",
+       .name           = "smartreflex_core",
        .class          = &omap34xx_smartreflex_hwmod_class,
        .main_clk       = "sr2_fck",
        .prcm           = {
  };
  
  static struct omap_hwmod omap36xx_sr2_hwmod = {
-       .name           = "sr2",
+       .name           = "smartreflex_core",
        .class          = &omap36xx_smartreflex_hwmod_class,
        .main_clk       = "sr2_fck",
        .prcm           = {
@@@ -1670,20 -1638,25 +1670,20 @@@ static struct omap_hwmod omap3xxx_usbhs
  
  /* usb_otg_hs */
  static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = {
 -
        { .name = "mc", .irq = 71 },
        { .irq = -1 }
  };
  
  static struct omap_hwmod_class am35xx_usbotg_class = {
        .name = "am35xx_usbotg",
 -      .sysc = NULL,
  };
  
  static struct omap_hwmod am35xx_usbhsotg_hwmod = {
        .name           = "am35x_otg_hs",
        .mpu_irqs       = am35xx_usbhsotg_mpu_irqs,
 -      .main_clk       = NULL,
 -      .prcm = {
 -              .omap2 = {
 -              },
 -      },
 +      .main_clk       = "hsotgusb_fck",
        .class          = &am35xx_usbotg_class,
 +      .flags          = HWMOD_NO_IDLEST,
  };
  
  /* MMC/SD/SDIO common */
@@@ -2124,10 -2097,9 +2124,10 @@@ static struct omap_hwmod_ocp_if omap3xx
  static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = {
        .master         = &am35xx_usbhsotg_hwmod,
        .slave          = &omap3xxx_l3_main_hwmod,
 -      .clk            = "core_l3_ick",
 +      .clk            = "hsotgusb_ick",
        .user           = OCP_USER_MPU,
  };
 +
  /* L4_CORE -> L4_WKUP interface */
  static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
        .master = &omap3xxx_l4_core_hwmod,
@@@ -2271,7 -2243,6 +2271,7 @@@ static struct omap_hwmod_addr_space am3
                .pa_end         = OMAP3_UART4_AM35XX_BASE + SZ_1K - 1,
                .flags          = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
        },
 +      { }
  };
  
  static struct omap_hwmod_ocp_if am35xx_l4_core__uart4 = {
@@@ -2422,7 -2393,7 +2422,7 @@@ static struct omap_hwmod_addr_space am3
  static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &am35xx_usbhsotg_hwmod,
 -      .clk            = "l4_ick",
 +      .clk            = "hsotgusb_ick",
        .addr           = am35xx_usbhsotg_addrs,
        .user           = OCP_USER_MPU,
  };
@@@ -3167,107 -3138,6 +3167,107 @@@ static struct omap_hwmod_ocp_if omap3xx
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
  };
  
 +/* am35xx has Davinci MDIO & EMAC */
 +static struct omap_hwmod_class am35xx_mdio_class = {
 +      .name = "davinci_mdio",
 +};
 +
 +static struct omap_hwmod am35xx_mdio_hwmod = {
 +      .name           = "davinci_mdio",
 +      .class          = &am35xx_mdio_class,
 +      .flags          = HWMOD_NO_IDLEST,
 +};
 +
 +/*
 + * XXX Should be connected to an IPSS hwmod, not the L3 directly;
 + * but this will probably require some additional hwmod core support,
 + * so is left as a future to-do item.
 + */
 +static struct omap_hwmod_ocp_if am35xx_mdio__l3 = {
 +      .master         = &am35xx_mdio_hwmod,
 +      .slave          = &omap3xxx_l3_main_hwmod,
 +      .clk            = "emac_fck",
 +      .user           = OCP_USER_MPU,
 +};
 +
 +static struct omap_hwmod_addr_space am35xx_mdio_addrs[] = {
 +      {
 +              .pa_start       = AM35XX_IPSS_MDIO_BASE,
 +              .pa_end         = AM35XX_IPSS_MDIO_BASE + SZ_4K - 1,
 +              .flags          = ADDR_TYPE_RT,
 +      },
 +      { }
 +};
 +
 +/* l4_core -> davinci mdio  */
 +/*
 + * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
 + * but this will probably require some additional hwmod core support,
 + * so is left as a future to-do item.
 + */
 +static struct omap_hwmod_ocp_if am35xx_l4_core__mdio = {
 +      .master         = &omap3xxx_l4_core_hwmod,
 +      .slave          = &am35xx_mdio_hwmod,
 +      .clk            = "emac_fck",
 +      .addr           = am35xx_mdio_addrs,
 +      .user           = OCP_USER_MPU,
 +};
 +
 +static struct omap_hwmod_irq_info am35xx_emac_mpu_irqs[] = {
 +      { .name = "rxthresh",   .irq = INT_35XX_EMAC_C0_RXTHRESH_IRQ },
 +      { .name = "rx_pulse",   .irq = INT_35XX_EMAC_C0_RX_PULSE_IRQ },
 +      { .name = "tx_pulse",   .irq = INT_35XX_EMAC_C0_TX_PULSE_IRQ },
 +      { .name = "misc_pulse", .irq = INT_35XX_EMAC_C0_MISC_PULSE_IRQ },
 +      { .irq = -1 }
 +};
 +
 +static struct omap_hwmod_class am35xx_emac_class = {
 +      .name = "davinci_emac",
 +};
 +
 +static struct omap_hwmod am35xx_emac_hwmod = {
 +      .name           = "davinci_emac",
 +      .mpu_irqs       = am35xx_emac_mpu_irqs,
 +      .class          = &am35xx_emac_class,
 +      .flags          = HWMOD_NO_IDLEST,
 +};
 +
 +/* l3_core -> davinci emac interface */
 +/*
 + * XXX Should be connected to an IPSS hwmod, not the L3 directly;
 + * but this will probably require some additional hwmod core support,
 + * so is left as a future to-do item.
 + */
 +static struct omap_hwmod_ocp_if am35xx_emac__l3 = {
 +      .master         = &am35xx_emac_hwmod,
 +      .slave          = &omap3xxx_l3_main_hwmod,
 +      .clk            = "emac_ick",
 +      .user           = OCP_USER_MPU,
 +};
 +
 +static struct omap_hwmod_addr_space am35xx_emac_addrs[] = {
 +      {
 +              .pa_start       = AM35XX_IPSS_EMAC_BASE,
 +              .pa_end         = AM35XX_IPSS_EMAC_BASE + 0x30000 - 1,
 +              .flags          = ADDR_TYPE_RT,
 +      },
 +      { }
 +};
 +
 +/* l4_core -> davinci emac  */
 +/*
 + * XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
 + * but this will probably require some additional hwmod core support,
 + * so is left as a future to-do item.
 + */
 +static struct omap_hwmod_ocp_if am35xx_l4_core__emac = {
 +      .master         = &omap3xxx_l4_core_hwmod,
 +      .slave          = &am35xx_emac_hwmod,
 +      .clk            = "emac_ick",
 +      .addr           = am35xx_emac_addrs,
 +      .user           = OCP_USER_MPU,
 +};
 +
  static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l3_main__l4_core,
        &omap3xxx_l3_main__l4_per,
@@@ -3396,10 -3266,6 +3396,10 @@@ static struct omap_hwmod_ocp_if *am35xx
        &omap3xxx_l4_core__usb_tll_hs,
        &omap3xxx_l4_core__es3plus_mmc1,
        &omap3xxx_l4_core__es3plus_mmc2,
 +      &am35xx_mdio__l3,
 +      &am35xx_l4_core__mdio,
 +      &am35xx_emac__l3,
 +      &am35xx_l4_core__emac,
        NULL
  };
  
@@@ -3417,8 -3283,6 +3417,8 @@@ int __init omap3xxx_hwmod_init(void
        struct omap_hwmod_ocp_if **h = NULL;
        unsigned int rev;
  
 +      omap_hwmod_init();
 +
        /* Register hwmod links common to all OMAP3 */
        r = omap_hwmod_register_links(omap3xxx_hwmod_ocp_ifs);
        if (r < 0)
index 5c2ce7e7783828737ab9abaf41f1b20325391ebe,6b564c9c2cea60a3f89493ede4fe3be14488b082..242aee498ceb21466e33ee04035ed63147e4a615
@@@ -19,6 -19,7 +19,7 @@@
   */
  
  #include <linux/io.h>
+ #include <linux/power/smartreflex.h>
  
  #include <plat/omap_hwmod.h>
  #include <plat/cpu.h>
@@@ -32,8 -33,6 +33,6 @@@
  #include <plat/common.h>
  
  #include "omap_hwmod_common_data.h"
- #include "smartreflex.h"
  #include "cm1_44xx.h"
  #include "cm2_44xx.h"
  #include "prm44xx.h"
@@@ -1928,7 -1927,7 +1927,7 @@@ static struct omap_hwmod_dma_info omap4
  
  static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = {
        { .role = "pad_fck", .clk = "pad_clks_ck" },
 -      { .role = "prcm_clk", .clk = "mcbsp1_sync_mux_ck" },
 +      { .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" },
  };
  
  static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
@@@ -1963,7 -1962,7 +1962,7 @@@ static struct omap_hwmod_dma_info omap4
  
  static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = {
        { .role = "pad_fck", .clk = "pad_clks_ck" },
 -      { .role = "prcm_clk", .clk = "mcbsp2_sync_mux_ck" },
 +      { .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" },
  };
  
  static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
@@@ -1998,7 -1997,7 +1997,7 @@@ static struct omap_hwmod_dma_info omap4
  
  static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = {
        { .role = "pad_fck", .clk = "pad_clks_ck" },
 -      { .role = "prcm_clk", .clk = "mcbsp3_sync_mux_ck" },
 +      { .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" },
  };
  
  static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
@@@ -2033,7 -2032,7 +2032,7 @@@ static struct omap_hwmod_dma_info omap4
  
  static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = {
        { .role = "pad_fck", .clk = "pad_clks_ck" },
 -      { .role = "prcm_clk", .clk = "mcbsp4_sync_mux_ck" },
 +      { .role = "prcm_fck", .clk = "mcbsp4_sync_mux_ck" },
  };
  
  static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
@@@ -2544,12 -2543,14 +2543,12 @@@ static struct omap_hwmod omap44xx_prcm_
  static struct omap_hwmod omap44xx_cm_core_aon_hwmod = {
        .name           = "cm_core_aon",
        .class          = &omap44xx_prcm_hwmod_class,
 -      .clkdm_name     = "cm_clkdm",
  };
  
  /* cm_core */
  static struct omap_hwmod omap44xx_cm_core_hwmod = {
        .name           = "cm_core",
        .class          = &omap44xx_prcm_hwmod_class,
 -      .clkdm_name     = "cm_clkdm",
  };
  
  /* prm */
@@@ -2566,6 -2567,7 +2565,6 @@@ static struct omap_hwmod_rst_info omap4
  static struct omap_hwmod omap44xx_prm_hwmod = {
        .name           = "prm",
        .class          = &omap44xx_prcm_hwmod_class,
 -      .clkdm_name     = "prm_clkdm",
        .mpu_irqs       = omap44xx_prm_irqs,
        .rst_lines      = omap44xx_prm_resets,
        .rst_lines_cnt  = ARRAY_SIZE(omap44xx_prm_resets),
@@@ -2944,6 -2946,7 +2943,6 @@@ static struct omap_hwmod omap44xx_timer
                        .modulemode   = MODULEMODE_SWCTRL,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
  };
  
  /* timer3 */
@@@ -2965,6 -2968,7 +2964,6 @@@ static struct omap_hwmod omap44xx_timer
                        .modulemode   = MODULEMODE_SWCTRL,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
  };
  
  /* timer4 */
@@@ -2986,6 -2990,7 +2985,6 @@@ static struct omap_hwmod omap44xx_timer
                        .modulemode   = MODULEMODE_SWCTRL,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
  };
  
  /* timer5 */
@@@ -3007,6 -3012,7 +3006,6 @@@ static struct omap_hwmod omap44xx_timer
                        .modulemode   = MODULEMODE_SWCTRL,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
  };
  
  /* timer6 */
@@@ -3029,6 -3035,7 +3028,6 @@@ static struct omap_hwmod omap44xx_timer
                        .modulemode   = MODULEMODE_SWCTRL,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
  };
  
  /* timer7 */
@@@ -3050,6 -3057,7 +3049,6 @@@ static struct omap_hwmod omap44xx_timer
                        .modulemode   = MODULEMODE_SWCTRL,
                },
        },
 -      .dev_attr       = &capability_alwon_dev_attr,
  };
  
  /* timer8 */
@@@ -3855,7 -3863,7 +3854,7 @@@ static struct omap_hwmod_ocp_if omap44x
  };
  
  /* usb_host_fs -> l3_main_2 */
 -static struct omap_hwmod_ocp_if omap44xx_usb_host_fs__l3_main_2 = {
 +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_usb_host_fs__l3_main_2 = {
        .master         = &omap44xx_usb_host_fs_hwmod,
        .slave          = &omap44xx_l3_main_2_hwmod,
        .clk            = "l3_div_ck",
@@@ -3913,7 -3921,7 +3912,7 @@@ static struct omap_hwmod_ocp_if omap44x
  };
  
  /* aess -> l4_abe */
 -static struct omap_hwmod_ocp_if omap44xx_aess__l4_abe = {
 +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_aess__l4_abe = {
        .master         = &omap44xx_aess_hwmod,
        .slave          = &omap44xx_l4_abe_hwmod,
        .clk            = "ocp_abe_iclk",
@@@ -4004,7 -4012,7 +4003,7 @@@ static struct omap_hwmod_addr_space oma
  };
  
  /* l4_abe -> aess */
 -static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess = {
 +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = {
        .master         = &omap44xx_l4_abe_hwmod,
        .slave          = &omap44xx_aess_hwmod,
        .clk            = "ocp_abe_iclk",
@@@ -4022,7 -4030,7 +4021,7 @@@ static struct omap_hwmod_addr_space oma
  };
  
  /* l4_abe -> aess (dma) */
 -static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess_dma = {
 +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess_dma = {
        .master         = &omap44xx_l4_abe_hwmod,
        .slave          = &omap44xx_aess_hwmod,
        .clk            = "ocp_abe_iclk",
@@@ -5848,7 -5856,7 +5847,7 @@@ static struct omap_hwmod_addr_space oma
  };
  
  /* l4_cfg -> usb_host_fs */
 -static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_fs = {
 +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_cfg__usb_host_fs = {
        .master         = &omap44xx_l4_cfg_hwmod,
        .slave          = &omap44xx_usb_host_fs_hwmod,
        .clk            = "l4_div_ck",
@@@ -6005,13 -6013,13 +6004,13 @@@ static struct omap_hwmod_ocp_if *omap44
        &omap44xx_iva__l3_main_2,
        &omap44xx_l3_main_1__l3_main_2,
        &omap44xx_l4_cfg__l3_main_2,
 -      &omap44xx_usb_host_fs__l3_main_2,
 +      /* &omap44xx_usb_host_fs__l3_main_2, */
        &omap44xx_usb_host_hs__l3_main_2,
        &omap44xx_usb_otg_hs__l3_main_2,
        &omap44xx_l3_main_1__l3_main_3,
        &omap44xx_l3_main_2__l3_main_3,
        &omap44xx_l4_cfg__l3_main_3,
 -      &omap44xx_aess__l4_abe,
 +      /* &omap44xx_aess__l4_abe, */
        &omap44xx_dsp__l4_abe,
        &omap44xx_l3_main_1__l4_abe,
        &omap44xx_mpu__l4_abe,
        &omap44xx_l4_cfg__l4_wkup,
        &omap44xx_mpu__mpu_private,
        &omap44xx_l4_cfg__ocp_wp_noc,
 -      &omap44xx_l4_abe__aess,
 -      &omap44xx_l4_abe__aess_dma,
 +      /* &omap44xx_l4_abe__aess, */
 +      /* &omap44xx_l4_abe__aess_dma, */
        &omap44xx_l3_main_2__c2c,
        &omap44xx_l4_wkup__counter_32k,
        &omap44xx_l4_cfg__ctrl_module_core,
        &omap44xx_l4_per__uart2,
        &omap44xx_l4_per__uart3,
        &omap44xx_l4_per__uart4,
 -      &omap44xx_l4_cfg__usb_host_fs,
 +      /* &omap44xx_l4_cfg__usb_host_fs, */
        &omap44xx_l4_cfg__usb_host_hs,
        &omap44xx_l4_cfg__usb_otg_hs,
        &omap44xx_l4_cfg__usb_tll_hs,
  
  int __init omap44xx_hwmod_init(void)
  {
 +      omap_hwmod_init();
        return omap_hwmod_register_links(omap44xx_hwmod_ocp_ifs);
  }
  
diff --combined arch/arm/mach-omap2/pm.h
index ab04d3bba2e756dc573c621a8fe68058402be2bb,9fac67d6c985a3ca36489f8a536e385f0b60eb86..686137d164dac9faee69b2293e524fa08c69bcea
  
  #include "powerdomain.h"
  
 +#ifdef CONFIG_CPU_IDLE
 +extern int __init omap3_idle_init(void);
 +extern int __init omap4_idle_init(void);
 +#else
 +static inline int omap3_idle_init(void)
 +{
 +      return 0;
 +}
 +
 +static inline int omap4_idle_init(void)
 +{
 +      return 0;
 +}
 +#endif
 +
  extern void *omap3_secure_ram_storage;
  extern void omap3_pm_off_mode_enable(int);
  extern void omap_sram_idle(void);
  extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 -extern int omap3_idle_init(void);
 -extern int omap4_idle_init(void);
  extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
  extern int (*omap_pm_suspend)(void);
  
@@@ -101,7 -88,7 +101,7 @@@ extern void enable_omap3630_toggle_l2_o
  static inline void enable_omap3630_toggle_l2_on_restore(void) { }
  #endif                /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
  
- #ifdef CONFIG_OMAP_SMARTREFLEX
+ #ifdef CONFIG_POWER_AVS_OMAP
  extern int omap_devinit_smartreflex(void);
  extern void omap_enable_smartreflex_on_init(void);
  #else
index 9b463c987508740e876749674c4b5e63e94f53b6,e63fdd02c6f50599f191343b4e9295cce92b289a..e4fc88c65dbd6a868b6dac07229de3ee3b7791ea
@@@ -70,34 -70,6 +70,6 @@@ void (*omap3_do_wfi_sram)(void)
  
  static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
  static struct powerdomain *core_pwrdm, *per_pwrdm;
- static struct powerdomain *cam_pwrdm;
- static void omap3_enable_io_chain(void)
- {
-       int timeout = 0;
-       omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-                                  PM_WKEN);
-       /* Do a readback to assure write has been done */
-       omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
-       while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
-                OMAP3430_ST_IO_CHAIN_MASK)) {
-               timeout++;
-               if (timeout > 1000) {
-                       pr_err("Wake up daisy chain activation failed.\n");
-                       return;
-               }
-               omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
-                                          WKUP_MOD, PM_WKEN);
-       }
- }
- static void omap3_disable_io_chain(void)
- {
-       omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-                                    PM_WKEN);
- }
  
  static void omap3_core_save_context(void)
  {
@@@ -299,24 -271,22 +271,22 @@@ void omap_sram_idle(void
        /* Enable IO-PAD and IO-CHAIN wakeups */
        per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
        core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
-       if (omap3_has_io_wakeup() &&
-           (per_next_state < PWRDM_POWER_ON ||
-            core_next_state < PWRDM_POWER_ON)) {
-               omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
-               if (omap3_has_io_chain_ctrl())
-                       omap3_enable_io_chain();
-       }
  
-       pwrdm_pre_transition();
+       if (mpu_next_state < PWRDM_POWER_ON) {
+               pwrdm_pre_transition(mpu_pwrdm);
+               pwrdm_pre_transition(neon_pwrdm);
+       }
  
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
+               pwrdm_pre_transition(per_pwrdm);
                per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
                omap2_gpio_prepare_for_idle(per_going_off);
        }
  
        /* CORE */
        if (core_next_state < PWRDM_POWER_ON) {
+               pwrdm_pre_transition(core_pwrdm);
                if (core_next_state == PWRDM_POWER_OFF) {
                        omap3_core_save_context();
                        omap3_cm_save_context();
                        omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
                                               OMAP3430_GR_MOD,
                                               OMAP3_PRM_VOLTCTRL_OFFSET);
+               pwrdm_post_transition(core_pwrdm);
        }
        omap3_intc_resume_idle();
  
-       pwrdm_post_transition();
        /* PER */
-       if (per_next_state < PWRDM_POWER_ON)
+       if (per_next_state < PWRDM_POWER_ON) {
                omap2_gpio_resume_after_idle();
-       /* Disable IO-PAD and IO-CHAIN wakeup */
-       if (omap3_has_io_wakeup() &&
-           (per_next_state < PWRDM_POWER_ON ||
-            core_next_state < PWRDM_POWER_ON)) {
-               omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
-                                            PM_WKEN);
-               if (omap3_has_io_chain_ctrl())
-                       omap3_disable_io_chain();
+               pwrdm_post_transition(per_pwrdm);
        }
  
-       clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
+       if (mpu_next_state < PWRDM_POWER_ON) {
+               pwrdm_post_transition(mpu_pwrdm);
+               pwrdm_post_transition(neon_pwrdm);
+       }
  }
  
  static void omap3_pm_idle(void)
@@@ -581,13 -545,10 +545,13 @@@ static void __init prcm_setup_regs(void
                          OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
  
        /* Don't attach IVA interrupts */
 -      omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
 -      omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
 -      omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
 -      omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
 +      if (omap3_has_iva()) {
 +              omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
 +              omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
 +              omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
 +              omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD,
 +                                      OMAP3430_PM_IVAGRPSEL);
 +      }
  
        /* Clear any pending 'reset' flags */
        omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
        /* Clear any pending PRCM interrupts */
        omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
  
 -      omap3_iva_idle();
 +      if (omap3_has_iva())
 +              omap3_iva_idle();
 +
        omap3_d2d_idle();
  }
  
@@@ -754,7 -713,6 +718,6 @@@ int __init omap3_pm_init(void
        neon_pwrdm = pwrdm_lookup("neon_pwrdm");
        per_pwrdm = pwrdm_lookup("per_pwrdm");
        core_pwrdm = pwrdm_lookup("core_pwrdm");
-       cam_pwrdm = pwrdm_lookup("cam_pwrdm");
  
        neon_clkdm = clkdm_lookup("neon_clkdm");
        mpu_clkdm = clkdm_lookup("mpu_clkdm");
index 2f963f702a055da9ef5d6bf3ac554054e30a1ba5,eefe179045e6897216d6b1a52b1b5b1ee00c755b..69b36e185e9b7cc019e664f17c53cf96f282eee1
@@@ -526,8 -526,7 +526,8 @@@ int pwrdm_read_next_pwrst(struct powerd
   *
   * Return the powerdomain @pwrdm's current power state.       Returns -EINVAL
   * if the powerdomain pointer is null or returns the current power state
 - * upon success.
 + * upon success. Note that if the power domain only supports the ON state
 + * then just return ON as the current state.
   */
  int pwrdm_read_pwrst(struct powerdomain *pwrdm)
  {
        if (!pwrdm)
                return -EINVAL;
  
 +      if (pwrdm->pwrsts == PWRSTS_ON)
 +              return PWRDM_POWER_ON;
 +
        if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
                ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
  
@@@ -985,15 -981,23 +985,23 @@@ int pwrdm_state_switch(struct powerdoma
        return ret;
  }
  
- int pwrdm_pre_transition(void)
+ int pwrdm_pre_transition(struct powerdomain *pwrdm)
  {
-       pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
+       if (pwrdm)
+               _pwrdm_pre_transition_cb(pwrdm, NULL);
+       else
+               pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
        return 0;
  }
  
- int pwrdm_post_transition(void)
+ int pwrdm_post_transition(struct powerdomain *pwrdm)
  {
-       pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
+       if (pwrdm)
+               _pwrdm_post_transition_cb(pwrdm, NULL);
+       else
+               pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
        return 0;
  }
  
index a8a95184243ddf2d612357756961af8c0310e133,a6a4604801add75c2cfd8f2536e53a9beb32253d..baee90608d11b8ddd444df041e401b4ef5314456
@@@ -67,9 -67,9 +67,9 @@@
  
  /*
   * Maximum number of clockdomains that can be associated with a powerdomain.
 - * CORE powerdomain on OMAP4 is the worst case
 + * PER powerdomain on AM33XX is the worst case
   */
 -#define PWRDM_MAX_CLKDMS      9
 +#define PWRDM_MAX_CLKDMS      11
  
  /* XXX A completely arbitrary number. What is reasonable here? */
  #define PWRDM_TRANSITION_BAILOUT 100000
@@@ -92,15 -92,6 +92,15 @@@ struct powerdomain
   * @pwrdm_clkdms: Clockdomains in this powerdomain
   * @node: list_head linking all powerdomains
   * @voltdm_node: list_head linking all powerdomains in a voltagedomain
 + * @pwrstctrl_offs: (AM33XX only) XXX_PWRSTCTRL reg offset from prcm_offs
 + * @pwrstst_offs: (AM33XX only) XXX_PWRSTST reg offset from prcm_offs
 + * @logicretstate_mask: (AM33XX only) mask for logic retention bitfield
 + *    in @pwrstctrl_offs
 + * @mem_on_mask: (AM33XX only) mask for mem on bitfield in @pwrstctrl_offs
 + * @mem_ret_mask: (AM33XX only) mask for mem ret bitfield in @pwrstctrl_offs
 + * @mem_pwrst_mask: (AM33XX only) mask for mem state bitfield in @pwrstst_offs
 + * @mem_retst_mask: (AM33XX only) mask for mem retention state bitfield
 + *    in @pwrstctrl_offs
   * @state:
   * @state_counter:
   * @timer:
@@@ -130,14 -121,6 +130,14 @@@ struct powerdomain 
        unsigned ret_logic_off_counter;
        unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
  
 +      const u8 pwrstctrl_offs;
 +      const u8 pwrstst_offs;
 +      const u32 logicretstate_mask;
 +      const u32 mem_on_mask[PWRDM_MAX_MEM_BANKS];
 +      const u32 mem_ret_mask[PWRDM_MAX_MEM_BANKS];
 +      const u32 mem_pwrst_mask[PWRDM_MAX_MEM_BANKS];
 +      const u32 mem_retst_mask[PWRDM_MAX_MEM_BANKS];
 +
  #ifdef CONFIG_PM_DEBUG
        s64 timer;
        s64 state_timer[PWRDM_MAX_PWRSTS];
@@@ -230,8 -213,8 +230,8 @@@ bool pwrdm_has_hdwr_sar(struct powerdom
  int pwrdm_wait_transition(struct powerdomain *pwrdm);
  
  int pwrdm_state_switch(struct powerdomain *pwrdm);
- int pwrdm_pre_transition(void);
- int pwrdm_post_transition(void);
+ int pwrdm_pre_transition(struct powerdomain *pwrdm);
+ int pwrdm_post_transition(struct powerdomain *pwrdm);
  int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
  int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
  bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
  extern void omap242x_powerdomains_init(void);
  extern void omap243x_powerdomains_init(void);
  extern void omap3xxx_powerdomains_init(void);
 +extern void am33xx_powerdomains_init(void);
  extern void omap44xx_powerdomains_init(void);
  
  extern struct pwrdm_ops omap2_pwrdm_operations;
  extern struct pwrdm_ops omap3_pwrdm_operations;
 +extern struct pwrdm_ops am33xx_pwrdm_operations;
  extern struct pwrdm_ops omap4_pwrdm_operations;
  
  /* Common Internal functions used across OMAP rev's */
index d5ae4e234bbc028d4563fe80f4f140dd772af81a,fca23cbea708798a1adca967041cbfe1d51b2d3a..e5f0503a68b09e5a2eff32e1a01350a33e32c91b
  #define OMAP3430_EN_MMC2_SHIFT                                25
  #define OMAP3430_EN_MMC1_MASK                         (1 << 24)
  #define OMAP3430_EN_MMC1_SHIFT                                24
 -#define OMAP3430_EN_UART4_MASK                                (1 << 23)
 -#define OMAP3430_EN_UART4_SHIFT                               23
 +#define AM35XX_EN_UART4_MASK                          (1 << 23)
 +#define AM35XX_EN_UART4_SHIFT                         23
  #define OMAP3430_EN_MCSPI4_MASK                               (1 << 21)
  #define OMAP3430_EN_MCSPI4_SHIFT                      21
  #define OMAP3430_EN_MCSPI3_MASK                               (1 << 20)
   */
  #define MAX_MODULE_HARDRESET_WAIT             10000
  
+ /*
+  * Maximum time(us) it takes to output the signal WUCLKOUT of the last
+  * pad of the I/O ring after asserting WUCLKIN high.  Tero measured
+  * the actual time at 7 to 8 microseconds on OMAP3 and 2 to 4
+  * microseconds on OMAP4, so this timeout may be too high.
+  */
+ #define MAX_IOPAD_LATCH_TIME                  100
  # ifndef __ASSEMBLER__
  extern void __iomem *prm_base;
  extern void __iomem *cm_base;
  extern void __iomem *cm2_base;
  extern void __iomem *prcm_mpu_base;
  
 -#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_OMAP5)
 +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
  extern void omap_prm_base_init(void);
  extern void omap_cm_base_init(void);
  #else
index f7bb57fff416f8f3c3d1fd6703f4d9161ad49ccc,a8c946f318ab798b5abeb79dbe9c3349324f8b17..c19d249b481675557f36ebdf315b23c5752d1d4b
  
  
  #ifndef __ASSEMBLER__
 -/*
 - * Stub omap2xxx/omap3xxx functions so that common files
 - * continue to build when custom builds are used
 - */
 -#if defined(CONFIG_ARCH_OMAP4) && !(defined(CONFIG_ARCH_OMAP2) ||     \
 -                                      defined(CONFIG_ARCH_OMAP3))
 -static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -}
 -static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits,
 -              s16 module, s16 idx)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -static inline int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
 -                                              u8 st_shift)
 -{
 -      WARN(1, "prm: omap2xxx/omap3xxx specific function and "
 -              "not suppose to be used on omap4\n");
 -      return 0;
 -}
 -#else
  /* Power/reset management domain register get/set */
  extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
  extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx);
@@@ -241,6 -303,8 +241,6 @@@ extern int omap2_prm_is_hardreset_asser
  extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
  extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
  
 -#endif        /* CONFIG_ARCH_OMAP4 */
 -
  /* OMAP3-specific VP functions */
  u32 omap3_prm_vp_check_txdone(u8 vp_id);
  void omap3_prm_vp_clear_txdone(u8 vp_id);
@@@ -253,12 -317,15 +253,15 @@@ extern u32 omap3_prm_vcvp_read(u8 offse
  extern void omap3_prm_vcvp_write(u32 val, u8 offset);
  extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
  
+ extern void omap3xxx_prm_reconfigure_io_chain(void);
  /* PRM interrupt-related functions */
  extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
  extern void omap3xxx_prm_ocp_barrier(void);
  extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
  extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
- #endif
 -#endif
++#endif /* __ASSEMBLER */
  
  /*
   * Bits common to specific registers
index a7c43c1042bea599d303ce1cf04120d9153eed75,34ef504adafd61ef421095b5964ec6a5144948ce..0ac2caf159410d96831542c867afd81a789838e5
@@@ -16,6 -16,8 +16,8 @@@
  
  #include <linux/err.h>
  
+ #include <plat/voltage.h>
  #include "vc.h"
  #include "vp.h"
  
@@@ -90,25 -92,6 +92,6 @@@ struct voltagedomain 
        struct omap_volt_data *volt_data;
  };
  
- /**
-  * struct omap_volt_data - Omap voltage specific data.
-  * @voltage_nominal:  The possible voltage value in uV
-  * @sr_efuse_offs:    The offset of the efuse register(from system
-  *                    control module base address) from where to read
-  *                    the n-target value for the smartreflex module.
-  * @sr_errminlimit:   Error min limit value for smartreflex. This value
-  *                    differs at differnet opp and thus is linked
-  *                    with voltage.
-  * @vp_errorgain:     Error gain value for the voltage processor. This
-  *                    field also differs according to the voltage/opp.
-  */
- struct omap_volt_data {
-       u32     volt_nominal;
-       u32     sr_efuse_offs;
-       u8      sr_errminlimit;
-       u8      vp_errgain;
- };
  /**
   * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
   * @slew_rate:        PMIC slew rate (in uv/us)
@@@ -156,7 -139,6 +139,7 @@@ int omap_voltage_late_init(void)
  
  extern void omap2xxx_voltagedomains_init(void);
  extern void omap3xxx_voltagedomains_init(void);
 +extern void am33xx_voltagedomains_init(void);
  extern void omap44xx_voltagedomains_init(void);
  
  struct voltagedomain *voltdm_lookup(const char *name);
index 7cfcc44537f0027e8c2f967a6d6f120ab7f86877,7ca15044154f29c7a5a5c5ac12220d0a3103b548..7128e9710417d2a77b06f29cfd45efcb558ff2e3
@@@ -54,6 -54,7 +54,7 @@@ extern void imx50_soc_init(void)
  extern void imx51_soc_init(void);
  extern void imx53_soc_init(void);
  extern void imx51_init_late(void);
+ extern void imx53_init_late(void);
  extern void epit_timer_init(void __iomem *base, int irq);
  extern void mxc_timer_init(void __iomem *, int);
  extern int mx1_clocks_init(unsigned long fref);
@@@ -67,7 -68,6 +68,7 @@@ extern int mx51_clocks_init(unsigned lo
  extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
                        unsigned long ckih1, unsigned long ckih2);
  extern int mx27_clocks_init_dt(void);
 +extern int mx31_clocks_init_dt(void);
  extern int mx51_clocks_init_dt(void);
  extern int mx53_clocks_init_dt(void);
  extern int mx6q_clocks_init(void);
@@@ -96,7 -96,6 +97,6 @@@ enum mx3_cpu_pwr_mode 
  };
  
  extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
- extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
  extern void imx_print_silicon_rev(const char *cpu, int srev);
  
  void avic_handle_irq(struct pt_regs *);
@@@ -147,8 -146,12 +147,12 @@@ extern void imx6q_clock_map_io(void)
  
  #ifdef CONFIG_PM
  extern void imx6q_pm_init(void);
+ extern void imx51_pm_init(void);
+ extern void imx53_pm_init(void);
  #else
  static inline void imx6q_pm_init(void) {}
+ static inline void imx51_pm_init(void) {}
+ static inline void imx53_pm_init(void) {}
  #endif
  
  #ifdef CONFIG_NEON
index 1d432a75e4092f6ebf27eb72615a9610198c560e,071afd0b9283ac7675a07a51921bc52ea0ee8dfb..ebf10654bb42ae477cfdeede23eedbcbc308c395
@@@ -50,7 -50,7 +50,7 @@@
   *    IO      0x00200000+0x100000     ->      0xf4000000+0x100000
   * mx21:
   *    AIPI    0x10000000+0x100000     ->      0xf4400000+0x100000
-  *    SAHB1   0x80000000+0x100000     ->      0xf4000000+0x100000
+  *    SAHB1   0x80000000+0x100000     ->      0xf5000000+0x100000
   *    X_MEMC  0xdf000000+0x004000     ->      0xf5f00000+0x004000
   * mx25:
   *    AIPS1   0x43f00000+0x100000     ->      0xf5300000+0x100000
   *    AVIC    0x68000000+0x100000     ->      0xf5800000+0x100000
   * mx27:
   *    AIPI    0x10000000+0x100000     ->      0xf4400000+0x100000
-  *    SAHB1   0x80000000+0x100000     ->      0xf4000000+0x100000
+  *    SAHB1   0x80000000+0x100000     ->      0xf5000000+0x100000
   *    X_MEMC  0xd8000000+0x100000     ->      0xf5c00000+0x100000
   * mx31:
   *    AIPS1   0x43f00000+0x100000     ->      0xf5300000+0x100000
   *    AIPS2   0x53f00000+0x100000     ->      0xf5700000+0x100000
   *    AVIC    0x68000000+0x100000     ->      0xf5800000+0x100000
-  *    X_MEMC  0xb8000000+0x010000     ->      0xf4c00000+0x010000
+  *    X_MEMC  0xb8000000+0x010000     ->      0xf5c00000+0x010000
   *    SPBA0   0x50000000+0x100000     ->      0xf5400000+0x100000
   * mx35:
   *    AIPS1   0x43f00000+0x100000     ->      0xf5300000+0x100000
   *    AIPS2   0x53f00000+0x100000     ->      0xf5700000+0x100000
   *    AVIC    0x68000000+0x100000     ->      0xf5800000+0x100000
-  *    X_MEMC  0xb8000000+0x010000     ->      0xf4c00000+0x010000
+  *    X_MEMC  0xb8000000+0x010000     ->      0xf5c00000+0x010000
   *    SPBA0   0x50000000+0x100000     ->      0xf5400000+0x100000
   * mx50:
   *    TZIC    0x0fffc000+0x004000     ->      0xf4bfc000+0x004000
-  *    SPBA0   0x50000000+0x100000     ->      0xf5400000+0x100000
   *    AIPS1   0x53f00000+0x100000     ->      0xf5700000+0x100000
+  *    SPBA0   0x50000000+0x100000     ->      0xf5400000+0x100000
   *    AIPS2   0x63f00000+0x100000     ->      0xf5300000+0x100000
   * mx51:
-  *    TZIC    0xe0000000+0x004000     ->      0xf5000000+0x004000
+  *    TZIC    0x0fffc000+0x004000     ->      0xf4bfc000+0x004000
   *    IRAM    0x1ffe0000+0x020000     ->      0xf4fe0000+0x020000
+  *    DEBUG   0x60000000+0x100000     ->      0xf5000000+0x100000
   *    SPBA0   0x70000000+0x100000     ->      0xf5400000+0x100000
   *    AIPS1   0x73f00000+0x100000     ->      0xf5700000+0x100000
-  *    AIPS2   0x83f00000+0x100000     ->      0xf4300000+0x100000
+  *    AIPS2   0x83f00000+0x100000     ->      0xf5300000+0x100000
   * mx53:
   *    TZIC    0x0fffc000+0x004000     ->      0xf4bfc000+0x004000
+  *    DEBUG   0x40000000+0x100000     ->      0xf5000000+0x100000
   *    SPBA0   0x50000000+0x100000     ->      0xf5400000+0x100000
   *    AIPS1   0x53f00000+0x100000     ->      0xf5700000+0x100000
   *    AIPS2   0x63f00000+0x100000     ->      0xf5300000+0x100000
   * mx6q:
-  *    SCU     0x00a00000+0x001000     ->      0xf4000000+0x001000
+  *    SCU     0x00a00000+0x004000     ->      0xf4000000+0x004000
   *    CCM     0x020c4000+0x004000     ->      0xf42c4000+0x004000
-  *    ANATOP  0x020c8000+0x001000     ->      0xf42c8000+0x001000
+  *    ANATOP  0x020c8000+0x004000     ->      0xf42c8000+0x004000
   *    UART4   0x021f0000+0x004000     ->      0xf42f0000+0x004000
   */
  #define IMX_IO_P2V(x) (                                               \
-                       0xf4000000 +                                    \
+                       (((x) & 0x80000000) >> 7) |                     \
+                       (0xf4000000 +                                   \
                        (((x) & 0x50000000) >> 6) +                     \
                        (((x) & 0x0b000000) >> 4) +                     \
-                       (((x) & 0x000fffff)))
+                       (((x) & 0x000fffff))))
  
  #define IMX_IO_ADDRESS(x)     IOMEM(IMX_IO_P2V(x))
  
  /* range e.g. GPIO_1_5 is gpio 5 under linux */
  #define IMX_GPIO_NR(bank, nr)         (((bank) - 1) * 32 + (nr))
  
 -#define IMX_GPIO_TO_IRQ(gpio) (MXC_GPIO_IRQ_START + (gpio))
 -
  #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --combined arch/arm/plat-mxc/tzic.c
index c60a7e4163850e0e029152a88f87eed25489b860,a45dbea5e176ab49d5451bd0b925a5a9592bf916..c2193178210bdd47dbd04b904cdba45a82fd1ad9
@@@ -15,8 -15,6 +15,8 @@@
  #include <linux/device.h>
  #include <linux/errno.h>
  #include <linux/io.h>
 +#include <linux/irqdomain.h>
 +#include <linux/of.h>
  
  #include <asm/mach/irq.h>
  #include <asm/exception.h>
@@@ -51,7 -49,6 +51,7 @@@
  #define TZIC_ID0      0x0FD0  /* Indentification Register 0 */
  
  void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
 +static struct irq_domain *domain;
  
  #define TZIC_NUM_IRQS 128
  
@@@ -80,14 -77,15 +80,14 @@@ static int tzic_set_irq_fiq(unsigned in
  static void tzic_irq_suspend(struct irq_data *d)
  {
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
 -      int idx = gc->irq_base >> 5;
 +      int idx = d->hwirq >> 5;
  
        __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx));
  }
  
  static void tzic_irq_resume(struct irq_data *d)
  {
 -      struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
 -      int idx = gc->irq_base >> 5;
 +      int idx = d->hwirq >> 5;
  
        __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)),
                     tzic_base + TZIC_WAKEUP0(idx));
@@@ -104,10 -102,11 +104,10 @@@ static struct mxc_extra_irq tzic_extra_
  #endif
  };
  
 -static __init void tzic_init_gc(unsigned int irq_start)
 +static __init void tzic_init_gc(int idx, unsigned int irq_start)
  {
        struct irq_chip_generic *gc;
        struct irq_chip_type *ct;
 -      int idx = irq_start >> 5;
  
        gc = irq_alloc_generic_chip("tzic", 1, irq_start, tzic_base,
                                    handle_level_irq);
@@@ -141,8 -140,7 +141,8 @@@ asmlinkage void __exception_irq_entry t
                        while (stat) {
                                handled = 1;
                                irqofs = fls(stat) - 1;
 -                              handle_IRQ(irqofs + i * 32, regs);
 +                              handle_IRQ(irq_find_mapping(domain,
 +                                              irqofs + i * 32), regs);
                                stat &= ~(1 << irqofs);
                        }
                }
   */
  void __init tzic_init_irq(void __iomem *irqbase)
  {
 +      struct device_node *np;
 +      int irq_base;
        int i;
  
        tzic_base = irqbase;
  
        /* all IRQ no FIQ Warning :: No selection */
  
 -      for (i = 0; i < TZIC_NUM_IRQS; i += 32)
 -              tzic_init_gc(i);
 +      irq_base = irq_alloc_descs(-1, 0, TZIC_NUM_IRQS, numa_node_id());
 +      WARN_ON(irq_base < 0);
 +
 +      np = of_find_compatible_node(NULL, NULL, "fsl,tzic");
 +      domain = irq_domain_add_legacy(np, TZIC_NUM_IRQS, irq_base, 0,
 +                                     &irq_domain_simple_ops, NULL);
 +      WARN_ON(!domain);
 +
 +      for (i = 0; i < 4; i++, irq_base += 32)
 +              tzic_init_gc(i, irq_base);
  
  #ifdef CONFIG_FIQ
        /* Initialize FIQ */
 -      init_FIQ();
 +      init_FIQ(FIQ_START);
  #endif
  
        pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
   * tzic_enable_wake() - enable wakeup interrupt
   *
   * @return                    0 if successful; non-zero otherwise
+  *
+  * This function provides an interrupt synchronization point that is required
+  * by tzic enabled platforms before entering imx specific low power modes (ie,
+  * those low power modes beyond the WAIT_CLOCKED basic ARM WFI only mode).
   */
  int tzic_enable_wake(void)
  {
index dcfb506a592e49ac1be2eaddfb683d7bbc13b758,816dec062f3cdb663320ee38d20276dc8763e595..dd36eba9506c85877d91e57d2d95894343199d7d
@@@ -29,7 -29,7 +29,7 @@@ config ARCH_OMAP2PLU
        select USE_OF
        select PROC_DEVICETREE if PROC_FS
        help
 -        "Systems based on OMAP2, OMAP3 or OMAP4"
 +        "Systems based on OMAP2, OMAP3, OMAP4 or OMAP5"
  
  endchoice
  
@@@ -45,31 -45,30 +45,30 @@@ config OMAP_DEBUG_LED
        depends on OMAP_DEBUG_DEVICES
        default y if LEDS_CLASS
  
- config OMAP_SMARTREFLEX
-       bool "SmartReflex support"
-       depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM
+ config POWER_AVS_OMAP
+       bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
+       depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
        help
-         Say Y if you want to enable SmartReflex.
-         SmartReflex can perform continuous dynamic voltage
-         scaling around the nominal operating point voltage
-         according to silicon characteristics and operating
-         conditions. Enabling SmartReflex reduces power
-         consumption.
+         Say Y to enable AVS(Adaptive Voltage Scaling)
+         support on OMAP containing the version 1 or
+         version 2 of the SmartReflex IP.
+         V1 is the 65nm version used in OMAP3430.
+         V2 is the update for the 45nm version of the IP used in OMAP3630
+         and OMAP4430
  
          Please note, that by default SmartReflex is only
-         initialized. To enable the automatic voltage
-         compensation for vdd mpu  and vdd core from user space,
+         initialized and not enabled. To enable the automatic voltage
+         compensation for vdd mpu and vdd core from user space,
          user must write 1 to
-               /debug/voltage/vdd_<X>/smartreflex/autocomp,
-         where X is mpu or core for OMAP3.
+               /debug/smartreflex/sr_<X>/autocomp,
+         where X is mpu_iva or core for OMAP3.
          Optionally autocompensation can be enabled in the kernel
          by default during system init via the enable_on_init flag
          which an be passed as platform data to the smartreflex driver.
  
- config OMAP_SMARTREFLEX_CLASS3
+ config POWER_AVS_OMAP_CLASS3
        bool "Class 3 mode of Smartreflex Implementation"
-       depends on OMAP_SMARTREFLEX && TWL4030_CORE
+       depends on POWER_AVS_OMAP && TWL4030_CORE
        help
          Say Y to enable Class 3 implementation of Smartreflex
  
@@@ -150,7 -149,7 +149,7 @@@ config OMAP_32K_TIME
          This timer saves power compared to the OMAP_MPU_TIMER, and has
          support for no tick during idle. The 32KHz timer provides less
          intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
 -        currently only available for OMAP16XX, 24XX, 34XX and OMAP4.
 +        currently only available for OMAP16XX, 24XX, 34XX and OMAP4/5.
  
  config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
        bool "OMAP3 HS/EMU save and restore for L2 AUX control register"