diff mbox series

[04/13] iommu/arm-smmu: Clean up bus_set_iommu()

Message ID 2e59602d982fd4941ec923571940fa3c628b2188.1649935679.git.robin.murphy@arm.com (mailing list archive)
State New, archived
Headers show
Series iommu: Retire bus_set_iommu() | expand

Commit Message

Robin Murphy April 14, 2022, 12:42 p.m. UTC
Stop calling bus_set_iommu() since it's now unnecessary. With device
probes now replayed for every IOMMU instance registration, the whole
sorry ordering workaround for legacy DT bindings goes too, hooray!

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 84 +--------------------------
 1 file changed, 2 insertions(+), 82 deletions(-)

Comments

Will Deacon April 19, 2022, 2:40 p.m. UTC | #1
On Thu, Apr 14, 2022 at 01:42:33PM +0100, Robin Murphy wrote:
> Stop calling bus_set_iommu() since it's now unnecessary. With device
> probes now replayed for every IOMMU instance registration, the whole
> sorry ordering workaround for legacy DT bindings goes too, hooray!

Ha, I hope you tested this!

> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.c | 84 +--------------------------
>  1 file changed, 2 insertions(+), 82 deletions(-)

Assuming it works,

Acked-by: Will Deacon <will@kernel.org>

Will
Robin Murphy April 20, 2022, 4:05 p.m. UTC | #2
On 2022-04-19 15:40, Will Deacon wrote:
> On Thu, Apr 14, 2022 at 01:42:33PM +0100, Robin Murphy wrote:
>> Stop calling bus_set_iommu() since it's now unnecessary. With device
>> probes now replayed for every IOMMU instance registration, the whole
>> sorry ordering workaround for legacy DT bindings goes too, hooray!
> 
> Ha, I hope you tested this!

Oh alright then, since it's you... :)

I've hacked up a Juno DT with the old bindings, and (after needing a 
while to remember that they're fundamentally incompatible with 
disable_bypass), can confirm that with my whole dev branch including 
this series applied, it boots and creates IOMMU groups as expected. I 
then made the mistake of trying without the branch to check whether the 
squawks from iommu_setup_dma_ops() were new or not, and... well... plain 
rc3 doesn't even boot on the same setup - it's somehow blowing up in the 
failure cleanup path of iommu_bus_init(), apparently calling 
iommu_release_device() on something where dev->iommu->iommu_dev is NULL, 
for reasons that are far from clear and I'm not sure I can really be 
bothered to debug further... :/

Cheers,
Robin.

>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>   drivers/iommu/arm/arm-smmu/arm-smmu.c | 84 +--------------------------
>>   1 file changed, 2 insertions(+), 82 deletions(-)
> 
> Assuming it works,
> 
> Acked-by: Will Deacon <will@kernel.org>
> 
> Will
Will Deacon April 21, 2022, 8:33 a.m. UTC | #3
On Wed, Apr 20, 2022 at 05:05:03PM +0100, Robin Murphy wrote:
> On 2022-04-19 15:40, Will Deacon wrote:
> > On Thu, Apr 14, 2022 at 01:42:33PM +0100, Robin Murphy wrote:
> > > Stop calling bus_set_iommu() since it's now unnecessary. With device
> > > probes now replayed for every IOMMU instance registration, the whole
> > > sorry ordering workaround for legacy DT bindings goes too, hooray!
> > 
> > Ha, I hope you tested this!
> 
> Oh alright then, since it's you... :)
> 
> I've hacked up a Juno DT with the old bindings, and (after needing a while
> to remember that they're fundamentally incompatible with disable_bypass),
> can confirm that with my whole dev branch including this series applied, it
> boots and creates IOMMU groups as expected. I then made the mistake of
> trying without the branch to check whether the squawks from
> iommu_setup_dma_ops() were new or not, and... well... plain rc3 doesn't even
> boot on the same setup - it's somehow blowing up in the failure cleanup path
> of iommu_bus_init(), apparently calling iommu_release_device() on something
> where dev->iommu->iommu_dev is NULL, for reasons that are far from clear and
> I'm not sure I can really be bothered to debug further... :/

Great, so your series is a fix!

Will
diff mbox series

Patch

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 52bd42d80b4f..34cab56b9c6d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -37,7 +37,6 @@ 
 #include <linux/ratelimit.h>
 #include <linux/slab.h>
 
-#include <linux/amba/bus.h>
 #include <linux/fsl/mc.h>
 
 #include "arm-smmu.h"
@@ -93,8 +92,6 @@  static struct platform_driver arm_smmu_driver;
 static struct iommu_ops arm_smmu_ops;
 
 #ifdef CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS
-static int arm_smmu_bus_init(struct iommu_ops *ops);
-
 static struct device_node *dev_get_dev_node(struct device *dev)
 {
 	if (dev_is_pci(dev)) {
@@ -180,20 +177,6 @@  static int arm_smmu_register_legacy_master(struct device *dev,
 	kfree(sids);
 	return err;
 }
-
-/*
- * With the legacy DT binding in play, we have no guarantees about
- * probe order, but then we're also not doing default domains, so we can
- * delay setting bus ops until we're sure every possible SMMU is ready,
- * and that way ensure that no probe_device() calls get missed.
- */
-static int arm_smmu_legacy_bus_init(void)
-{
-	if (using_legacy_binding)
-		return arm_smmu_bus_init(&arm_smmu_ops);
-	return 0;
-}
-device_initcall_sync(arm_smmu_legacy_bus_init);
 #else
 static int arm_smmu_register_legacy_master(struct device *dev,
 					   struct arm_smmu_device **smmu)
@@ -2022,52 +2005,6 @@  static int arm_smmu_device_dt_probe(struct arm_smmu_device *smmu,
 	return 0;
 }
 
-static int arm_smmu_bus_init(struct iommu_ops *ops)
-{
-	int err;
-
-	/* Oh, for a proper bus abstraction */
-	if (!iommu_present(&platform_bus_type)) {
-		err = bus_set_iommu(&platform_bus_type, ops);
-		if (err)
-			return err;
-	}
-#ifdef CONFIG_ARM_AMBA
-	if (!iommu_present(&amba_bustype)) {
-		err = bus_set_iommu(&amba_bustype, ops);
-		if (err)
-			goto err_reset_platform_ops;
-	}
-#endif
-#ifdef CONFIG_PCI
-	if (!iommu_present(&pci_bus_type)) {
-		err = bus_set_iommu(&pci_bus_type, ops);
-		if (err)
-			goto err_reset_amba_ops;
-	}
-#endif
-#ifdef CONFIG_FSL_MC_BUS
-	if (!iommu_present(&fsl_mc_bus_type)) {
-		err = bus_set_iommu(&fsl_mc_bus_type, ops);
-		if (err)
-			goto err_reset_pci_ops;
-	}
-#endif
-	return 0;
-
-err_reset_pci_ops: __maybe_unused;
-#ifdef CONFIG_PCI
-	bus_set_iommu(&pci_bus_type, NULL);
-#endif
-err_reset_amba_ops: __maybe_unused;
-#ifdef CONFIG_ARM_AMBA
-	bus_set_iommu(&amba_bustype, NULL);
-#endif
-err_reset_platform_ops: __maybe_unused;
-	bus_set_iommu(&platform_bus_type, NULL);
-	return err;
-}
-
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -2185,7 +2122,8 @@  static int arm_smmu_device_probe(struct platform_device *pdev)
 	err = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
 	if (err) {
 		dev_err(dev, "Failed to register iommu\n");
-		goto err_sysfs_remove;
+		iommu_device_sysfs_remove(&smmu->iommu);
+		return err;
 	}
 
 	platform_set_drvdata(pdev, smmu);
@@ -2203,24 +2141,7 @@  static int arm_smmu_device_probe(struct platform_device *pdev)
 		pm_runtime_enable(dev);
 	}
 
-	/*
-	 * For ACPI and generic DT bindings, an SMMU will be probed before
-	 * any device which might need it, so we want the bus ops in place
-	 * ready to handle default domain setup as soon as any SMMU exists.
-	 */
-	if (!using_legacy_binding) {
-		err = arm_smmu_bus_init(&arm_smmu_ops);
-		if (err)
-			goto err_unregister_device;
-	}
-
 	return 0;
-
-err_unregister_device:
-	iommu_device_unregister(&smmu->iommu);
-err_sysfs_remove:
-	iommu_device_sysfs_remove(&smmu->iommu);
-	return err;
 }
 
 static int arm_smmu_device_remove(struct platform_device *pdev)
@@ -2233,7 +2154,6 @@  static int arm_smmu_device_remove(struct platform_device *pdev)
 	if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS))
 		dev_notice(&pdev->dev, "disabling translation\n");
 
-	arm_smmu_bus_init(NULL);
 	iommu_device_unregister(&smmu->iommu);
 	iommu_device_sysfs_remove(&smmu->iommu);