18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/kernel.h>
78c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
88c2ecf20Sopenharmony_ci#include <linux/device.h>
98c2ecf20Sopenharmony_ci#include <linux/idr.h>
108c2ecf20Sopenharmony_ci#include <linux/kdev_t.h>
118c2ecf20Sopenharmony_ci#include <linux/err.h>
128c2ecf20Sopenharmony_ci#include <linux/dca.h>
138c2ecf20Sopenharmony_ci#include <linux/gfp.h>
148c2ecf20Sopenharmony_ci#include <linux/export.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cistatic struct class *dca_class;
178c2ecf20Sopenharmony_cistatic struct idr dca_idr;
188c2ecf20Sopenharmony_cistatic spinlock_t dca_idr_lock;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciint dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	struct device *cd;
238c2ecf20Sopenharmony_ci	static int req_count;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL,
268c2ecf20Sopenharmony_ci			   "requester%d", req_count++);
278c2ecf20Sopenharmony_ci	return PTR_ERR_OR_ZERO(cd);
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_civoid dca_sysfs_remove_req(struct dca_provider *dca, int slot)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci	device_destroy(dca_class, MKDEV(0, slot + 1));
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ciint dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	struct device *cd;
388c2ecf20Sopenharmony_ci	int ret;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	idr_preload(GFP_KERNEL);
418c2ecf20Sopenharmony_ci	spin_lock(&dca_idr_lock);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	ret = idr_alloc(&dca_idr, dca, 0, 0, GFP_NOWAIT);
448c2ecf20Sopenharmony_ci	if (ret >= 0)
458c2ecf20Sopenharmony_ci		dca->id = ret;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	spin_unlock(&dca_idr_lock);
488c2ecf20Sopenharmony_ci	idr_preload_end();
498c2ecf20Sopenharmony_ci	if (ret < 0)
508c2ecf20Sopenharmony_ci		return ret;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id);
538c2ecf20Sopenharmony_ci	if (IS_ERR(cd)) {
548c2ecf20Sopenharmony_ci		spin_lock(&dca_idr_lock);
558c2ecf20Sopenharmony_ci		idr_remove(&dca_idr, dca->id);
568c2ecf20Sopenharmony_ci		spin_unlock(&dca_idr_lock);
578c2ecf20Sopenharmony_ci		return PTR_ERR(cd);
588c2ecf20Sopenharmony_ci	}
598c2ecf20Sopenharmony_ci	dca->cd = cd;
608c2ecf20Sopenharmony_ci	return 0;
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_civoid dca_sysfs_remove_provider(struct dca_provider *dca)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	device_unregister(dca->cd);
668c2ecf20Sopenharmony_ci	dca->cd = NULL;
678c2ecf20Sopenharmony_ci	spin_lock(&dca_idr_lock);
688c2ecf20Sopenharmony_ci	idr_remove(&dca_idr, dca->id);
698c2ecf20Sopenharmony_ci	spin_unlock(&dca_idr_lock);
708c2ecf20Sopenharmony_ci}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ciint __init dca_sysfs_init(void)
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci	idr_init(&dca_idr);
758c2ecf20Sopenharmony_ci	spin_lock_init(&dca_idr_lock);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	dca_class = class_create(THIS_MODULE, "dca");
788c2ecf20Sopenharmony_ci	if (IS_ERR(dca_class)) {
798c2ecf20Sopenharmony_ci		idr_destroy(&dca_idr);
808c2ecf20Sopenharmony_ci		return PTR_ERR(dca_class);
818c2ecf20Sopenharmony_ci	}
828c2ecf20Sopenharmony_ci	return 0;
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_civoid __exit dca_sysfs_exit(void)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	class_destroy(dca_class);
888c2ecf20Sopenharmony_ci	idr_destroy(&dca_idr);
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
91