[PATCH v8 09/12] iommu/arm-smmu-v3: Implement pm_runtime & system sleep ops

Daniel Mentz danielmentz at google.com
Sun Jun 7 15:30:00 PDT 2026


On Mon, Jun 1, 2026 at 2:59 PM Pranjal Shrivastava <praan at google.com> wrote:
> +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
> +{
> +       struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> +       struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
> +       int timeout = ARM_SMMU_SUSPEND_TIMEOUT_US;
> +       u32 enables, target;
> +       int ret;
> +
> +       /* Abort all transactions before disable to avoid spurious bypass */
> +       arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
> +
> +       /* Disable the SMMU via CR0.EN and all queues except CMDQ */
> +       enables = CR0_CMDQEN;
> +       ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0, ARM_SMMU_CR0ACK);
> +       if (ret) {
> +               dev_err(smmu->dev, "failed to disable SMMU\n");
> +               return ret;
> +       }
> +
> +       /*
> +        * At this point the SMMU is completely disabled and won't access
> +        * any translation/config structures, even speculative accesses
> +        * aren't performed as per the IHI0070 spec (section 6.3.9.6).
> +        */
> +
> +       /* Mark the CMDQ to stop and get the target index before the stop */
> +       target = atomic_fetch_or_relaxed(CMDQ_PROD_STOP_FLAG, &cmdq->q.llq.atomic.prod);

I'm wondering if we need the non-relaxed version of atomic_fetch_or()
here to benefit from the barrier guarantees. Otherwise, how do you
ensure that CMDQ_PROD_STOP_FLAG isn't set before SMMUEN is cleared?

> +       target &= CMDQ_PROD_IDX_MASK;



More information about the linux-arm-kernel mailing list