1 #include <linux/kernel.h> 2 #include <linux/spinlock.h> 3 #include <linux/device.h> 4 #include <linux/idr.h> 5 #include <linux/kdev_t.h> 6 #include <linux/err.h> 7 #include <linux/dca.h> 8 9 static struct class *dca_class; 10 static struct idr dca_idr; 11 static spinlock_t dca_idr_lock; 12 13 int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot) 14 { 15 struct class_device *cd; 16 17 cd = class_device_create(dca_class, dca->cd, MKDEV(0, slot + 1), 18 dev, "requester%d", slot); 19 if (IS_ERR(cd)) 20 return PTR_ERR(cd); 21 return 0; 22 } 23 24 void dca_sysfs_remove_req(struct dca_provider *dca, int slot) 25 { 26 class_device_destroy(dca_class, MKDEV(0, slot + 1)); 27 } 28 29 int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev) 30 { 31 struct class_device *cd; 32 int err = 0; 33 34 idr_try_again: 35 if (!idr_pre_get(&dca_idr, GFP_KERNEL)) 36 return -ENOMEM; 37 spin_lock(&dca_idr_lock); 38 err = idr_get_new(&dca_idr, dca, &dca->id); 39 spin_unlock(&dca_idr_lock); 40 switch (err) { 41 case 0: 42 break; 43 case -EAGAIN: 44 goto idr_try_again; 45 default: 46 return err; 47 } 48 49 cd = class_device_create(dca_class, NULL, MKDEV(0, 0), 50 dev, "dca%d", dca->id); 51 if (IS_ERR(cd)) { 52 spin_lock(&dca_idr_lock); 53 idr_remove(&dca_idr, dca->id); 54 spin_unlock(&dca_idr_lock); 55 return PTR_ERR(cd); 56 } 57 dca->cd = cd; 58 return 0; 59 } 60 61 void dca_sysfs_remove_provider(struct dca_provider *dca) 62 { 63 class_device_unregister(dca->cd); 64 dca->cd = NULL; 65 spin_lock(&dca_idr_lock); 66 idr_remove(&dca_idr, dca->id); 67 spin_unlock(&dca_idr_lock); 68 } 69 70 int __init dca_sysfs_init(void) 71 { 72 idr_init(&dca_idr); 73 spin_lock_init(&dca_idr_lock); 74 75 dca_class = class_create(THIS_MODULE, "dca"); 76 if (IS_ERR(dca_class)) { 77 idr_destroy(&dca_idr); 78 return PTR_ERR(dca_class); 79 } 80 return 0; 81 } 82 83 void __exit dca_sysfs_exit(void) 84 { 85 class_destroy(dca_class); 86 idr_destroy(&dca_idr); 87 } 88 89