]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
iommu/arm-smmu-qcom: Register the TBU driver in qcom_smmu_impl_init
authorGeorgi Djakov <quic_c_gdjako@quicinc.com>
Thu, 4 Jul 2024 01:07:59 +0000 (18:07 -0700)
committerWill Deacon <will@kernel.org>
Thu, 4 Jul 2024 12:33:10 +0000 (13:33 +0100)
Currently the TBU driver will only probe when CONFIG_ARM_SMMU_QCOM_DEBUG
is enabled. The driver not probing would prevent the platform to reach
sync_state and the system will remain in sub-optimal power consumption
mode while waiting for all consumer drivers to probe. To address this,
let's register the TBU driver in qcom_smmu_impl_init(), so that it can
probe, but still enable its functionality only when the debug option in
Kconfig is enabled.

Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Closes: https://lore.kernel.org/r/CAA8EJppcXVu72OSo+OiYEiC1HQjP3qCwKMumOsUhcn6Czj0URg@mail.gmail.com
Fixes: 414ecb030870 ("iommu/arm-smmu-qcom-debug: Add support for TBUs")
Signed-off-by: Georgi Djakov <quic_c_gdjako@quicinc.com>
Link: https://lore.kernel.org/r/20240704010759.507798-1-quic_c_gdjako@quicinc.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h

index ef93f825f11f98cc5931c5d99d01ac94ffb332a9..548783f3f8e89fd978367afa65c473002f66e2e7 100644 (file)
@@ -464,7 +464,7 @@ irqreturn_t qcom_smmu_context_fault(int irq, void *dev)
        return ret;
 }
 
-static int qcom_tbu_probe(struct platform_device *pdev)
+int qcom_tbu_probe(struct platform_device *pdev)
 {
        struct of_phandle_args args = { .args_count = 2 };
        struct device_node *np = pdev->dev.of_node;
@@ -506,18 +506,3 @@ static int qcom_tbu_probe(struct platform_device *pdev)
 
        return 0;
 }
-
-static const struct of_device_id qcom_tbu_of_match[] = {
-       { .compatible = "qcom,sc7280-tbu" },
-       { .compatible = "qcom,sdm845-tbu" },
-       { }
-};
-
-static struct platform_driver qcom_tbu_driver = {
-       .driver = {
-               .name           = "qcom_tbu",
-               .of_match_table = qcom_tbu_of_match,
-       },
-       .probe = qcom_tbu_probe,
-};
-builtin_platform_driver(qcom_tbu_driver);
index 971c6a2e592b9f15f747d27cb27a021d54b1486c..36c6b36ad4ff74549b2520a84be30cacfbe858e8 100644 (file)
@@ -8,6 +8,8 @@
 #include <linux/delay.h>
 #include <linux/of_device.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include "arm-smmu.h"
 #include "arm-smmu-qcom.h"
@@ -562,10 +564,47 @@ static struct acpi_platform_list qcom_acpi_platlist[] = {
 };
 #endif
 
+static int qcom_smmu_tbu_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       int ret;
+
+       if (IS_ENABLED(CONFIG_ARM_SMMU_QCOM_DEBUG)) {
+               ret = qcom_tbu_probe(pdev);
+               if (ret)
+                       return ret;
+       }
+
+       if (dev->pm_domain) {
+               pm_runtime_set_active(dev);
+               pm_runtime_enable(dev);
+       }
+
+       return 0;
+}
+
+static const struct of_device_id qcom_smmu_tbu_of_match[] = {
+       { .compatible = "qcom,sc7280-tbu" },
+       { .compatible = "qcom,sdm845-tbu" },
+       { }
+};
+
+static struct platform_driver qcom_smmu_tbu_driver = {
+       .driver = {
+               .name           = "qcom_tbu",
+               .of_match_table = qcom_smmu_tbu_of_match,
+       },
+       .probe = qcom_smmu_tbu_probe,
+};
+
 struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
 {
        const struct device_node *np = smmu->dev->of_node;
        const struct of_device_id *match;
+       static u8 tbu_registered;
+
+       if (!tbu_registered++)
+               platform_driver_register(&qcom_smmu_tbu_driver);
 
 #ifdef CONFIG_ACPI
        if (np == NULL) {
index 9bb3ae7d62da68600181268026a19768cce9c387..3c134d1a62773ed99133510ee1f82bd08d86e623 100644 (file)
@@ -34,8 +34,10 @@ irqreturn_t qcom_smmu_context_fault(int irq, void *dev);
 
 #ifdef CONFIG_ARM_SMMU_QCOM_DEBUG
 void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu);
+int qcom_tbu_probe(struct platform_device *pdev);
 #else
 static inline void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu) { }
+static inline int qcom_tbu_probe(struct platform_device *pdev) { return -EINVAL; }
 #endif
 
 #endif /* _ARM_SMMU_QCOM_H */