[PATCH 1/5] csky: Init pmu as a device

From: Mao Han
Date: Wed May 22 2019 - 05:29:27 EST


This patch change the csky pmu initialization from arch init to
device init. The pmu can be configued with information from
device tree(pmu device name, irq number and etc.).

Signed-off-by: Mao Han <han_mao@xxxxxxxxx>
CC: Guo Ren <guoren@xxxxxxxxxx>
CC: linux-csky@xxxxxxxxxxxxxxx
---
arch/csky/kernel/perf_event.c | 58 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/arch/csky/kernel/perf_event.c b/arch/csky/kernel/perf_event.c
index 376c972..c022acc 100644
--- a/arch/csky/kernel/perf_event.c
+++ b/arch/csky/kernel/perf_event.c
@@ -21,6 +21,8 @@ struct csky_pmu_t {
uint32_t hpcr;
} csky_pmu;

+typedef int (*csky_pmu_init)(struct csky_pmu_t *);
+
#define cprgr(reg) \
({ \
unsigned int tmp; \
@@ -1028,4 +1030,58 @@ int __init init_hw_perf_events(void)

return perf_pmu_register(&csky_pmu.pmu, "cpu", PERF_TYPE_RAW);
}
-arch_initcall(init_hw_perf_events);
+
+int csky_pmu_device_probe(struct platform_device *pdev,
+ const struct of_device_id *of_table)
+{
+ const struct of_device_id *of_id;
+ csky_pmu_init init_fn;
+ struct device_node *node = pdev->dev.of_node;
+ int ret = -ENODEV;
+
+ of_id = of_match_node(of_table, pdev->dev.of_node);
+ if (node && of_id) {
+ init_fn = of_id->data;
+ ret = init_fn(&csky_pmu);
+ }
+
+ if (ret) {
+ pr_notice("[perf] failed to probe PMU!\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+const static struct of_device_id csky_pmu_of_device_ids[] = {
+ {.compatible = "csky,csky-pmu", .data = init_hw_perf_events},
+ {},
+};
+
+static int csky_pmu_dev_probe(struct platform_device *pdev)
+{
+ return csky_pmu_device_probe(pdev, csky_pmu_of_device_ids);
+}
+
+static struct platform_driver csky_pmu_driver = {
+ .driver = {
+ .name = "csky-pmu",
+ .of_match_table = csky_pmu_of_device_ids,
+ },
+ .probe = csky_pmu_dev_probe,
+};
+
+static int __init csky_pmu_probe(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&csky_pmu_driver);
+ if (ret)
+ pr_notice("[perf] PMU initialization failed\n");
+ else
+ pr_notice("[perf] PMU initialization done\n");
+
+ return ret;
+}
+
+device_initcall(csky_pmu_probe);
--
2.7.4