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 device *cd; 16 17 cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), 18 "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 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 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 = device_create(dca_class, dev, MKDEV(0, 0), "dca%d", dca->id); 50 if (IS_ERR(cd)) { 51 spin_lock(&dca_idr_lock); 52 idr_remove(&dca_idr, dca->id); 53 spin_unlock(&dca_idr_lock); 54 return PTR_ERR(cd); 55 } 56 dca->cd = cd; 57 return 0; 58 } 59 60 void dca_sysfs_remove_provider(struct dca_provider *dca) 61 { 62 device_unregister(dca->cd); 63 dca->cd = NULL; 64 spin_lock(&dca_idr_lock); 65 idr_remove(&dca_idr, dca->id); 66 spin_unlock(&dca_idr_lock); 67 } 68 69 int __init dca_sysfs_init(void) 70 { 71 idr_init(&dca_idr); 72 spin_lock_init(&dca_idr_lock); 73 74 dca_class = class_create(THIS_MODULE, "dca"); 75 if (IS_ERR(dca_class)) { 76 idr_destroy(&dca_idr); 77 return PTR_ERR(dca_class); 78 } 79 return 0; 80 } 81 82 void __exit dca_sysfs_exit(void) 83 { 84 class_destroy(dca_class); 85 idr_destroy(&dca_idr); 86 } 87 88