$(obj)/sleep33xx.o $(obj)/sleep43xx.o: include/generated/ti-pm-asm-offsets.h
targets += pm-asm-offsets.s
+
+obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * OMAP IOMMU quirks for various TI SoCs
+ *
+ * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Suman Anna <s-anna@ti.com>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "powerdomain.h"
+
+int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
+ u8 *pwrst)
+{
+ struct powerdomain *pwrdm;
+ struct omap_device *od;
+ u8 next_pwrst;
+
+ od = to_omap_device(pdev);
+ if (!od)
+ return -ENODEV;
+
+ if (od->hwmods_cnt != 1)
+ return -EINVAL;
+
+ pwrdm = omap_hwmod_get_pwrdm(od->hwmods[0]);
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (request)
+ *pwrst = pwrdm_read_next_pwrst(pwrdm);
+
+ if (*pwrst > PWRDM_POWER_RET)
+ return 0;
+
+ next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
+
+ return pwrdm_set_next_pwrst(pwrdm, next_pwrst);
+}
struct platform_device *pdev = to_platform_device(obj->dev);
struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ if (pdata && pdata->set_pwrdm_constraint) {
+ err = pdata->set_pwrdm_constraint(pdev, true, &obj->pwrst);
+ if (err) {
+ dev_warn(obj->dev, "pwrdm_constraint failed to be set, status = %d\n",
+ err);
+ }
+ }
+
if (pdata && pdata->deassert_reset) {
err = pdata->deassert_reset(pdev, pdata->reset_name);
if (err) {
{
struct platform_device *pdev = to_platform_device(obj->dev);
struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ int ret;
omap2_iommu_disable(obj);
if (pdata && pdata->assert_reset)
pdata->assert_reset(pdev, pdata->reset_name);
+
+ if (pdata && pdata->set_pwrdm_constraint) {
+ ret = pdata->set_pwrdm_constraint(pdev, false, &obj->pwrst);
+ if (ret) {
+ dev_warn(obj->dev, "pwrdm_constraint failed to be reset, status = %d\n",
+ ret);
+ }
+ }
}
/*
struct iommu_device iommu;
struct iommu_group *group;
+
+ u8 pwrst;
};
/**
const char *reset_name;
int (*assert_reset)(struct platform_device *pdev, const char *name);
int (*deassert_reset)(struct platform_device *pdev, const char *name);
+ int (*set_pwrdm_constraint)(struct platform_device *pdev, bool request,
+ u8 *pwrst);
};