Skip to content

Commit 6de80d6

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Add struct arm_smmu_impl_ops
Mimicing the arm-smmu (v2) driver, introduce a struct arm_smmu_impl_ops to accommodate impl routines. Suggested-by: Will Deacon <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Signed-off-by: Nicolin Chen <[email protected]> Link: https://lore.kernel.org/r/8fe9f3805568aabf771fc6706c116459016bf62d.1724970714.git.nicolinc@nvidia.com Signed-off-by: Will Deacon <[email protected]>
1 parent 6f3f9ff commit 6de80d6

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,12 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
348348

349349
static struct arm_smmu_cmdq *arm_smmu_get_cmdq(struct arm_smmu_device *smmu)
350350
{
351-
return &smmu->cmdq;
351+
struct arm_smmu_cmdq *cmdq = NULL;
352+
353+
if (smmu->impl_ops && smmu->impl_ops->get_secondary_cmdq)
354+
cmdq = smmu->impl_ops->get_secondary_cmdq(smmu);
355+
356+
return cmdq ?: &smmu->cmdq;
352357
}
353358

354359
static bool arm_smmu_cmdq_needs_busy_polling(struct arm_smmu_device *smmu,
@@ -4052,6 +4057,14 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
40524057
return ret;
40534058
}
40544059

4060+
if (smmu->impl_ops && smmu->impl_ops->device_reset) {
4061+
ret = smmu->impl_ops->device_reset(smmu);
4062+
if (ret) {
4063+
dev_err(smmu->dev, "failed to reset impl\n");
4064+
return ret;
4065+
}
4066+
}
4067+
40554068
return 0;
40564069
}
40574070

@@ -4466,6 +4479,38 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
44664479
iort_put_rmr_sids(dev_fwnode(smmu->dev), &rmr_list);
44674480
}
44684481

4482+
static void arm_smmu_impl_remove(void *data)
4483+
{
4484+
struct arm_smmu_device *smmu = data;
4485+
4486+
if (smmu->impl_ops && smmu->impl_ops->device_remove)
4487+
smmu->impl_ops->device_remove(smmu);
4488+
}
4489+
4490+
/*
4491+
* Probe all the compiled in implementations. Each one checks to see if it
4492+
* matches this HW and if so returns a devm_krealloc'd arm_smmu_device which
4493+
* replaces the callers. Otherwise the original is returned or ERR_PTR.
4494+
*/
4495+
static struct arm_smmu_device *arm_smmu_impl_probe(struct arm_smmu_device *smmu)
4496+
{
4497+
struct arm_smmu_device *new_smmu = ERR_PTR(-ENODEV);
4498+
int ret;
4499+
4500+
/* Add impl probe */
4501+
4502+
if (new_smmu == ERR_PTR(-ENODEV))
4503+
return smmu;
4504+
if (IS_ERR(new_smmu))
4505+
return new_smmu;
4506+
4507+
ret = devm_add_action_or_reset(new_smmu->dev, arm_smmu_impl_remove,
4508+
new_smmu);
4509+
if (ret)
4510+
return ERR_PTR(ret);
4511+
return new_smmu;
4512+
}
4513+
44694514
static int arm_smmu_device_probe(struct platform_device *pdev)
44704515
{
44714516
int irq, ret;
@@ -4487,6 +4532,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
44874532
if (ret)
44884533
return ret;
44894534

4535+
smmu = arm_smmu_impl_probe(smmu);
4536+
if (IS_ERR(smmu))
4537+
return PTR_ERR(smmu);
4538+
44904539
/* Base address */
44914540
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
44924541
if (!res)

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <linux/mmzone.h>
1515
#include <linux/sizes.h>
1616

17+
struct arm_smmu_device;
18+
1719
/* MMIO registers */
1820
#define ARM_SMMU_IDR0 0x0
1921
#define IDR0_ST_LVL GENMASK(28, 27)
@@ -630,9 +632,17 @@ struct arm_smmu_strtab_cfg {
630632
u32 strtab_base_cfg;
631633
};
632634

635+
struct arm_smmu_impl_ops {
636+
int (*device_reset)(struct arm_smmu_device *smmu);
637+
void (*device_remove)(struct arm_smmu_device *smmu);
638+
struct arm_smmu_cmdq *(*get_secondary_cmdq)(struct arm_smmu_device *smmu);
639+
};
640+
633641
/* An SMMUv3 instance */
634642
struct arm_smmu_device {
635643
struct device *dev;
644+
const struct arm_smmu_impl_ops *impl_ops;
645+
636646
void __iomem *base;
637647
void __iomem *page1;
638648

0 commit comments

Comments
 (0)