Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / arch / arm / mach-omap2 / pdata-quirks.c
index b0f8c9a..6c6f8fc 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/platform_data/wkup_m3.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 
+#include "clockdomain.h"
 #include "common.h"
 #include "common-board-devices.h"
 #include "control.h"
@@ -460,6 +461,62 @@ static void __init dra7x_evm_mmc_quirk(void)
 }
 #endif
 
+static struct clockdomain *ti_sysc_find_one_clockdomain(struct clk *clk)
+{
+       struct clockdomain *clkdm = NULL;
+       struct clk_hw_omap *hwclk;
+
+       hwclk = to_clk_hw_omap(__clk_get_hw(clk));
+       if (hwclk && hwclk->clkdm_name)
+               clkdm = clkdm_lookup(hwclk->clkdm_name);
+
+       return clkdm;
+}
+
+/**
+ * ti_sysc_clkdm_init - find clockdomain based on clock
+ * @fck: device functional clock
+ * @ick: device interface clock
+ * @dev: struct device
+ *
+ * Populate clockdomain based on clock. It is needed for
+ * clkdm_deny_idle() and clkdm_allow_idle() for blocking clockdomain
+ * clockdomain idle during reset, enable and idle.
+ *
+ * Note that we assume interconnect driver manages the clocks
+ * and do not need to populate oh->_clk for dynamically
+ * allocated modules.
+ */
+static int ti_sysc_clkdm_init(struct device *dev,
+                             struct clk *fck, struct clk *ick,
+                             struct ti_sysc_cookie *cookie)
+{
+       if (fck)
+               cookie->clkdm = ti_sysc_find_one_clockdomain(fck);
+       if (cookie->clkdm)
+               return 0;
+       if (ick)
+               cookie->clkdm = ti_sysc_find_one_clockdomain(ick);
+       if (cookie->clkdm)
+               return 0;
+
+       return -ENODEV;
+}
+
+static void ti_sysc_clkdm_deny_idle(struct device *dev,
+                                   const struct ti_sysc_cookie *cookie)
+{
+       if (cookie->clkdm)
+               clkdm_deny_idle(cookie->clkdm);
+}
+
+static void ti_sysc_clkdm_allow_idle(struct device *dev,
+                                    const struct ti_sysc_cookie *cookie)
+{
+       if (cookie->clkdm)
+               clkdm_allow_idle(cookie->clkdm);
+}
+
 static int ti_sysc_enable_module(struct device *dev,
                                 const struct ti_sysc_cookie *cookie)
 {
@@ -491,6 +548,9 @@ static struct of_dev_auxdata omap_auxdata_lookup[];
 
 static struct ti_sysc_platform_data ti_sysc_pdata = {
        .auxdata = omap_auxdata_lookup,
+       .init_clockdomain = ti_sysc_clkdm_init,
+       .clkdm_deny_idle = ti_sysc_clkdm_deny_idle,
+       .clkdm_allow_idle = ti_sysc_clkdm_allow_idle,
        .init_module = omap_hwmod_init_module,
        .enable_module = ti_sysc_enable_module,
        .idle_module = ti_sysc_idle_module,