예제 #1
0
static void omap2_iommu_disable(struct omap_iommu *obj)
{
	struct omap_hwmod *oh;
	u32 l;

	oh = omap_hwmod_lookup(obj->name);
	if (!oh)
		return;
	/*
	 * IPU and DSP iommus are not directly connected to the processor
	 * instead they are  behind a shared MMU. Therefore in the case of
	 * a mmu fault and the mmu fault was not handled, even if the processor
	 * is under reset, the shared MMU will try to translation the address
	 * again causing that the status flag cannot be clear and therefore
	 * as soon as the clkdm wants to go to idle the clkdm will be stuck
	 * in transition state. The only way to reset the shared MMU is doing
	 * a hardreset of the L2 iommu which shared the reset line with the
	 * shared MMU. That way we can clean the status bit and turn off
	 * the iommu without any issue.
	 */
	if (!strcmp(obj->name, "ipu") || !strcmp(obj->name, "dsp")) {
		omap_hwmod_assert_hardreset(oh, oh->rst_lines->name);
		omap_hwmod_deassert_hardreset(oh, oh->rst_lines->name);
		goto out;
	}

	l = iommu_read_reg(obj, MMU_IRQSTATUS);
	iommu_write_reg(obj, l, MMU_IRQSTATUS);
	l = iommu_read_reg(obj, MMU_CNTL);
	l &= ~MMU_CNTL_MASK;
	iommu_write_reg(obj, l, MMU_CNTL);
out:
	clkdm_allow_idle(oh->clkdm);
	dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
}
예제 #2
0
/**
 * omap_device_assert_hardreset - set a device's hardreset line
 * @pdev: struct platform_device * to reset
 * @name: const char * name of the reset line
 *
 * Set the hardreset line identified by @name on the IP blocks
 * associated with the hwmods backing the platform_device @pdev.  All
 * of the hwmods associated with @pdev must have the same hardreset
 * line linked to them for this to work.  Passes along the return value
 * of omap_hwmod_assert_hardreset() in the event of any failure, or
 * returns 0 upon success.
 */
int omap_device_assert_hardreset(struct platform_device *pdev, const char *name)
{
    struct omap_device *od = to_omap_device(pdev);
    int ret = 0;
    int i;

    for (i = 0; i < od->hwmods_cnt; i++) {
        ret = omap_hwmod_assert_hardreset(od->hwmods[i], name);
        if (ret)
            break;
    }

    return ret;
}