@@ -348,7 +348,12 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
348
348
349
349
static struct arm_smmu_cmdq * arm_smmu_get_cmdq (struct arm_smmu_device * smmu )
350
350
{
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 ;
352
357
}
353
358
354
359
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)
4052
4057
return ret ;
4053
4058
}
4054
4059
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
+
4055
4068
return 0 ;
4056
4069
}
4057
4070
@@ -4466,6 +4479,38 @@ static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
4466
4479
iort_put_rmr_sids (dev_fwnode (smmu -> dev ), & rmr_list );
4467
4480
}
4468
4481
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
+
4469
4514
static int arm_smmu_device_probe (struct platform_device * pdev )
4470
4515
{
4471
4516
int irq , ret ;
@@ -4487,6 +4532,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
4487
4532
if (ret )
4488
4533
return ret ;
4489
4534
4535
+ smmu = arm_smmu_impl_probe (smmu );
4536
+ if (IS_ERR (smmu ))
4537
+ return PTR_ERR (smmu );
4538
+
4490
4539
/* Base address */
4491
4540
res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
4492
4541
if (!res )
0 commit comments