kcs_bmc.c (faae6e391eda73a5b9870c78349064282a625bfa) kcs_bmc.c (d4e7ac68f771addc19352121706d8584eb0166cd)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2015-2018, Intel Corporation.
4 * Copyright (c) 2021, IBM Corp.
5 */
6
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2015-2018, Intel Corporation.
4 * Copyright (c) 2021, IBM Corp.
5 */
6
7#include <linux/device.h>
7#include <linux/module.h>
8
9#include "kcs_bmc.h"
10
11/* Implement both the device and client interfaces here */
12#include "kcs_bmc_device.h"
13#include "kcs_bmc_client.h"
14
15/* Consumer data access */
16
8#include <linux/module.h>
9
10#include "kcs_bmc.h"
11
12/* Implement both the device and client interfaces here */
13#include "kcs_bmc_device.h"
14#include "kcs_bmc_client.h"
15
16/* Consumer data access */
17
17u8 kcs_bmc_read_data(struct kcs_bmc *kcs_bmc)
18u8 kcs_bmc_read_data(struct kcs_bmc_device *kcs_bmc)
18{
19 return kcs_bmc->ops->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr);
20}
21EXPORT_SYMBOL(kcs_bmc_read_data);
22
19{
20 return kcs_bmc->ops->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr);
21}
22EXPORT_SYMBOL(kcs_bmc_read_data);
23
23void kcs_bmc_write_data(struct kcs_bmc *kcs_bmc, u8 data)
24void kcs_bmc_write_data(struct kcs_bmc_device *kcs_bmc, u8 data)
24{
25 kcs_bmc->ops->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data);
26}
27EXPORT_SYMBOL(kcs_bmc_write_data);
28
25{
26 kcs_bmc->ops->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data);
27}
28EXPORT_SYMBOL(kcs_bmc_write_data);
29
29u8 kcs_bmc_read_status(struct kcs_bmc *kcs_bmc)
30u8 kcs_bmc_read_status(struct kcs_bmc_device *kcs_bmc)
30{
31 return kcs_bmc->ops->io_inputb(kcs_bmc, kcs_bmc->ioreg.str);
32}
33EXPORT_SYMBOL(kcs_bmc_read_status);
34
31{
32 return kcs_bmc->ops->io_inputb(kcs_bmc, kcs_bmc->ioreg.str);
33}
34EXPORT_SYMBOL(kcs_bmc_read_status);
35
35void kcs_bmc_write_status(struct kcs_bmc *kcs_bmc, u8 data)
36void kcs_bmc_write_status(struct kcs_bmc_device *kcs_bmc, u8 data)
36{
37 kcs_bmc->ops->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data);
38}
39EXPORT_SYMBOL(kcs_bmc_write_status);
40
37{
38 kcs_bmc->ops->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data);
39}
40EXPORT_SYMBOL(kcs_bmc_write_status);
41
41void kcs_bmc_update_status(struct kcs_bmc *kcs_bmc, u8 mask, u8 val)
42void kcs_bmc_update_status(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 val)
42{
43 kcs_bmc->ops->io_updateb(kcs_bmc, kcs_bmc->ioreg.str, mask, val);
44}
45EXPORT_SYMBOL(kcs_bmc_update_status);
46
43{
44 kcs_bmc->ops->io_updateb(kcs_bmc, kcs_bmc->ioreg.str, mask, val);
45}
46EXPORT_SYMBOL(kcs_bmc_update_status);
47
47irqreturn_t kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc)
48irqreturn_t kcs_bmc_handle_event(struct kcs_bmc_device *kcs_bmc)
48{
49{
49 return kcs_bmc->client.ops->event(&kcs_bmc->client);
50 struct kcs_bmc_client *client;
51 irqreturn_t rc;
52
53 spin_lock(&kcs_bmc->lock);
54 client = kcs_bmc->client;
55 if (client) {
56 rc = client->ops->event(client);
57 } else {
58 u8 status;
59
60 status = kcs_bmc_read_status(kcs_bmc);
61 if (status & KCS_BMC_STR_IBF) {
62 /* Ack the event by reading the data */
63 kcs_bmc_read_data(kcs_bmc);
64 rc = IRQ_HANDLED;
65 } else {
66 rc = IRQ_NONE;
67 }
68 }
69 spin_unlock(&kcs_bmc->lock);
70
71 return rc;
50}
51EXPORT_SYMBOL(kcs_bmc_handle_event);
52
72}
73EXPORT_SYMBOL(kcs_bmc_handle_event);
74
53int kcs_bmc_ipmi_add_device(struct kcs_bmc *kcs_bmc);
54int kcs_bmc_add_device(struct kcs_bmc *kcs_bmc)
75int kcs_bmc_enable_device(struct kcs_bmc_device *kcs_bmc, struct kcs_bmc_client *client)
55{
76{
77 int rc;
78
79 spin_lock_irq(&kcs_bmc->lock);
80 if (kcs_bmc->client) {
81 rc = -EBUSY;
82 } else {
83 kcs_bmc->client = client;
84 rc = 0;
85 }
86 spin_unlock_irq(&kcs_bmc->lock);
87
88 return rc;
89}
90EXPORT_SYMBOL(kcs_bmc_enable_device);
91
92void kcs_bmc_disable_device(struct kcs_bmc_device *kcs_bmc, struct kcs_bmc_client *client)
93{
94 spin_lock_irq(&kcs_bmc->lock);
95 if (client == kcs_bmc->client)
96 kcs_bmc->client = NULL;
97 spin_unlock_irq(&kcs_bmc->lock);
98}
99EXPORT_SYMBOL(kcs_bmc_disable_device);
100
101int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc);
102int kcs_bmc_add_device(struct kcs_bmc_device *kcs_bmc)
103{
56 return kcs_bmc_ipmi_add_device(kcs_bmc);
57}
58EXPORT_SYMBOL(kcs_bmc_add_device);
59
104 return kcs_bmc_ipmi_add_device(kcs_bmc);
105}
106EXPORT_SYMBOL(kcs_bmc_add_device);
107
60int kcs_bmc_ipmi_remove_device(struct kcs_bmc *kcs_bmc);
61void kcs_bmc_remove_device(struct kcs_bmc *kcs_bmc)
108int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc);
109void kcs_bmc_remove_device(struct kcs_bmc_device *kcs_bmc)
62{
63 if (kcs_bmc_ipmi_remove_device(kcs_bmc))
64 pr_warn("Failed to remove device for KCS channel %d\n",
65 kcs_bmc->channel);
66}
67EXPORT_SYMBOL(kcs_bmc_remove_device);
68
69MODULE_LICENSE("GPL v2");
70MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>");
71MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
72MODULE_DESCRIPTION("KCS BMC to handle the IPMI request from system software");
110{
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);
114}
115EXPORT_SYMBOL(kcs_bmc_remove_device);
116
117MODULE_LICENSE("GPL v2");
118MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>");
119MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
120MODULE_DESCRIPTION("KCS BMC to handle the IPMI request from system software");