diff options
author | Will Deacon <will.deacon@arm.com> | 2014-07-14 14:47:39 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2014-09-16 14:13:48 -0400 |
commit | 4cf740b0b6628bda1e5c9201ae0d4f56fc6c06a5 (patch) | |
tree | ccd54c982e334efced7eb7888149683d106da18e | |
parent | 9e82bf014195d6f0054982c463575cdce24292be (diff) |
iommu/arm-smmu: allow translation stage to be forced on the cmdline
When debugging and testing code on an SMMU that supports nested
translation, it can be useful to restrict the driver to a particular
stage of translation.
This patch adds a module parameter to the ARM SMMU driver to allow this
by restricting the ability of the probe() code to detect support for
only the specified stage.
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | drivers/iommu/arm-smmu.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index a83cc2a2a2ca..958ae8194afe 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -326,6 +326,11 @@ | |||
326 | 326 | ||
327 | #define FSYNR0_WNR (1 << 4) | 327 | #define FSYNR0_WNR (1 << 4) |
328 | 328 | ||
329 | static int force_stage; | ||
330 | module_param_named(force_stage, force_stage, int, S_IRUGO | S_IWUSR); | ||
331 | MODULE_PARM_DESC(force_stage, | ||
332 | "Force SMMU mappings to be installed at a particular stage of translation. A value of '1' or '2' forces the corresponding stage. All other values are ignored (i.e. no stage is forced). Note that selecting a specific stage will disable support for nested translation."); | ||
333 | |||
329 | struct arm_smmu_smr { | 334 | struct arm_smmu_smr { |
330 | u8 idx; | 335 | u8 idx; |
331 | u16 mask; | 336 | u16 mask; |
@@ -1716,6 +1721,13 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
1716 | return -ENODEV; | 1721 | return -ENODEV; |
1717 | } | 1722 | } |
1718 | #endif | 1723 | #endif |
1724 | |||
1725 | /* Restrict available stages based on module parameter */ | ||
1726 | if (force_stage == 1) | ||
1727 | id &= ~(ID0_S2TS | ID0_NTS); | ||
1728 | else if (force_stage == 2) | ||
1729 | id &= ~(ID0_S1TS | ID0_NTS); | ||
1730 | |||
1719 | if (id & ID0_S1TS) { | 1731 | if (id & ID0_S1TS) { |
1720 | smmu->features |= ARM_SMMU_FEAT_TRANS_S1; | 1732 | smmu->features |= ARM_SMMU_FEAT_TRANS_S1; |
1721 | dev_notice(smmu->dev, "\tstage 1 translation\n"); | 1733 | dev_notice(smmu->dev, "\tstage 1 translation\n"); |
@@ -1732,8 +1744,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
1732 | } | 1744 | } |
1733 | 1745 | ||
1734 | if (!(smmu->features & | 1746 | if (!(smmu->features & |
1735 | (ARM_SMMU_FEAT_TRANS_S1 | ARM_SMMU_FEAT_TRANS_S2 | | 1747 | (ARM_SMMU_FEAT_TRANS_S1 | ARM_SMMU_FEAT_TRANS_S2))) { |
1736 | ARM_SMMU_FEAT_TRANS_NESTED))) { | ||
1737 | dev_err(smmu->dev, "\tno translation support!\n"); | 1748 | dev_err(smmu->dev, "\tno translation support!\n"); |
1738 | return -ENODEV; | 1749 | return -ENODEV; |
1739 | } | 1750 | } |