|
5 | 5 | */ |
6 | 6 |
|
7 | 7 | #include <linux/device.h> |
| 8 | +#include <linux/list.h> |
8 | 9 | #include <linux/module.h> |
| 10 | +#include <linux/mutex.h> |
9 | 11 |
|
10 | 12 | #include "kcs_bmc.h" |
11 | 13 |
|
12 | 14 | /* Implement both the device and client interfaces here */ |
13 | 15 | #include "kcs_bmc_device.h" |
14 | 16 | #include "kcs_bmc_client.h" |
15 | 17 |
|
| 18 | +/* Record registered devices and drivers */ |
| 19 | +static DEFINE_MUTEX(kcs_bmc_lock); |
| 20 | +static LIST_HEAD(kcs_bmc_devices); |
| 21 | +static LIST_HEAD(kcs_bmc_drivers); |
| 22 | + |
16 | 23 | /* Consumer data access */ |
17 | 24 |
|
18 | 25 | u8 kcs_bmc_read_data(struct kcs_bmc_device *kcs_bmc) |
@@ -98,22 +105,83 @@ void kcs_bmc_disable_device(struct kcs_bmc_device *kcs_bmc, struct kcs_bmc_clien |
98 | 105 | } |
99 | 106 | EXPORT_SYMBOL(kcs_bmc_disable_device); |
100 | 107 |
|
101 | | -int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc); |
102 | 108 | int kcs_bmc_add_device(struct kcs_bmc_device *kcs_bmc) |
103 | 109 | { |
104 | | - return kcs_bmc_ipmi_add_device(kcs_bmc); |
| 110 | + struct kcs_bmc_driver *drv; |
| 111 | + int error = 0; |
| 112 | + int rc; |
| 113 | + |
| 114 | + spin_lock_init(&kcs_bmc->lock); |
| 115 | + kcs_bmc->client = NULL; |
| 116 | + |
| 117 | + mutex_lock(&kcs_bmc_lock); |
| 118 | + list_add(&kcs_bmc->entry, &kcs_bmc_devices); |
| 119 | + list_for_each_entry(drv, &kcs_bmc_drivers, entry) { |
| 120 | + rc = drv->ops->add_device(kcs_bmc); |
| 121 | + if (!rc) |
| 122 | + continue; |
| 123 | + |
| 124 | + dev_err(kcs_bmc->dev, "Failed to add chardev for KCS channel %d: %d", |
| 125 | + kcs_bmc->channel, rc); |
| 126 | + error = rc; |
| 127 | + } |
| 128 | + mutex_unlock(&kcs_bmc_lock); |
| 129 | + |
| 130 | + return error; |
105 | 131 | } |
106 | 132 | EXPORT_SYMBOL(kcs_bmc_add_device); |
107 | 133 |
|
108 | | -int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc); |
109 | 134 | void kcs_bmc_remove_device(struct kcs_bmc_device *kcs_bmc) |
110 | 135 | { |
111 | | - if (kcs_bmc_ipmi_remove_device(kcs_bmc)) |
112 | | - pr_warn("Failed to remove device for KCS channel %d\n", |
113 | | - kcs_bmc->channel); |
| 136 | + struct kcs_bmc_driver *drv; |
| 137 | + int rc; |
| 138 | + |
| 139 | + mutex_lock(&kcs_bmc_lock); |
| 140 | + list_del(&kcs_bmc->entry); |
| 141 | + list_for_each_entry(drv, &kcs_bmc_drivers, entry) { |
| 142 | + rc = drv->ops->remove_device(kcs_bmc); |
| 143 | + if (rc) |
| 144 | + dev_err(kcs_bmc->dev, "Failed to remove chardev for KCS channel %d: %d", |
| 145 | + kcs_bmc->channel, rc); |
| 146 | + } |
| 147 | + mutex_unlock(&kcs_bmc_lock); |
114 | 148 | } |
115 | 149 | EXPORT_SYMBOL(kcs_bmc_remove_device); |
116 | 150 |
|
| 151 | +void kcs_bmc_register_driver(struct kcs_bmc_driver *drv) |
| 152 | +{ |
| 153 | + struct kcs_bmc_device *kcs_bmc; |
| 154 | + int rc; |
| 155 | + |
| 156 | + mutex_lock(&kcs_bmc_lock); |
| 157 | + list_add(&drv->entry, &kcs_bmc_drivers); |
| 158 | + list_for_each_entry(kcs_bmc, &kcs_bmc_devices, entry) { |
| 159 | + rc = drv->ops->add_device(kcs_bmc); |
| 160 | + if (rc) |
| 161 | + dev_err(kcs_bmc->dev, "Failed to add driver for KCS channel %d: %d", |
| 162 | + kcs_bmc->channel, rc); |
| 163 | + } |
| 164 | + mutex_unlock(&kcs_bmc_lock); |
| 165 | +} |
| 166 | +EXPORT_SYMBOL(kcs_bmc_register_driver); |
| 167 | + |
| 168 | +void kcs_bmc_unregister_driver(struct kcs_bmc_driver *drv) |
| 169 | +{ |
| 170 | + struct kcs_bmc_device *kcs_bmc; |
| 171 | + int rc; |
| 172 | + |
| 173 | + mutex_lock(&kcs_bmc_lock); |
| 174 | + list_del(&drv->entry); |
| 175 | + list_for_each_entry(kcs_bmc, &kcs_bmc_devices, entry) { |
| 176 | + rc = drv->ops->remove_device(kcs_bmc); |
| 177 | + if (rc) |
| 178 | + dev_err(kcs_bmc->dev, "Failed to remove driver for KCS channel %d: %d", |
| 179 | + kcs_bmc->channel, rc); |
| 180 | + } |
| 181 | + mutex_unlock(&kcs_bmc_lock); |
| 182 | +} |
| 183 | +EXPORT_SYMBOL(kcs_bmc_unregister_driver); |
| 184 | + |
117 | 185 | MODULE_LICENSE("GPL v2"); |
118 | 186 | MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>"); |
119 | 187 | MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>"); |
|
0 commit comments