xref: /kernel/linux/linux-6.6/drivers/dca/dca-sysfs.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/kernel.h>
762306a36Sopenharmony_ci#include <linux/spinlock.h>
862306a36Sopenharmony_ci#include <linux/device.h>
962306a36Sopenharmony_ci#include <linux/idr.h>
1062306a36Sopenharmony_ci#include <linux/kdev_t.h>
1162306a36Sopenharmony_ci#include <linux/err.h>
1262306a36Sopenharmony_ci#include <linux/dca.h>
1362306a36Sopenharmony_ci#include <linux/gfp.h>
1462306a36Sopenharmony_ci#include <linux/export.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistatic struct class *dca_class;
1762306a36Sopenharmony_cistatic struct idr dca_idr;
1862306a36Sopenharmony_cistatic spinlock_t dca_idr_lock;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciint dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	struct device *cd;
2362306a36Sopenharmony_ci	static int req_count;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL,
2662306a36Sopenharmony_ci			   "requester%d", req_count++);
2762306a36Sopenharmony_ci	return PTR_ERR_OR_ZERO(cd);
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_civoid dca_sysfs_remove_req(struct dca_provider *dca, int slot)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	device_destroy(dca_class, MKDEV(0, slot + 1));
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ciint dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	struct device *cd;
3862306a36Sopenharmony_ci	int ret;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	idr_preload(GFP_KERNEL);
4162306a36Sopenharmony_ci	spin_lock(&dca_idr_lock);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	ret = idr_alloc(&dca_idr, dca, 0, 0, GFP_NOWAIT);
4462306a36Sopenharmony_ci	if (ret >= 0)
4562306a36Sopenharmony_ci		dca->id = ret;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	spin_unlock(&dca_idr_lock);
4862306a36Sopenharmony_ci	idr_preload_end();
4962306a36Sopenharmony_ci	if (ret < 0)
5062306a36Sopenharmony_ci		return ret;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id);
5362306a36Sopenharmony_ci	if (IS_ERR(cd)) {
5462306a36Sopenharmony_ci		spin_lock(&dca_idr_lock);
5562306a36Sopenharmony_ci		idr_remove(&dca_idr, dca->id);
5662306a36Sopenharmony_ci		spin_unlock(&dca_idr_lock);
5762306a36Sopenharmony_ci		return PTR_ERR(cd);
5862306a36Sopenharmony_ci	}
5962306a36Sopenharmony_ci	dca->cd = cd;
6062306a36Sopenharmony_ci	return 0;
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_civoid dca_sysfs_remove_provider(struct dca_provider *dca)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	device_unregister(dca->cd);
6662306a36Sopenharmony_ci	dca->cd = NULL;
6762306a36Sopenharmony_ci	spin_lock(&dca_idr_lock);
6862306a36Sopenharmony_ci	idr_remove(&dca_idr, dca->id);
6962306a36Sopenharmony_ci	spin_unlock(&dca_idr_lock);
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ciint __init dca_sysfs_init(void)
7362306a36Sopenharmony_ci{
7462306a36Sopenharmony_ci	idr_init(&dca_idr);
7562306a36Sopenharmony_ci	spin_lock_init(&dca_idr_lock);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	dca_class = class_create("dca");
7862306a36Sopenharmony_ci	if (IS_ERR(dca_class)) {
7962306a36Sopenharmony_ci		idr_destroy(&dca_idr);
8062306a36Sopenharmony_ci		return PTR_ERR(dca_class);
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci	return 0;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_civoid __exit dca_sysfs_exit(void)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	class_destroy(dca_class);
8862306a36Sopenharmony_ci	idr_destroy(&dca_idr);
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
91