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"); |