Skip to content

Commit 7cafff9

Browse files
amboarcminyard
authored andcommitted
ipmi: kcs_bmc: Decouple the IPMI chardev from the core
Now that we have untangled the data-structures, split the userspace interface out into its own module. Userspace interfaces and drivers are registered to the KCS BMC core to support arbitrary binding of either. Signed-off-by: Andrew Jeffery <[email protected]> Message-Id: <[email protected]> Reviewed-by: Zev Weiss <[email protected]> Signed-off-by: Corey Minyard <[email protected]>
1 parent d4e7ac6 commit 7cafff9

File tree

5 files changed

+128
-13
lines changed

5 files changed

+128
-13
lines changed

drivers/char/ipmi/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ config NPCM7XX_KCS_IPMI_BMC
124124
This support is also available as a module. If so, the module
125125
will be called kcs_bmc_npcm7xx.
126126

127+
config IPMI_KCS_BMC_CDEV_IPMI
128+
depends on IPMI_KCS_BMC
129+
tristate "IPMI character device interface for BMC KCS devices"
130+
help
131+
Provides a BMC-side character device implementing IPMI
132+
semantics for KCS IPMI devices.
133+
134+
Say YES if you wish to expose KCS devices on the BMC for IPMI
135+
purposes.
136+
137+
This support is also available as a module. The module will be
138+
called kcs_bmc_cdev_ipmi.
139+
127140
config ASPEED_BT_IPMI_BMC
128141
depends on ARCH_ASPEED || COMPILE_TEST
129142
depends on REGMAP && REGMAP_MMIO && MFD_SYSCON

drivers/char/ipmi/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o
2222
obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
2323
obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
2424
obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
25-
obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o kcs_bmc_cdev_ipmi.o
25+
obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o
26+
obj-$(CONFIG_IPMI_KCS_BMC_CDEV_IPMI) += kcs_bmc_cdev_ipmi.o
2627
obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
2728
obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o
2829
obj-$(CONFIG_NPCM7XX_KCS_IPMI_BMC) += kcs_bmc_npcm7xx.o

drivers/char/ipmi/kcs_bmc.c

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@
55
*/
66

77
#include <linux/device.h>
8+
#include <linux/list.h>
89
#include <linux/module.h>
10+
#include <linux/mutex.h>
911

1012
#include "kcs_bmc.h"
1113

1214
/* Implement both the device and client interfaces here */
1315
#include "kcs_bmc_device.h"
1416
#include "kcs_bmc_client.h"
1517

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+
1623
/* Consumer data access */
1724

1825
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
98105
}
99106
EXPORT_SYMBOL(kcs_bmc_disable_device);
100107

101-
int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc);
102108
int kcs_bmc_add_device(struct kcs_bmc_device *kcs_bmc)
103109
{
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;
105131
}
106132
EXPORT_SYMBOL(kcs_bmc_add_device);
107133

108-
int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc);
109134
void kcs_bmc_remove_device(struct kcs_bmc_device *kcs_bmc)
110135
{
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);
114148
}
115149
EXPORT_SYMBOL(kcs_bmc_remove_device);
116150

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+
117185
MODULE_LICENSE("GPL v2");
118186
MODULE_AUTHOR("Haiyue Wang <[email protected]>");
119187
MODULE_AUTHOR("Andrew Jeffery <[email protected]>");

drivers/char/ipmi/kcs_bmc_cdev_ipmi.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,7 @@ static const struct file_operations kcs_bmc_ipmi_fops = {
469469
static DEFINE_SPINLOCK(kcs_bmc_ipmi_instances_lock);
470470
static LIST_HEAD(kcs_bmc_ipmi_instances);
471471

472-
int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc);
473-
int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc)
472+
static int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc)
474473
{
475474
struct kcs_bmc_ipmi *priv;
476475
int rc;
@@ -512,10 +511,8 @@ int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc)
512511

513512
return 0;
514513
}
515-
EXPORT_SYMBOL(kcs_bmc_ipmi_add_device);
516514

517-
int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc);
518-
int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc)
515+
static int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc)
519516
{
520517
struct kcs_bmc_ipmi *priv = NULL, *pos;
521518

@@ -541,7 +538,29 @@ int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc)
541538

542539
return 0;
543540
}
544-
EXPORT_SYMBOL(kcs_bmc_ipmi_remove_device);
541+
542+
static const struct kcs_bmc_driver_ops kcs_bmc_ipmi_driver_ops = {
543+
.add_device = kcs_bmc_ipmi_add_device,
544+
.remove_device = kcs_bmc_ipmi_remove_device,
545+
};
546+
547+
static struct kcs_bmc_driver kcs_bmc_ipmi_driver = {
548+
.ops = &kcs_bmc_ipmi_driver_ops,
549+
};
550+
551+
static int kcs_bmc_ipmi_init(void)
552+
{
553+
kcs_bmc_register_driver(&kcs_bmc_ipmi_driver);
554+
555+
return 0;
556+
}
557+
module_init(kcs_bmc_ipmi_init);
558+
559+
static void kcs_bmc_ipmi_exit(void)
560+
{
561+
kcs_bmc_unregister_driver(&kcs_bmc_ipmi_driver);
562+
}
563+
module_exit(kcs_bmc_ipmi_exit);
545564

546565
MODULE_LICENSE("GPL v2");
547566
MODULE_AUTHOR("Haiyue Wang <[email protected]>");

drivers/char/ipmi/kcs_bmc_client.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88

99
#include "kcs_bmc.h"
1010

11+
struct kcs_bmc_driver_ops {
12+
int (*add_device)(struct kcs_bmc_device *kcs_bmc);
13+
int (*remove_device)(struct kcs_bmc_device *kcs_bmc);
14+
};
15+
16+
struct kcs_bmc_driver {
17+
struct list_head entry;
18+
19+
const struct kcs_bmc_driver_ops *ops;
20+
};
21+
1122
struct kcs_bmc_client_ops {
1223
irqreturn_t (*event)(struct kcs_bmc_client *client);
1324
};
@@ -18,6 +29,9 @@ struct kcs_bmc_client {
1829
struct kcs_bmc_device *dev;
1930
};
2031

32+
void kcs_bmc_register_driver(struct kcs_bmc_driver *drv);
33+
void kcs_bmc_unregister_driver(struct kcs_bmc_driver *drv);
34+
2135
int kcs_bmc_enable_device(struct kcs_bmc_device *kcs_bmc, struct kcs_bmc_client *client);
2236
void kcs_bmc_disable_device(struct kcs_bmc_device *kcs_bmc, struct kcs_bmc_client *client);
2337

0 commit comments

Comments
 (0)