Skip to content

Commit fd5015c

Browse files
wildea01Somasundaram Krishnasamy
authored andcommitted
iommu/arm-smmu-v3: Split arm_smmu_cmdq_issue_sync in half
[ Upstream commit 4980659 ] arm_smmu_cmdq_issue_sync is a little unwieldy now that it supports both MSI and event-based polling, so split it into two functions to make things easier to follow. Signed-off-by: Will Deacon <[email protected]> (cherry picked from commit 4980659) Orabug: 30479048 Signed-off-by: Thomas Tai <[email protected]> Reviewed-by: Tom Saeger <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent ce9dfa4 commit fd5015c

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

drivers/iommu/arm-smmu-v3.c

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ static void arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
990990
* The difference between val and sync_idx is bounded by the maximum size of
991991
* a queue at 2^20 entries, so 32 bits is plenty for wrap-safe arithmetic.
992992
*/
993-
static int arm_smmu_sync_poll_msi(struct arm_smmu_device *smmu, u32 sync_idx)
993+
static int __arm_smmu_sync_poll_msi(struct arm_smmu_device *smmu, u32 sync_idx)
994994
{
995995
ktime_t timeout = ktime_add_us(ktime_get(), ARM_SMMU_SYNC_TIMEOUT_US);
996996
u32 val = smp_cond_load_acquire(&smmu->sync_count,
@@ -1000,30 +1000,53 @@ static int arm_smmu_sync_poll_msi(struct arm_smmu_device *smmu, u32 sync_idx)
10001000
return (int)(val - sync_idx) < 0 ? -ETIMEDOUT : 0;
10011001
}
10021002

1003-
static void arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
1003+
static int __arm_smmu_cmdq_issue_sync_msi(struct arm_smmu_device *smmu)
1004+
{
1005+
u64 cmd[CMDQ_ENT_DWORDS];
1006+
unsigned long flags;
1007+
struct arm_smmu_cmdq_ent ent = {
1008+
.opcode = CMDQ_OP_CMD_SYNC,
1009+
.sync = {
1010+
.msidata = atomic_inc_return_relaxed(&smmu->sync_nr),
1011+
.msiaddr = virt_to_phys(&smmu->sync_count),
1012+
},
1013+
};
1014+
1015+
arm_smmu_cmdq_build_cmd(cmd, &ent);
1016+
1017+
spin_lock_irqsave(&smmu->cmdq.lock, flags);
1018+
arm_smmu_cmdq_insert_cmd(smmu, cmd);
1019+
spin_unlock_irqrestore(&smmu->cmdq.lock, flags);
1020+
1021+
return __arm_smmu_sync_poll_msi(smmu, ent.sync.msidata);
1022+
}
1023+
1024+
static int __arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
10041025
{
10051026
u64 cmd[CMDQ_ENT_DWORDS];
10061027
unsigned long flags;
10071028
bool wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
1008-
bool msi = (smmu->features & ARM_SMMU_FEAT_MSI) &&
1009-
(smmu->features & ARM_SMMU_FEAT_COHERENCY);
10101029
struct arm_smmu_cmdq_ent ent = { .opcode = CMDQ_OP_CMD_SYNC };
10111030
int ret;
10121031

1013-
if (msi) {
1014-
ent.sync.msidata = atomic_inc_return_relaxed(&smmu->sync_nr);
1015-
ent.sync.msiaddr = virt_to_phys(&smmu->sync_count);
1016-
}
10171032
arm_smmu_cmdq_build_cmd(cmd, &ent);
10181033

10191034
spin_lock_irqsave(&smmu->cmdq.lock, flags);
10201035
arm_smmu_cmdq_insert_cmd(smmu, cmd);
1021-
if (!msi)
1022-
ret = queue_poll_cons(&smmu->cmdq.q, true, wfe);
1036+
ret = queue_poll_cons(&smmu->cmdq.q, true, wfe);
10231037
spin_unlock_irqrestore(&smmu->cmdq.lock, flags);
10241038

1025-
if (msi)
1026-
ret = arm_smmu_sync_poll_msi(smmu, ent.sync.msidata);
1039+
return ret;
1040+
}
1041+
1042+
static void arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
1043+
{
1044+
int ret;
1045+
bool msi = (smmu->features & ARM_SMMU_FEAT_MSI) &&
1046+
(smmu->features & ARM_SMMU_FEAT_COHERENCY);
1047+
1048+
ret = msi ? __arm_smmu_cmdq_issue_sync_msi(smmu)
1049+
: __arm_smmu_cmdq_issue_sync(smmu);
10271050
if (ret)
10281051
dev_err_ratelimited(smmu->dev, "CMD_SYNC timeout\n");
10291052
}

0 commit comments

Comments
 (0)