|
|
@@ -11,14 +11,43 @@
|
|
|
|
|
|
#include "omap_hwmod.h"
|
|
|
#include "omap_device.h"
|
|
|
+#include "clockdomain.h"
|
|
|
#include "powerdomain.h"
|
|
|
|
|
|
+static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
|
|
|
+ bool enable)
|
|
|
+{
|
|
|
+ static struct clockdomain *emu_clkdm;
|
|
|
+ static DEFINE_SPINLOCK(emu_lock);
|
|
|
+ static atomic_t count;
|
|
|
+ struct device_node *np = pdev->dev.of_node;
|
|
|
+
|
|
|
+ if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!emu_clkdm) {
|
|
|
+ emu_clkdm = clkdm_lookup("emu_clkdm");
|
|
|
+ if (WARN_ON_ONCE(!emu_clkdm))
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_lock(&emu_lock);
|
|
|
+
|
|
|
+ if (enable && (atomic_inc_return(&count) == 1))
|
|
|
+ clkdm_deny_idle(emu_clkdm);
|
|
|
+ else if (!enable && (atomic_dec_return(&count) == 0))
|
|
|
+ clkdm_allow_idle(emu_clkdm);
|
|
|
+
|
|
|
+ spin_unlock(&emu_lock);
|
|
|
+}
|
|
|
+
|
|
|
int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
|
|
|
u8 *pwrst)
|
|
|
{
|
|
|
struct powerdomain *pwrdm;
|
|
|
struct omap_device *od;
|
|
|
u8 next_pwrst;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
od = to_omap_device(pdev);
|
|
|
if (!od)
|
|
|
@@ -31,13 +60,21 @@ int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
|
|
|
if (!pwrdm)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (request)
|
|
|
+ if (request) {
|
|
|
*pwrst = pwrdm_read_next_pwrst(pwrdm);
|
|
|
+ omap_iommu_dra7_emu_swsup_config(pdev, true);
|
|
|
+ }
|
|
|
|
|
|
if (*pwrst > PWRDM_POWER_RET)
|
|
|
- return 0;
|
|
|
+ goto out;
|
|
|
|
|
|
next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
|
|
|
|
|
|
- return pwrdm_set_next_pwrst(pwrdm, next_pwrst);
|
|
|
+ ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst);
|
|
|
+
|
|
|
+out:
|
|
|
+ if (!request)
|
|
|
+ omap_iommu_dra7_emu_swsup_config(pdev, false);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|