2018-02-02 10:16:10 +08:00
// SPDX-License-Identifier: GPL-2.0
2018-02-26 23:48:14 +08:00
/*
* Copyright ( c ) 2015 - 2018 , Intel Corporation .
2021-06-08 20:17:47 +09:30
* Copyright ( c ) 2021 , IBM Corp .
2018-02-26 23:48:14 +08:00
*/
2018-02-02 10:16:10 +08:00
2021-06-08 20:17:48 +09:30
# include <linux/device.h>
2018-02-02 10:16:10 +08:00
# include <linux/module.h>
# include "kcs_bmc.h"
2021-06-08 20:17:47 +09:30
/* Implement both the device and client interfaces here */
# include "kcs_bmc_device.h"
# include "kcs_bmc_client.h"
/* Consumer data access */
2021-06-08 20:17:48 +09:30
u8 kcs_bmc_read_data ( struct kcs_bmc_device * kcs_bmc )
2018-02-02 10:16:10 +08:00
{
2021-06-08 20:17:47 +09:30
return kcs_bmc - > ops - > io_inputb ( kcs_bmc , kcs_bmc - > ioreg . idr ) ;
2018-02-02 10:16:10 +08:00
}
2021-06-08 20:17:45 +09:30
EXPORT_SYMBOL ( kcs_bmc_read_data ) ;
2018-02-02 10:16:10 +08:00
2021-06-08 20:17:48 +09:30
void kcs_bmc_write_data ( struct kcs_bmc_device * kcs_bmc , u8 data )
2018-02-02 10:16:10 +08:00
{
2021-06-08 20:17:47 +09:30
kcs_bmc - > ops - > io_outputb ( kcs_bmc , kcs_bmc - > ioreg . odr , data ) ;
2018-02-02 10:16:10 +08:00
}
2021-06-08 20:17:45 +09:30
EXPORT_SYMBOL ( kcs_bmc_write_data ) ;
2018-02-02 10:16:10 +08:00
2021-06-08 20:17:48 +09:30
u8 kcs_bmc_read_status ( struct kcs_bmc_device * kcs_bmc )
2018-02-02 10:16:10 +08:00
{
2021-06-08 20:17:47 +09:30
return kcs_bmc - > ops - > io_inputb ( kcs_bmc , kcs_bmc - > ioreg . str ) ;
2018-02-02 10:16:10 +08:00
}
2021-06-08 20:17:45 +09:30
EXPORT_SYMBOL ( kcs_bmc_read_status ) ;
2018-02-02 10:16:10 +08:00
2021-06-08 20:17:48 +09:30
void kcs_bmc_write_status ( struct kcs_bmc_device * kcs_bmc , u8 data )
2018-02-02 10:16:10 +08:00
{
2021-06-08 20:17:47 +09:30
kcs_bmc - > ops - > io_outputb ( kcs_bmc , kcs_bmc - > ioreg . str , data ) ;
2018-02-02 10:16:10 +08:00
}
2021-06-08 20:17:45 +09:30
EXPORT_SYMBOL ( kcs_bmc_write_status ) ;
2018-02-02 10:16:10 +08:00
2021-06-08 20:17:48 +09:30
void kcs_bmc_update_status ( struct kcs_bmc_device * kcs_bmc , u8 mask , u8 val )
2018-02-02 10:16:10 +08:00
{
2021-06-08 20:17:47 +09:30
kcs_bmc - > ops - > io_updateb ( kcs_bmc , kcs_bmc - > ioreg . str , mask , val ) ;
2018-02-02 10:16:10 +08:00
}
2021-06-08 20:17:45 +09:30
EXPORT_SYMBOL ( kcs_bmc_update_status ) ;
2018-02-02 10:16:10 +08:00
2021-06-08 20:17:48 +09:30
irqreturn_t kcs_bmc_handle_event ( struct kcs_bmc_device * kcs_bmc )
2018-02-02 10:16:10 +08:00
{
2021-06-08 20:17:48 +09:30
struct kcs_bmc_client * client ;
irqreturn_t rc ;
spin_lock ( & kcs_bmc - > lock ) ;
client = kcs_bmc - > client ;
if ( client ) {
rc = client - > ops - > event ( client ) ;
} else {
u8 status ;
status = kcs_bmc_read_status ( kcs_bmc ) ;
if ( status & KCS_BMC_STR_IBF ) {
/* Ack the event by reading the data */
kcs_bmc_read_data ( kcs_bmc ) ;
rc = IRQ_HANDLED ;
} else {
rc = IRQ_NONE ;
}
}
spin_unlock ( & kcs_bmc - > lock ) ;
return rc ;
2018-02-02 10:16:10 +08:00
}
EXPORT_SYMBOL ( kcs_bmc_handle_event ) ;
2021-06-08 20:17:48 +09:30
int kcs_bmc_enable_device ( struct kcs_bmc_device * kcs_bmc , struct kcs_bmc_client * client )
{
int rc ;
spin_lock_irq ( & kcs_bmc - > lock ) ;
if ( kcs_bmc - > client ) {
rc = - EBUSY ;
} else {
kcs_bmc - > client = client ;
rc = 0 ;
}
spin_unlock_irq ( & kcs_bmc - > lock ) ;
return rc ;
}
EXPORT_SYMBOL ( kcs_bmc_enable_device ) ;
void kcs_bmc_disable_device ( struct kcs_bmc_device * kcs_bmc , struct kcs_bmc_client * client )
{
spin_lock_irq ( & kcs_bmc - > lock ) ;
if ( client = = kcs_bmc - > client )
kcs_bmc - > client = NULL ;
spin_unlock_irq ( & kcs_bmc - > lock ) ;
}
EXPORT_SYMBOL ( kcs_bmc_disable_device ) ;
int kcs_bmc_ipmi_add_device ( struct kcs_bmc_device * kcs_bmc ) ;
int kcs_bmc_add_device ( struct kcs_bmc_device * kcs_bmc )
2018-02-02 10:16:10 +08:00
{
2021-06-08 20:17:46 +09:30
return kcs_bmc_ipmi_add_device ( kcs_bmc ) ;
2018-02-02 10:16:10 +08:00
}
2021-06-08 20:17:46 +09:30
EXPORT_SYMBOL ( kcs_bmc_add_device ) ;
2021-06-08 20:17:48 +09:30
int kcs_bmc_ipmi_remove_device ( struct kcs_bmc_device * kcs_bmc ) ;
void kcs_bmc_remove_device ( struct kcs_bmc_device * kcs_bmc )
2021-06-08 20:17:46 +09:30
{
if ( kcs_bmc_ipmi_remove_device ( kcs_bmc ) )
pr_warn ( " Failed to remove device for KCS channel %d \n " ,
kcs_bmc - > channel ) ;
}
EXPORT_SYMBOL ( kcs_bmc_remove_device ) ;
2018-02-02 10:16:10 +08:00
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_AUTHOR ( " Haiyue Wang <haiyue.wang@linux.intel.com> " ) ;
2021-06-08 20:17:47 +09:30
MODULE_AUTHOR ( " Andrew Jeffery <andrew@aj.id.au> " ) ;
2018-02-02 10:16:10 +08:00
MODULE_DESCRIPTION ( " KCS BMC to handle the IPMI request from system software " ) ;