1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright(c) 2023 Huawei. All rights reserved. */
3
4#include <linux/device.h>
5#include <linux/slab.h>
6#include <linux/idr.h>
7#include <cxlmem.h>
8#include <pmu.h>
9#include <cxl.h>
10#include "core.h"
11
12static void cxl_pmu_release(struct device *dev)
13{
14 struct cxl_pmu *pmu = to_cxl_pmu(dev);
15
16 kfree(objp: pmu);
17}
18
19const struct device_type cxl_pmu_type = {
20 .name = "cxl_pmu",
21 .release = cxl_pmu_release,
22};
23
24static void remove_dev(void *dev)
25{
26 device_unregister(dev);
27}
28
29int devm_cxl_pmu_add(struct device *parent, struct cxl_pmu_regs *regs,
30 int assoc_id, int index, enum cxl_pmu_type type)
31{
32 struct cxl_pmu *pmu;
33 struct device *dev;
34 int rc;
35
36 pmu = kzalloc(size: sizeof(*pmu), GFP_KERNEL);
37 if (!pmu)
38 return -ENOMEM;
39
40 pmu->assoc_id = assoc_id;
41 pmu->index = index;
42 pmu->type = type;
43 pmu->base = regs->pmu;
44 dev = &pmu->dev;
45 device_initialize(dev);
46 device_set_pm_not_required(dev);
47 dev->parent = parent;
48 dev->bus = &cxl_bus_type;
49 dev->type = &cxl_pmu_type;
50 switch (pmu->type) {
51 case CXL_PMU_MEMDEV:
52 rc = dev_set_name(dev, name: "pmu_mem%d.%d", assoc_id, index);
53 break;
54 }
55 if (rc)
56 goto err;
57
58 rc = device_add(dev);
59 if (rc)
60 goto err;
61
62 return devm_add_action_or_reset(parent, remove_dev, dev);
63
64err:
65 put_device(dev: &pmu->dev);
66 return rc;
67}
68EXPORT_SYMBOL_NS_GPL(devm_cxl_pmu_add, CXL);
69

source code of linux/drivers/cxl/core/pmu.c