pmu.c 1.3 KB

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