Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 Jul 2012 23:04:15 +0000 (16:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 Jul 2012 23:04:15 +0000 (16:04 -0700)
Pull general arm-soc cleanups from Arnd Bergmann:
 "These are all boring changes, moving stuff around or renaming things
  mostly, and also getting rid of stuff that is duplicate or should not
  be there to start with.  Platform-wise this is all over the place,
  mainly omap, samsung, at91, imx and tegra."

Resolve trivial conflict in arch/arm/mach-omap2/clockdomains3xxx_data.c

* tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (67 commits)
  ARM: clps711x: Remove the setting of the time
  ARM: clps711x: Removed superfluous transform virt_to_bus and related functions
  ARM: clps711x/p720t: Replace __initcall by .init_early call
  ARM: S3C24XX: Remove unused GPIO definitions for Openmoko GTA02 board
  ARM: S3C24XX: Remove unused GPIO definitions for port J
  ARM: S3C24XX: Remove unused GPA, GPE, GPH bank GPIO aliases
  ARM: S3C24XX: Convert the touchscreen setup code to common GPIO API
  ARM: S3C24XX: Convert the PM code to gpiolib API
  ARM: S3C24XX: Convert QT2410 board file to the gpiolib API
  ARM: S3C24XX: Convert SMDK board file to the gpiolib API
  ARM: S3C24XX: Free the backlight gpio requested in Mini2440 board code
  ARM: imx: remove unused pdata from device macros
  ARM: imx: Kconfig: Remove IMX_HAVE_PLATFORM_IMX_SSI from MACH_MX25_3DS
  ARM: at91: fix new build errors
  ARM: at91: add AIC5 support
  ARM: at91: remove mach/irqs.h
  ARM: at91: sparse irq support
  ARM: at91: at91 based machines specify their own irq handler at run time
  ARM: at91: remove static irq priorities for sam9x5
  ARM: at91: add of irq priorities support
  ...

1  2 
Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clockdomain.h
arch/arm/mach-omap2/clockdomains3xxx_data.c
arch/arm/mach-omap2/clockdomains44xx_data.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c

index 0000000,f77c303..c6d7b11
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,27 +1,25 @@@
 -- reg : Should contain SD/MMC registers location and length
 -- interrupts : Should contain SD/MMC interrupt
 -- bus-width : Number of data lines, can be <1>, <4>, or <8>
+ * NVIDIA Tegra Secure Digital Host Controller
+ This controller on Tegra family SoCs provides an interface for MMC, SD,
+ and SDIO types of memory cards.
++This file documents differences between the core properties described
++by mmc.txt and the properties used by the sdhci-tegra driver.
++
+ Required properties:
+ - compatible : Should be "nvidia,<chip>-sdhci"
 -- cd-gpios : Specify GPIOs for card detection
 -- wp-gpios : Specify GPIOs for write protection
+ Optional properties:
+ - power-gpios : Specify GPIOs for power control
+ Example:
+ sdhci@c8000200 {
+       compatible = "nvidia,tegra20-sdhci";
+       reg = <0xc8000200 0x200>;
+       interrupts = <47>;
+       cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+       wp-gpios = <&gpio 57 0>; /* gpio PH1 */
+       power-gpios = <&gpio 155 0>; /* gpio PT3 */
+       bus-width = <8>;
+ };
@@@ -35,7 -35,6 +35,7 @@@ config ARCH_OMAP
        select CPU_V7
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
        select ARCH_HAS_OPP
 +      select PM_RUNTIME if CPU_IDLE
        select PM_OPP if PM
        select ARM_CPU_SUSPEND if PM
        select MULTI_IRQ_HANDLER
@@@ -53,7 -52,6 +53,7 @@@ config ARCH_OMAP
        select PL310_ERRATA_727915
        select ARM_ERRATA_720789
        select ARCH_HAS_OPP
 +      select PM_RUNTIME if CPU_IDLE
        select PM_OPP if PM
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
        select ARM_CPU_SUSPEND if PM
@@@ -66,19 -64,16 +66,16 @@@ config SOC_OMAP242
        depends on ARCH_OMAP2
        default y
        select OMAP_DM_TIMER
-       select ARCH_OMAP_OTG
  
  config SOC_OMAP2430
        bool "OMAP2430 support"
        depends on ARCH_OMAP2
        default y
-       select ARCH_OMAP_OTG
  
  config SOC_OMAP3430
        bool "OMAP3430 support"
        depends on ARCH_OMAP3
        default y
-       select ARCH_OMAP_OTG
  
  config SOC_TI81XX
        bool "TI81XX support"
@@@ -66,7 -66,9 +66,7 @@@ 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_PM_DEBUG)                        += pm-debug.o
  obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
  obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
@@@ -80,11 -82,6 +80,11 @@@ endi
  
  endif
  
 +ifeq ($(CONFIG_CPU_IDLE),y)
 +obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
 +obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
 +endif
 +
  # PRCM
  obj-y                                 += prm_common.o
  obj-$(CONFIG_ARCH_OMAP2)              += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
@@@ -119,7 -116,6 +119,6 @@@ obj-$(CONFIG_ARCH_OMAP4)           += powerdomai
  
  # 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
@@@ -247,9 -243,6 +246,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
  
@@@ -218,6 -218,9 +218,6 @@@ static struct twl4030_gpio_platform_dat
  };
  
  static struct twl4030_platform_data sdp2430_twldata = {
 -      .irq_base       = TWL4030_IRQ_BASE,
 -      .irq_end        = TWL4030_IRQ_END,
 -
        /* platform_data for children goes here */
        .gpio           = &sdp2430_gpio_data,
        .vmmc1          = &sdp2430_vmmc1,
@@@ -251,16 -254,6 +251,6 @@@ static struct omap2_hsmmc_info mmc[] __
        {}      /* Terminator */
  };
  
- static struct omap_usb_config sdp2430_usb_config __initdata = {
-       .otg            = 1,
- #ifdef  CONFIG_USB_GADGET_OMAP
-       .hmc_mode       = 0x0,
- #elif   defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-       .hmc_mode       = 0x1,
- #endif
-       .pins[0]        = 3,
- };
  #ifdef CONFIG_OMAP_MUX
  static struct omap_board_mux board_mux[] __initdata = {
        { .reg_offset = OMAP_MUX_TERMINATOR },
@@@ -277,7 -270,6 +267,6 @@@ static void __init omap_2430sdp_init(vo
        omap_serial_init();
        omap_sdrc_init(NULL, NULL);
        omap_hsmmc_init(mmc);
-       omap2_usbfs_init(&sdp2430_usb_config);
  
        omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
        usb_musb_init(NULL);
@@@ -2490,13 -2490,13 +2490,13 @@@ static struct clk uart4_fck = 
  };
  
  static struct clk uart4_fck_am35xx = {
 -      .name           = "uart4_fck",
 -      .ops            = &clkops_omap2_dflt_wait,
 -      .parent         = &per_48m_fck,
 -      .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 -      .enable_bit     = OMAP3430_EN_UART4_SHIFT,
 -      .clkdm_name     = "core_l4_clkdm",
 -      .recalc         = &followparent_recalc,
 +      .name           = "uart4_fck",
 +      .ops            = &clkops_omap2_dflt_wait,
 +      .parent         = &core_48m_fck,
 +      .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 +      .enable_bit     = AM35XX_EN_UART4_SHIFT,
 +      .clkdm_name     = "core_l4_clkdm",
 +      .recalc         = &followparent_recalc,
  };
  
  static struct clk gpt2_fck = {
@@@ -3201,12 -3201,8 +3201,12 @@@ static struct clk vpfe_fck = 
  };
  
  /*
 - * The UART1/2 functional clock acts as the functional
 - * clock for UART4. No separate fclk control available.
 + * The UART1/2 functional clock acts as the functional clock for
 + * UART4. No separate fclk control available.  XXX Well now we have a
 + * uart4_fck that is apparently used as the UART4 functional clock,
 + * but it also seems that uart1_fck or uart2_fck are still needed, at
 + * least for UART4 softresets to complete.  This really needs
 + * clarification.
   */
  static struct clk uart4_ick_am35xx = {
        .name           = "uart4_ick",
@@@ -3240,11 -3236,6 +3240,6 @@@ static struct omap_clk omap3xxx_clks[] 
        CLK(NULL,       "osc_sys_ck",   &osc_sys_ck,    CK_3XXX),
        CLK(NULL,       "sys_ck",       &sys_ck,        CK_3XXX),
        CLK(NULL,       "sys_altclk",   &sys_altclk,    CK_3XXX),
-       CLK("omap-mcbsp.1",     "pad_fck",      &mcbsp_clks,    CK_3XXX),
-       CLK("omap-mcbsp.2",     "pad_fck",      &mcbsp_clks,    CK_3XXX),
-       CLK("omap-mcbsp.3",     "pad_fck",      &mcbsp_clks,    CK_3XXX),
-       CLK("omap-mcbsp.4",     "pad_fck",      &mcbsp_clks,    CK_3XXX),
-       CLK("omap-mcbsp.5",     "pad_fck",      &mcbsp_clks,    CK_3XXX),
        CLK(NULL,       "mcbsp_clks",   &mcbsp_clks,    CK_3XXX),
        CLK(NULL,       "sys_clkout1",  &sys_clkout1,   CK_3XXX),
        CLK(NULL,       "dpll1_ck",     &dpll1_ck,      CK_3XXX),
        CLK(NULL,       "ts_fck",       &ts_fck,        CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK(NULL,       "usbtll_fck",   &usbtll_fck,    CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK("usbhs_omap",       "usbtll_fck",   &usbtll_fck,    CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-       CLK("omap-mcbsp.1",     "prcm_fck",     &core_96m_fck,  CK_3XXX),
-       CLK("omap-mcbsp.5",     "prcm_fck",     &core_96m_fck,  CK_3XXX),
        CLK(NULL,       "core_96m_fck", &core_96m_fck,  CK_3XXX),
        CLK(NULL,       "mmchs3_fck",   &mmchs3_fck,    CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK(NULL,       "mmchs2_fck",   &mmchs2_fck,    CK_3XXX),
        CLK(NULL,       "omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
        CLK(NULL,       "gpt12_ick",    &gpt12_ick,     CK_3XXX),
        CLK(NULL,       "gpt1_ick",     &gpt1_ick,      CK_3XXX),
-       CLK("omap-mcbsp.2",     "prcm_fck",     &per_96m_fck,   CK_3XXX),
-       CLK("omap-mcbsp.3",     "prcm_fck",     &per_96m_fck,   CK_3XXX),
-       CLK("omap-mcbsp.4",     "prcm_fck",     &per_96m_fck,   CK_3XXX),
        CLK(NULL,       "per_96m_fck",  &per_96m_fck,   CK_3XXX),
        CLK(NULL,       "per_48m_fck",  &per_48m_fck,   CK_3XXX),
        CLK(NULL,       "uart3_fck",    &uart3_fck,     CK_3XXX),
        CLK(NULL,       "ipss_ick",     &ipss_ick,      CK_AM35XX),
        CLK(NULL,       "rmii_ck",      &rmii_ck,       CK_AM35XX),
        CLK(NULL,       "pclk_ck",      &pclk_ck,       CK_AM35XX),
 -      CLK("davinci_emac",     NULL,   &emac_ick,      CK_AM35XX),
 +      CLK("davinci_emac.0",   NULL,   &emac_ick,      CK_AM35XX),
        CLK("davinci_mdio.0",   NULL,   &emac_fck,      CK_AM35XX),
        CLK("vpfe-capture",     "master",       &vpfe_ick,      CK_AM35XX),
        CLK("vpfe-capture",     "slave",        &vpfe_fck,      CK_AM35XX),
 -      CLK("musb-am35x",       "ick",          &hsotgusb_ick_am35xx,   CK_AM35XX),
 -      CLK("musb-am35x",       "fck",          &hsotgusb_fck_am35xx,   CK_AM35XX),
 +      CLK(NULL,       "hsotgusb_ick",         &hsotgusb_ick_am35xx,   CK_AM35XX),
 +      CLK(NULL,       "hsotgusb_fck",         &hsotgusb_fck_am35xx,   CK_AM35XX),
        CLK(NULL,       "hecc_ck",      &hecc_ck,       CK_AM35XX),
        CLK(NULL,       "uart4_ick",    &uart4_ick_am35xx,      CK_AM35XX),
        CLK("omap_timer.1",     "32k_ck",       &omap_32k_fck,  CK_3XXX),
   *
   * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this
   *     clockdomain.  (Currently, this applies to OMAP3 clockdomains only.)
 + * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
 + *     active whenever the MPU is active.  True for interconnects and
 + *     the WKUP clockdomains.
   */
  #define CLKDM_CAN_FORCE_SLEEP                 (1 << 0)
  #define CLKDM_CAN_FORCE_WAKEUP                        (1 << 1)
  #define CLKDM_CAN_ENABLE_AUTO                 (1 << 2)
  #define CLKDM_CAN_DISABLE_AUTO                        (1 << 3)
  #define CLKDM_NO_AUTODEPS                     (1 << 4)
 +#define CLKDM_ACTIVE_WITH_MPU                 (1 << 5)
  
  #define CLKDM_CAN_HWSUP               (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
  #define CLKDM_CAN_SWSUP               (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@@ -210,7 -206,5 +210,5 @@@ extern struct clkdm_ops omap4_clkdm_ope
  extern struct clkdm_dep gfx_24xx_wkdeps[];
  extern struct clkdm_dep dsp_24xx_wkdeps[];
  extern struct clockdomain wkup_common_clkdm;
- extern struct clockdomain prm_common_clkdm;
- extern struct clockdomain cm_common_clkdm;
  
  #endif
@@@ -59,12 -59,6 +59,12 @@@ static struct clkdm_dep gfx_sgx_3xxx_wk
        { NULL },
  };
  
 +static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
 +      { .clkdm_name = "mpu_clkdm" },
 +      { .clkdm_name = "wkup_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
  static struct clkdm_dep per_wkdeps[] = {
        { .clkdm_name = "core_l3_clkdm" },
        { NULL },
  };
  
 +static struct clkdm_dep per_am35x_wkdeps[] = {
 +      { .clkdm_name = "core_l3_clkdm" },
 +      { .clkdm_name = "core_l4_clkdm" },
 +      { .clkdm_name = "mpu_clkdm" },
 +      { .clkdm_name = "wkup_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
  static struct clkdm_dep usbhost_wkdeps[] = {
        { .clkdm_name = "core_l3_clkdm" },
        { NULL },
  };
  
 +static struct clkdm_dep usbhost_am35x_wkdeps[] = {
 +      { .clkdm_name = "core_l3_clkdm" },
 +      { .clkdm_name = "core_l4_clkdm" },
 +      { .clkdm_name = "mpu_clkdm" },
 +      { .clkdm_name = "wkup_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
  static struct clkdm_dep mpu_3xxx_wkdeps[] = {
        { .clkdm_name = "core_l3_clkdm" },
        { NULL },
  };
  
 +static struct clkdm_dep mpu_am35x_wkdeps[] = {
 +      { .clkdm_name = "core_l3_clkdm" },
 +      { .clkdm_name = "core_l4_clkdm" },
 +      { .clkdm_name = "dss_clkdm" },
 +      { .clkdm_name = "per_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
  static struct clkdm_dep iva2_wkdeps[] = {
        { .clkdm_name = "core_l3_clkdm" },
@@@ -146,12 -116,6 +146,12 @@@ static struct clkdm_dep dss_wkdeps[] = 
        { NULL },
  };
  
 +static struct clkdm_dep dss_am35x_wkdeps[] = {
 +      { .clkdm_name = "mpu_clkdm" },
 +      { .clkdm_name = "wkup_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430: PM_WKDEP_NEON: MPU */
  static struct clkdm_dep neon_wkdeps[] = {
        { .clkdm_name = "mpu_clkdm" },
@@@ -167,11 -131,6 +167,11 @@@ static struct clkdm_dep dss_sleepdeps[
        { NULL },
  };
  
 +static struct clkdm_dep dss_am35x_sleepdeps[] = {
 +      { .clkdm_name = "mpu_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
  static struct clkdm_dep per_sleepdeps[] = {
        { .clkdm_name = "mpu_clkdm" },
        { NULL },
  };
  
 +static struct clkdm_dep per_am35x_sleepdeps[] = {
 +      { .clkdm_name = "mpu_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
  static struct clkdm_dep usbhost_sleepdeps[] = {
        { .clkdm_name = "mpu_clkdm" },
        { NULL },
  };
  
 +static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
 +      { .clkdm_name = "mpu_clkdm" },
 +      { NULL },
 +};
 +
  /* 3430: CM_SLEEPDEP_CAM: MPU */
  static struct clkdm_dep cam_sleepdeps[] = {
        { .clkdm_name = "mpu_clkdm" },
@@@ -226,15 -175,6 +226,15 @@@ static struct clockdomain mpu_3xxx_clkd
        .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
  };
  
 +static struct clockdomain mpu_am35x_clkdm = {
 +      .name           = "mpu_clkdm",
 +      .pwrdm          = { .name = "mpu_pwrdm" },
 +      .flags          = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
 +      .dep_bit        = OMAP3430_EN_MPU_SHIFT,
 +      .wkdep_srcs     = mpu_am35x_wkdeps,
 +      .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
 +};
 +
  static struct clockdomain neon_clkdm = {
        .name           = "neon_clkdm",
        .pwrdm          = { .name = "neon_pwrdm" },
@@@ -270,15 -210,6 +270,15 @@@ static struct clockdomain sgx_clkdm = 
        .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
  };
  
 +static struct clockdomain sgx_am35x_clkdm = {
 +      .name           = "sgx_clkdm",
 +      .pwrdm          = { .name = "sgx_pwrdm" },
 +      .flags          = CLKDM_CAN_HWSUP_SWSUP,
 +      .wkdep_srcs     = gfx_sgx_am35x_wkdeps,
 +      .sleepdep_srcs  = gfx_sgx_sleepdeps,
 +      .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
 +};
 +
  /*
   * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
   * then that information was removed from the 34xx ES2+ TRM.  It is
@@@ -330,16 -261,6 +330,16 @@@ static struct clockdomain dss_3xxx_clkd
        .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
  };
  
 +static struct clockdomain dss_am35x_clkdm = {
 +      .name           = "dss_clkdm",
 +      .pwrdm          = { .name = "dss_pwrdm" },
 +      .flags          = CLKDM_CAN_HWSUP_SWSUP,
 +      .dep_bit        = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
 +      .wkdep_srcs     = dss_am35x_wkdeps,
 +      .sleepdep_srcs  = dss_am35x_sleepdeps,
 +      .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
 +};
 +
  static struct clockdomain cam_clkdm = {
        .name           = "cam_clkdm",
        .pwrdm          = { .name = "cam_pwrdm" },
@@@ -358,15 -279,6 +358,15 @@@ static struct clockdomain usbhost_clkd
        .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
  };
  
 +static struct clockdomain usbhost_am35x_clkdm = {
 +      .name           = "usbhost_clkdm",
 +      .pwrdm          = { .name = "core_pwrdm" },
 +      .flags          = CLKDM_CAN_HWSUP_SWSUP,
 +      .wkdep_srcs     = usbhost_am35x_wkdeps,
 +      .sleepdep_srcs  = usbhost_am35x_sleepdeps,
 +      .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
 +};
 +
  static struct clockdomain per_clkdm = {
        .name           = "per_clkdm",
        .pwrdm          = { .name = "per_pwrdm" },
        .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
  };
  
 +static struct clockdomain per_am35x_clkdm = {
 +      .name           = "per_clkdm",
 +      .pwrdm          = { .name = "per_pwrdm" },
 +      .flags          = CLKDM_CAN_HWSUP_SWSUP,
 +      .dep_bit        = OMAP3430_EN_PER_SHIFT,
 +      .wkdep_srcs     = per_am35x_wkdeps,
 +      .sleepdep_srcs  = per_am35x_sleepdeps,
 +      .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
 +};
 +
  /*
   * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
   * switched of even if sdti is in use
@@@ -439,44 -341,29 +439,42 @@@ static struct clkdm_autodep clkdm_autod
        }
  };
  
 +static struct clkdm_autodep clkdm_am35x_autodeps[] = {
 +      {
 +              .clkdm = { .name = "mpu_clkdm" },
 +      },
 +      {
 +              .clkdm = { .name = NULL },
 +      }
 +};
 +
  /*
   *
   */
  
 -static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
 +static struct clockdomain *clockdomains_common[] __initdata = {
        &wkup_common_clkdm,
-       &cm_common_clkdm,
-       &prm_common_clkdm,
 -      &mpu_3xxx_clkdm,
        &neon_clkdm,
 -      &iva2_clkdm,
 -      &d2d_clkdm,
        &core_l3_3xxx_clkdm,
        &core_l4_3xxx_clkdm,
 -      &dss_3xxx_clkdm,
 -      &cam_clkdm,
 -      &per_clkdm,
        &emu_clkdm,
        &dpll1_clkdm,
 -      &dpll2_clkdm,
        &dpll3_clkdm,
        &dpll4_clkdm,
        NULL
  };
  
 +static struct clockdomain *clockdomains_omap3430[] __initdata = {
 +      &mpu_3xxx_clkdm,
 +      &iva2_clkdm,
 +      &d2d_clkdm,
 +      &dss_3xxx_clkdm,
 +      &cam_clkdm,
 +      &per_clkdm,
 +      &dpll2_clkdm,
 +      NULL
 +};
 +
  static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
        &gfx_3430es1_clkdm,
        NULL,
@@@ -489,41 -376,21 +487,41 @@@ static struct clockdomain *clockdomains
        NULL,
  };
  
 +static struct clockdomain *clockdomains_am35x[] __initdata = {
 +      &mpu_am35x_clkdm,
 +      &sgx_am35x_clkdm,
 +      &dss_am35x_clkdm,
 +      &per_am35x_clkdm,
 +      &usbhost_am35x_clkdm,
 +      &dpll5_clkdm,
 +      NULL
 +};
 +
  void __init omap3xxx_clockdomains_init(void)
  {
        struct clockdomain **sc;
 +      unsigned int rev;
  
        if (!cpu_is_omap34xx())
                return;
  
        clkdm_register_platform_funcs(&omap3_clkdm_operations);
 -      clkdm_register_clkdms(clockdomains_omap3430_common);
 +      clkdm_register_clkdms(clockdomains_common);
  
 -      sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 :
 -              clockdomains_omap3430es2plus;
 +      rev = omap_rev();
  
 -      clkdm_register_clkdms(sc);
 +      if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
 +              clkdm_register_clkdms(clockdomains_am35x);
 +              clkdm_register_autodeps(clkdm_am35x_autodeps);
 +      } else {
 +              clkdm_register_clkdms(clockdomains_omap3430);
 +
 +              sc = (rev == OMAP3430_REV_ES1_0) ?
 +                      clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
 +
 +              clkdm_register_clkdms(sc);
 +              clkdm_register_autodeps(clkdm_autodeps);
 +      }
  
 -      clkdm_register_autodeps(clkdm_autodeps);
        clkdm_complete_init();
  }
@@@ -381,7 -381,7 +381,7 @@@ static struct clockdomain l4_wkup_44xx_
        .cm_inst          = OMAP4430_PRM_WKUP_CM_INST,
        .clkdm_offs       = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS,
        .dep_bit          = OMAP4430_L4WKUP_STATDEP_SHIFT,
 -      .flags            = CLKDM_CAN_HWSUP,
 +      .flags            = CLKDM_CAN_HWSUP | CLKDM_ACTIVE_WITH_MPU,
  };
  
  static struct clockdomain emu_sys_44xx_clkdm = {
@@@ -430,8 -430,6 +430,6 @@@ static struct clockdomain *clockdomains
        &l4_wkup_44xx_clkdm,
        &emu_sys_44xx_clkdm,
        &l3_dma_44xx_clkdm,
-       &prm_common_clkdm,
-       &cm_common_clkdm,
        NULL
  };
  
   */
  #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);
  
@@@ -186,6 -211,9 +211,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 */
  
  /**
@@@ -771,23 -799,19 +799,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)
@@@ -1124,18 -1145,15 +1145,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);
        }
  
@@@ -1219,13 -1229,8 +1240,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);
        }
  
@@@ -1301,24 -1306,20 +1322,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",
@@@ -1354,7 -1355,8 +1371,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 *
@@@ -1447,32 -1402,31 +1418,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);
  }
  
  /**
@@@ -1587,10 -1529,6 +1545,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;
  
@@@ -1830,9 -1768,11 +1784,11 @@@ static int _enable(struct omap_hwmod *o
        }
  
        _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,
@@@ -1886,7 -1826,8 +1842,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
@@@ -1991,7 -1932,8 +1948,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);
@@@ -2447,6 -2389,194 +2405,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)
@@@ -2579,12 -2709,18 +2725,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;
  
@@@ -3417,3 -3553,32 +3569,32 @@@ 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_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;
+ }
@@@ -527,27 -527,11 +527,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,
  };
  
@@@ -1093,6 -1074,17 +1093,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 },
@@@ -1116,6 -1108,8 +1127,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 */
@@@ -1145,6 -1139,8 +1158,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,
  };
  
@@@ -1175,6 -1171,8 +1190,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,
  };
  
@@@ -1207,6 -1205,8 +1224,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 */
@@@ -1238,6 -1238,8 +1257,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 */
@@@ -1657,20 -1659,25 +1678,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 */
@@@ -2111,10 -2118,9 +2132,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,
@@@ -2258,7 -2264,6 +2279,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 = {
@@@ -2409,7 -2414,7 +2430,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,
  };
@@@ -3154,107 -3159,6 +3175,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,
@@@ -3383,10 -3287,6 +3404,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
  };
  
@@@ -3404,6 -3304,8 +3425,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)