1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/spinlock.h> 8 #include <linux/device.h> 9 #include <linux/idr.h> 10 #include <linux/kdev_t.h> 11 #include <linux/err.h> 12 #include <linux/dca.h> 13 #include <linux/gfp.h> 14 #include <linux/export.h> 15 16 static struct class *dca_class; 17 static struct idr dca_idr; 18 static spinlock_t dca_idr_lock; 19 20 int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot) 21 { 22 struct device *cd; 23 static int req_count; 24 25 cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL, 26 "requester%d", req_count++); 27 return PTR_ERR_OR_ZERO(cd); 28 } 29 30 void dca_sysfs_remove_req(struct dca_provider *dca, int slot) 31 { 32 device_destroy(dca_class, MKDEV(0, slot + 1)); 33 } 34 35 int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev) 36 { 37 struct device *cd; 38 int ret; 39 40 idr_preload(GFP_KERNEL); 41 spin_lock(&dca_idr_lock); 42 43 ret = idr_alloc(&dca_idr, dca, 0, 0, GFP_NOWAIT); 44 if (ret >= 0) 45 dca->id = ret; 46 47 spin_unlock(&dca_idr_lock); 48 idr_preload_end(); 49 if (ret < 0) 50 return ret; 51 52 cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id); 53 if (IS_ERR(cd)) { 54 spin_lock(&dca_idr_lock); 55 idr_remove(&dca_idr, dca->id); 56 spin_unlock(&dca_idr_lock); 57 return PTR_ERR(cd); 58 } 59 dca->cd = cd; 60 return 0; 61 } 62 63 void dca_sysfs_remove_provider(struct dca_provider *dca) 64 { 65 device_unregister(dca->cd); 66 dca->cd = NULL; 67 spin_lock(&dca_idr_lock); 68 idr_remove(&dca_idr, dca->id); 69 spin_unlock(&dca_idr_lock); 70 } 71 72 int __init dca_sysfs_init(void) 73 { 74 idr_init(&dca_idr); 75 spin_lock_init(&dca_idr_lock); 76 77 dca_class = class_create(THIS_MODULE, "dca"); 78 if (IS_ERR(dca_class)) { 79 idr_destroy(&dca_idr); 80 return PTR_ERR(dca_class); 81 } 82 return 0; 83 } 84 85 void __exit dca_sysfs_exit(void) 86 { 87 class_destroy(dca_class); 88 idr_destroy(&dca_idr); 89 } 90 91